bool ScriptParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (keyword==Scanner::K_while || keyword==Scanner::K_if || keyword==Scanner::K_elseif) { mControlParser.reset(); if (mControlParser.parseKeyword (keyword, loc, scanner)) scanner.scan (mControlParser); mControlParser.appendCode (mOutput.getCode()); return true; } /// \todo add an option to disable this nonsense if (keyword==Scanner::K_endif) { // surplus endif getErrorHandler().warning ("endif without matching if/elseif", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return true; } if (keyword==Scanner::K_end && mEnd) { return false; } mLineParser.reset(); if (mLineParser.parseKeyword (keyword, loc, scanner)) scanner.scan (mLineParser); return true; }
void ExprParser::parseArguments (const std::string& arguments, Scanner& scanner, std::vector<Interpreter::Type_Code>& code, bool invert) { ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true); StringParser stringParser (getErrorHandler(), getContext(), mLiterals); std::stack<std::vector<Interpreter::Type_Code> > stack; for (std::string::const_iterator iter (arguments.begin()); iter!=arguments.end(); ++iter) { if (*iter=='S' || *iter=='c') { stringParser.reset(); if (*iter=='c') stringParser.smashCase(); scanner.scan (stringParser); if (invert) { std::vector<Interpreter::Type_Code> tmp; stringParser.append (tmp); stack.push (tmp); } else stringParser.append (code); } else { parser.reset(); scanner.scan (parser); std::vector<Interpreter::Type_Code> tmp; char type = parser.append (tmp); if (type!=*iter) Generator::convert (tmp, type, *iter); if (invert) stack.push (tmp); else std::copy (tmp.begin(), tmp.end(), std::back_inserter (code)); } } while (!stack.empty()) { std::vector<Interpreter::Type_Code>& tmp = stack.top(); std::copy (tmp.begin(), tmp.end(), std::back_inserter (code)); stack.pop(); } }
bool Compiler::QuickFileParser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return true; }
//-***************************************************************************** void OCompoundProperty::init( AbcA::CompoundPropertyWriterPtr iParent, const std::string &iName, const Argument &iArg0, const Argument &iArg1, const Argument &iArg2 ) { ALEMBIC_ABC_SAFE_CALL_BEGIN( "OCompoundProperty::init()" ); ABCA_ASSERT( iParent, "invalid parent" ); Arguments args; iArg0.setInto( args ); iArg1.setInto( args ); iArg2.setInto( args ); getErrorHandler().setPolicy( args.getErrorHandlerPolicy() ); m_property = Alembic::Util::dynamic_pointer_cast< AbcA::CompoundPropertyWriter>( iParent->getProperty( iName ) ); if ( !m_property ) { m_property = iParent->createCompoundProperty( iName, args.getMetaData() ); } ALEMBIC_ABC_SAFE_CALL_END_RESET(); }
//-***************************************************************************** void IArrayProperty::init( AbcA::CompoundPropertyReaderPtr iParent, const std::string &iName, ErrorHandler::Policy iParentPolicy, const Argument &iArg0, const Argument &iArg1 ) { Arguments args( iParentPolicy ); iArg0.setInto( args ); iArg1.setInto( args ); getErrorHandler().setPolicy( args.getErrorHandlerPolicy() ); ALEMBIC_ABC_SAFE_CALL_BEGIN( "IArrayProperty::init()" ); const AbcA::PropertyHeader *pheader = iParent->getPropertyHeader( iName ); ABCA_ASSERT( pheader != NULL, "Nonexistent array property: " << iName ); m_property = iParent->getArrayProperty( iName ); ALEMBIC_ABC_SAFE_CALL_END_RESET(); }
bool Compiler::QuickFileParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (code!=Scanner::S_newline) { SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); } return true; }
bool ControlParser::parseWhileBody (int keyword, const TokenLoc& loc, Scanner& scanner) { if (keyword==Scanner::K_endwhile) { Codes loop; Codes expr; mExprParser.append (expr); Generator::jump (loop, -static_cast<int> (mCodeBlock.size()+expr.size())); std::copy (expr.begin(), expr.end(), std::back_inserter (mCode)); Codes skip; Generator::jumpOnZero (skip, mCodeBlock.size()+loop.size()+1); std::copy (skip.begin(), skip.end(), std::back_inserter (mCode)); std::copy (mCodeBlock.begin(), mCodeBlock.end(), std::back_inserter (mCode)); Codes loop2; Generator::jump (loop2, -static_cast<int> (mCodeBlock.size()+expr.size()+skip.size())); if (loop.size()!=loop2.size()) throw std::logic_error ( "internal compiler error: failed to generate a while loop"); std::copy (loop2.begin(), loop2.end(), std::back_inserter (mCode)); mState = WhileEndwhileState; return true; } else if (keyword==Scanner::K_if || keyword==Scanner::K_while) { // nested ControlParser parser (getErrorHandler(), getContext(), mLocals, mLiterals); if (parser.parseKeyword (keyword, loc, scanner)) scanner.scan (parser); parser.appendCode (mCodeBlock); return true; } else { mLineParser.reset(); if (mLineParser.parseKeyword (keyword, loc, scanner)) scanner.scan (mLineParser); return true; } }
char ExprParser::append (std::vector<Interpreter::Type_Code>& code) { if (mOperands.empty() && mOperators.empty()) { getErrorHandler().error ("missing expression", mTokenLoc); return 'l'; } if (mNextOperand || mOperands.empty()) { getErrorHandler().error ("syntax error in expression", mTokenLoc); return 'l'; } while (!mOperators.empty()) pop(); std::copy (mCode.begin(), mCode.end(), std::back_inserter (code)); assert (mOperands.size()==1); return mOperands[0]; }
/////////////////////////////////////////////////////////////////////// // Function: Initialize // // Author: $author$ // Date: 7/18/2011 /////////////////////////////////////////////////////////////////////// virtual eError Initialize() { eError error = e_ERROR_FAILED; if (m_initializer) return e_ERROR_ALREADY_INITIALIZED; if (!(m_initializer = cXalanTransformerInitializer::GetInstance(error))) return error; m_oldErrorHandler = getErrorHandler(); setErrorHandler(&m_errorHandler); return error; }
//-***************************************************************************** void ICompoundProperty::init ( const IObject & iObject, const Argument &iArg0, const Argument &iArg1 ) { getErrorHandler().setPolicy( GetErrorHandlerPolicy( iObject, iArg0, iArg1 ) ); ALEMBIC_ABC_SAFE_CALL_BEGIN( "ICompoundProperty::init( IObject )" ); m_property = iObject.getProperties().getPtr(); ALEMBIC_ABC_SAFE_CALL_END_RESET(); }
bool Compiler::QuickFileParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (keyword==Scanner::K_end) return false; if (keyword==Scanner::K_short || keyword==Scanner::K_long || keyword==Scanner::K_float) { mDeclarationParser.reset(); scanner.putbackKeyword (keyword, loc); scanner.scan (mDeclarationParser); return true; } SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return true; }
//-------------------------------------------------------------------- bool ParserTemplateBase::handleError( ParserError::Severity severity, ParserError::ErrorType errorType, StringHash elementHash, StringHash attributeHash, const ParserChar* additionalText /*= ""*/ ) { IErrorHandler* errorHandler = getErrorHandler(); if ( !errorHandler ) return (severity == ParserError::SEVERITY_CRITICAL) ? true : false; ParserError error(severity, errorType, getNameByStringHash(elementHash), getNameByStringHash(attributeHash), getLineNumber(), getColumnNumber(), additionalText ? (const char*)additionalText : ""); bool handlerWantsToAbort = errorHandler->handleError(error); return (severity == ParserError::SEVERITY_CRITICAL) ? true : handlerWantsToAbort; }
bool ControlParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (code==Scanner::S_newline) { switch (mState) { case IfEndState: mState = IfBodyState; return true; case IfElseifEndState: mState = IfElseifBodyState; return true; case IfElseEndState: mState = IfElseBodyState; return true; case IfElseJunkState: mState = IfElseBodyState; return true; case WhileEndState: mState = WhileBodyState; return true; case IfBodyState: case IfElseifBodyState: case IfElseBodyState: case WhileBodyState: return true; // empty line case IfEndifState: case WhileEndwhileState: return false; default: ; } } else if (code==Scanner::S_open && mState==IfElseJunkState) { SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); mState = IfElseBodyState; return true; } return Parser::parseSpecial (code, loc, scanner); }
bool ControlParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (mState==StartState) { if (keyword==Scanner::K_if || keyword==Scanner::K_elseif) { if (keyword==Scanner::K_elseif) getErrorHandler().warning ("elseif without matching if", loc); mExprParser.reset(); scanner.scan (mExprParser); mState = IfEndState; return true; } else if (keyword==Scanner::K_while) { mExprParser.reset(); scanner.scan (mExprParser); mState = WhileEndState; return true; } } else if (mState==IfBodyState || mState==IfElseifBodyState || mState==IfElseBodyState || mState==IfElseJunkState) { if (parseIfBody (keyword, loc, scanner)) return true; } else if (mState==WhileBodyState) { if ( parseWhileBody (keyword, loc, scanner)) return true; } return Parser::parseKeyword (keyword, loc, scanner); }
bool ControlParser::parseIfBody (int keyword, const TokenLoc& loc, Scanner& scanner) { if (keyword==Scanner::K_endif || keyword==Scanner::K_elseif || keyword==Scanner::K_else) { std::pair<Codes, Codes> entry; if (mState!=IfElseBodyState) mExprParser.append (entry.first); std::copy (mCodeBlock.begin(), mCodeBlock.end(), std::back_inserter (entry.second)); mIfCode.push_back (entry); mCodeBlock.clear(); if (keyword==Scanner::K_endif) { // store code for if-cascade Codes codes; for (IfCodes::reverse_iterator iter (mIfCode.rbegin()); iter!=mIfCode.rend(); ++iter) { Codes block; if (iter!=mIfCode.rbegin()) Generator::jump (iter->second, codes.size()+1); if (!iter->first.empty()) { // if or elseif std::copy (iter->first.begin(), iter->first.end(), std::back_inserter (block)); Generator::jumpOnZero (block, iter->second.size()+1); } std::copy (iter->second.begin(), iter->second.end(), std::back_inserter (block)); std::swap (codes, block); std::copy (block.begin(), block.end(), std::back_inserter (codes)); } std::copy (codes.begin(), codes.end(), std::back_inserter (mCode)); mIfCode.clear(); mState = IfEndifState; } else if (keyword==Scanner::K_elseif) { mExprParser.reset(); scanner.scan (mExprParser); mState = IfElseifEndState; } else if (keyword==Scanner::K_else) { mState = IfElseJunkState; /// \todo should be IfElseEndState; add an option for that } return true; } else if (keyword==Scanner::K_if || keyword==Scanner::K_while) { // nested ControlParser parser (getErrorHandler(), getContext(), mLocals, mLiterals); if (parser.parseKeyword (keyword, loc, scanner)) scanner.scan (parser); parser.appendCode (mCodeBlock); return true; } else { mLineParser.reset(); if (mLineParser.parseKeyword (keyword, loc, scanner)) scanner.scan (mLineParser); return true; } }
int ExprParser::parseArguments (const std::string& arguments, Scanner& scanner, std::vector<Interpreter::Type_Code>& code) { bool optional = false; int optionalCount = 0; ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true); StringParser stringParser (getErrorHandler(), getContext(), mLiterals); std::stack<std::vector<Interpreter::Type_Code> > stack; for (std::string::const_iterator iter (arguments.begin()); iter!=arguments.end(); ++iter) { if (*iter=='/') { optional = true; } else if (*iter=='S' || *iter=='c' || *iter=='x') { stringParser.reset(); if (optional || *iter=='x') stringParser.setOptional (true); if (*iter=='c') stringParser.smashCase(); scanner.scan (stringParser); if (optional && stringParser.isEmpty()) break; if (*iter!='x') { std::vector<Interpreter::Type_Code> tmp; stringParser.append (tmp); stack.push (tmp); if (optional) ++optionalCount; } } else { parser.reset(); if (optional || *iter == 'X') parser.setOptional (true); scanner.scan (parser); if (optional && parser.isEmpty()) break; if (*iter != 'X') { std::vector<Interpreter::Type_Code> tmp; char type = parser.append (tmp); if (type!=*iter) Generator::convert (tmp, type, *iter); stack.push (tmp); if (optional) ++optionalCount; } } } while (!stack.empty()) { std::vector<Interpreter::Type_Code>& tmp = stack.top(); std::copy (tmp.begin(), tmp.end(), std::back_inserter (code)); stack.pop(); } return optionalCount; }
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (const Extensions *extensions = getContext().getExtensions()) { std::string argumentType; // ignored bool hasExplicit = false; // ignored if (extensions->isInstruction (keyword, argumentType, hasExplicit)) { // pretend this is not a keyword return parseName (loc.mLiteral, loc, scanner); } } if (keyword==Scanner::K_end || keyword==Scanner::K_begin || keyword==Scanner::K_short || keyword==Scanner::K_long || keyword==Scanner::K_float || keyword==Scanner::K_if || keyword==Scanner::K_endif || keyword==Scanner::K_else || keyword==Scanner::K_elseif || keyword==Scanner::K_while || keyword==Scanner::K_endwhile || keyword==Scanner::K_return || keyword==Scanner::K_messagebox || keyword==Scanner::K_set || keyword==Scanner::K_to || keyword==Scanner::K_startscript || keyword==Scanner::K_stopscript || keyword==Scanner::K_enable || keyword==Scanner::K_disable) { return parseName (loc.mLiteral, loc, scanner); } mFirst = false; if (!mExplicit.empty()) { if (mRefOp && mNextOperand) { if (keyword==Scanner::K_getdisabled) { start(); mTokenLoc = loc; Generator::getDisabled (mCode, mLiterals, mExplicit); mOperands.push_back ('l'); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } else if (keyword==Scanner::K_getdistance) { start(); mTokenLoc = loc; parseArguments ("c", scanner); Generator::getDistance (mCode, mLiterals, mExplicit); mOperands.push_back ('f'); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; bool hasExplicit = true; if (extensions->isFunction (keyword, returnType, argumentType, hasExplicit)) { if (!hasExplicit) { getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mExplicit.clear(); } start(); mTokenLoc = loc; int optionals = parseArguments (argumentType, scanner); extensions->generateFunctionCode (keyword, mCode, mLiterals, mExplicit, optionals); mOperands.push_back (returnType); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } } } return Parser::parseKeyword (keyword, loc, scanner); } if (mNextOperand) { if (keyword==Scanner::K_getsquareroot) { start(); mTokenLoc = loc; parseArguments ("f", scanner); Generator::squareRoot (mCode); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_menumode) { start(); mTokenLoc = loc; Generator::menuMode (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_random) { start(); mTokenLoc = loc; parseArguments ("l", scanner); Generator::random (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_scriptrunning) { start(); mTokenLoc = loc; parseArguments ("c", scanner); Generator::scriptRunning (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getdistance) { start(); mTokenLoc = loc; parseArguments ("c", scanner); Generator::getDistance (mCode, mLiterals, ""); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getsecondspassed) { start(); mTokenLoc = loc; Generator::getSecondsPassed (mCode); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getdisabled) { start(); mTokenLoc = loc; Generator::getDisabled (mCode, mLiterals, ""); mOperands.push_back ('l'); mNextOperand = false; return true; } else { // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { start(); char returnType; std::string argumentType; bool hasExplicit = false; if (extensions->isFunction (keyword, returnType, argumentType, hasExplicit)) { mTokenLoc = loc; int optionals = parseArguments (argumentType, scanner); extensions->generateFunctionCode (keyword, mCode, mLiterals, "", optionals); mOperands.push_back (returnType); mNextOperand = false; return true; } } } } else { // no comma was used between arguments scanner.putbackKeyword (keyword, loc); return false; } return Parser::parseKeyword (keyword, loc, scanner); }
bool LineParser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { if (mState==PotentialEndState) { getErrorHandler().warning ("stray string argument (ignoring it)", loc); mState = EndState; return true; } if (mState==SetState) { std::string name2 = Misc::StringUtils::lowerCase (name); mName = name2; // local variable? char type = mLocals.getType (name2); if (type!=' ') { mType = type; mState = SetLocalVarState; return true; } type = getContext().getGlobalType (name2); if (type!=' ') { mType = type; mState = SetGlobalVarState; return true; } mState = SetPotentialMemberVarState; return true; } if (mState==SetMemberVarState) { mMemberName = Misc::StringUtils::lowerCase (name); std::pair<char, bool> type = getContext().getMemberType (mMemberName, mName); if (type.first!=' ') { mState = SetMemberVarState2; mType = type.first; mReferenceMember = type.second; return true; } getErrorHandler().error ("unknown variable", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } if (mState==MessageState || mState==MessageCommaState) { std::string arguments; for (std::size_t i=0; i<name.size(); ++i) { if (name[i]=='%') { ++i; if (i<name.size()) { if (name[i]=='G' || name[i]=='g') { arguments += "l"; } else if (name[i]=='S' || name[i]=='s') { arguments += 'S'; } else if (name[i]=='.' || name[i]=='f') { arguments += 'f'; } } } } if (!arguments.empty()) { mExprParser.reset(); mExprParser.parseArguments (arguments, scanner, mCode); } mName = name; mButtons = 0; mState = MessageButtonState; return true; } if (mState==MessageButtonState || mState==MessageButtonCommaState) { Generator::pushString (mCode, mLiterals, name); mState = MessageButtonState; ++mButtons; return true; } if (mState==BeginState && getContext().isId (name)) { mState = PotentialExplicitState; mExplicit = Misc::StringUtils::lowerCase (name); return true; } if (mState==BeginState && mAllowExpression) { std::string name2 = Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); if (type!=' ') { scanner.putbackName (name, loc); parseExpression (scanner, loc); return true; } type = getContext().getGlobalType (name2); if (type!=' ') { scanner.putbackName (name, loc); parseExpression (scanner, loc); return true; } } return Parser::parseName (name, loc, scanner); }
bool LineParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (mState==SetMemberVarState) { mMemberName = loc.mLiteral; std::pair<char, bool> type = getContext().getMemberType (mMemberName, mName); if (type.first!=' ') { mState = SetMemberVarState2; mType = type.first; mReferenceMember = type.second; return true; } } if (mState==SetPotentialMemberVarState && keyword==Scanner::K_to) { getErrorHandler().warning ("unknown variable (ignoring set instruction)", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } if (mState==SetState) { // allow keywords to be used as variable names when assigning a value to a variable. return parseName (loc.mLiteral, loc, scanner); } if (mState==BeginState || mState==ExplicitState) { switch (keyword) { case Scanner::K_enable: Generator::enable (mCode, mLiterals, mExplicit); mState = PotentialEndState; return true; case Scanner::K_disable: Generator::disable (mCode, mLiterals, mExplicit); mState = PotentialEndState; return true; case Scanner::K_startscript: mExprParser.parseArguments ("c", scanner, mCode); Generator::startScript (mCode, mLiterals, mExplicit); mState = EndState; return true; case Scanner::K_stopscript: mExprParser.parseArguments ("c", scanner, mCode); Generator::stopScript (mCode); mState = EndState; return true; } // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { std::string argumentType; bool hasExplicit = mState==ExplicitState; if (extensions->isInstruction (keyword, argumentType, hasExplicit)) { if (!hasExplicit && mState==ExplicitState) { getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mExplicit.clear(); } int optionals = 0; try { // workaround for broken positioncell instructions. /// \todo add option to disable this std::auto_ptr<ErrorDowngrade> errorDowngrade (0); if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell") errorDowngrade.reset (new ErrorDowngrade (getErrorHandler())); std::vector<Interpreter::Type_Code> code; optionals = mExprParser.parseArguments (argumentType, scanner, code); mCode.insert (mCode.end(), code.begin(), code.end()); extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit, optionals); } catch (const SourceException& exception) { // Ignore argument exceptions for positioncell. /// \todo add option to disable this if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell") { SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } throw; } mState = EndState; return true; } } if (mAllowExpression) { if (keyword==Scanner::K_getdisabled || keyword==Scanner::K_getdistance) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; bool hasExplicit = !mExplicit.empty(); if (extensions->isFunction (keyword, returnType, argumentType, hasExplicit)) { if (!hasExplicit && !mExplicit.empty()) { getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mExplicit.clear(); } scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } } } } if (mState==ExplicitState) { // drop stray explicit reference getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mState = BeginState; mExplicit.clear(); } if (mState==BeginState) { switch (keyword) { case Scanner::K_short: case Scanner::K_long: case Scanner::K_float: { if (!getContext().canDeclareLocals()) { getErrorHandler().error ( "local variables can't be declared in this context", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return true; } DeclarationParser declaration (getErrorHandler(), getContext(), mLocals); if (declaration.parseKeyword (keyword, loc, scanner)) scanner.scan (declaration); return false; } case Scanner::K_set: mState = SetState; return true; case Scanner::K_messagebox: mState = MessageState; return true; case Scanner::K_return: Generator::exit (mCode); mState = EndState; return true; case Scanner::K_stopscript: mExprParser.parseArguments ("c", scanner, mCode); Generator::stopScript (mCode); mState = EndState; return true; case Scanner::K_else: getErrorHandler().warning ("stray else (ignoring it)", loc); mState = EndState; return true; case Scanner::K_endif: getErrorHandler().warning ("stray endif (ignoring it)", loc); mState = EndState; return true; case Scanner::K_begin: getErrorHandler().warning ("stray begin (ignoring it)", loc); mState = EndState; return true; } } else if (mState==SetLocalVarState && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToLocal (mCode, mLocals.getType (mName), mLocals.getIndex (mName), code, type); mState = EndState; return true; } else if (mState==SetGlobalVarState && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToGlobal (mCode, mLiterals, mType, mName, code, type); mState = EndState; return true; } else if (mState==SetMemberVarState2 && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToMember (mCode, mLiterals, mType, mMemberName, mName, code, type, !mReferenceMember); mState = EndState; return true; } if (mAllowExpression) { if (keyword==Scanner::K_getsquareroot || keyword==Scanner::K_menumode || keyword==Scanner::K_random || keyword==Scanner::K_scriptrunning || keyword==Scanner::K_getsecondspassed) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } } return Parser::parseKeyword (keyword, loc, scanner); }
bool LineParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (mState==EndState && code==Scanner::S_open) { getErrorHandler().warning ("stray '[' or '(' at the end of the line (ignoring it)", loc); return true; } if (code==Scanner::S_newline && (mState==EndState || mState==BeginState || mState==PotentialEndState)) return false; if (code==Scanner::S_comma && mState==MessageState) { mState = MessageCommaState; return true; } if (code==Scanner::S_ref && mState==PotentialExplicitState) { mState = ExplicitState; return true; } if (code==Scanner::S_member && mState==PotentialExplicitState) { mState = MemberState; parseExpression (scanner, loc); mState = EndState; return true; } if (code==Scanner::S_newline && mState==MessageButtonState) { Generator::message (mCode, mLiterals, mName, mButtons); return false; } if (code==Scanner::S_comma && mState==MessageButtonState) { mState = MessageButtonCommaState; return true; } if (code==Scanner::S_member && mState==SetPotentialMemberVarState) { mState = SetMemberVarState; return true; } if (mAllowExpression && mState==BeginState && (code==Scanner::S_open || code==Scanner::S_minus || code==Scanner::S_plus)) { scanner.putbackSpecial (code, loc); parseExpression (scanner, loc); mState = EndState; return true; } return Parser::parseSpecial (code, loc, scanner); }
bool LineParser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { if (mState==ShortState || mState==LongState || mState==FloatState) { if (!getContext().canDeclareLocals()) { getErrorHandler().error ("local variables can't be declared in this context", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } std::string name2 = Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); if (type!=' ') { /// \todo add option to make re-declared local variables an error getErrorHandler().warning ("can't re-declare local variable", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); mState = EndState; return true; } mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'), name2); mState = EndState; return true; } if (mState==SetState) { std::string name2 = Misc::StringUtils::lowerCase (name); mName = name2; // local variable? char type = mLocals.getType (name2); if (type!=' ') { mType = type; mState = SetLocalVarState; return true; } type = getContext().getGlobalType (name2); if (type!=' ') { mType = type; mState = SetGlobalVarState; return true; } mState = SetPotentialMemberVarState; return true; } if (mState==SetMemberVarState) { mMemberName = name; char type = getContext().getMemberType (mMemberName, mName); if (type!=' ') { mState = SetMemberVarState2; mType = type; return true; } getErrorHandler().error ("unknown variable", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } if (mState==MessageState || mState==MessageCommaState) { std::string arguments; for (std::size_t i=0; i<name.size(); ++i) { if (name[i]=='%') { ++i; if (i<name.size()) { if (name[i]=='G' || name[i]=='g') { arguments += "l"; } else if (name[i]=='S' || name[i]=='s') { arguments += 'S'; } else if (name[i]=='.' || name[i]=='f') { arguments += 'f'; } } } } if (!arguments.empty()) { mExprParser.reset(); mExprParser.parseArguments (arguments, scanner, mCode, true); } mName = name; mButtons = 0; mState = MessageButtonState; return true; } if (mState==MessageButtonState || mState==MessageButtonCommaState) { Generator::pushString (mCode, mLiterals, name); mState = MessageButtonState; ++mButtons; return true; } if (mState==BeginState && getContext().isId (name)) { mState = PotentialExplicitState; mExplicit = Misc::StringUtils::lowerCase (name); return true; } if (mState==BeginState && mAllowExpression) { std::string name2 = Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); if (type!=' ') { scanner.putbackName (name, loc); parseExpression (scanner, loc); return true; } type = getContext().getGlobalType (name2); if (type!=' ') { scanner.putbackName (name, loc); parseExpression (scanner, loc); return true; } } return Parser::parseName (name, loc, scanner); }