bool Parser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected name", loc); else scanner.putbackName (name, loc); return false; }
bool ControlParser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { if (mState==IfBodyState || mState==IfElseifBodyState || mState==IfElseBodyState || mState==WhileBodyState) { scanner.putbackName (name, loc); mLineParser.reset(); scanner.scan (mLineParser); return true; } return Parser::parseName (name, loc, scanner); }
bool ExprParser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { if (!mExplicit.empty()) return Parser::parseName (name, loc, scanner); mFirst = false; if (mNextOperand) { std::string name2 = toLower (name); char type = mLocals.getType (name2); if (type!=' ') { Generator::fetchLocal (mCode, type, mLocals.getIndex (name2)); mNextOperand = false; mOperands.push_back (type=='f' ? 'f' : 'l'); return true; } type = getContext().getGlobalType (name2); if (type!=' ') { Generator::fetchGlobal (mCode, mLiterals, type, name2); mNextOperand = false; mOperands.push_back (type=='f' ? 'f' : 'l'); return true; } if (mExplicit.empty() && getContext().isId (name)) { mExplicit = name; return true; } } else { // no comma was used between arguments scanner.putbackName (name, loc); return false; } return Parser::parseName (name, loc, scanner); }
bool ExprParser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { if (!mExplicit.empty()) { if (mMemberOp && handleMemberAccess (name)) return true; return Parser::parseName (name, loc, scanner); } mFirst = false; if (mNextOperand) { start(); std::string name2 = Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); if (type!=' ') { Generator::fetchLocal (mCode, type, mLocals.getIndex (name2)); mNextOperand = false; mOperands.push_back (type=='f' ? 'f' : 'l'); return true; } type = getContext().getGlobalType (name2); if (type!=' ') { Generator::fetchGlobal (mCode, mLiterals, type, name2); mNextOperand = false; mOperands.push_back (type=='f' ? 'f' : 'l'); return true; } // die in a fire, Morrowind script compiler! if (const Extensions *extensions = getContext().getExtensions()) { if (getContext().isJournalId (name2)) { // JournalID used as an argument. Use the index of that JournalID Generator::pushString (mCode, mLiterals, name2); int keyword = extensions->searchKeyword ("getjournalindex"); extensions->generateFunctionCode (keyword, mCode, mLiterals, mExplicit, 0); mNextOperand = false; mOperands.push_back ('l'); return 2; } } if (mExplicit.empty() && getContext().isId (name2)) { mExplicit = name2; return true; } } else { // no comma was used between arguments scanner.putbackName (name, loc); return false; } return Parser::parseName (name, 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::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); }