#include "lineparser.hpp" #include "scanner.hpp" #include "context.hpp" #include "errorhandler.hpp" #include "skipparser.hpp" #include "locals.hpp" #include "generator.hpp" namespace Compiler { LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals, Literals& literals, std::vector& code) : Parser (errorHandler, context), mLocals (locals), mLiterals (literals), mCode (code), mState (BeginState), mExprParser (errorHandler, context, locals, literals) {} bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) { return Parser::parseInt (value, loc, scanner); } bool LineParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner) { return Parser::parseFloat (value, 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 = toLower (name); char type = mLocals.getType (name2); if (type!=' ') { getErrorHandler().error ("can't re-declare local variable", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'), name2); mState = EndState; return true; } if (mState==SetState) { // local variable? std::string name2 = toLower (name); char type = mLocals.getType (name2); if (type!=' ') { mName = name2; mState = SetLocalVarState; 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 code; char type = mExprParser.append (code); Generator::assignToLocal (mCode, mLocals.getType (mName), mLocals.getIndex (mName), code, type); mState = EndState; return true; } return Parser::parseKeyword (keyword, loc, scanner); } bool LineParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (code==Scanner::S_newline && mState==EndState) return false; if (code==Scanner::S_comma && mState==MessageState) { mState = MessageCommaState; return true; } return Parser::parseSpecial (code, loc, scanner); } void LineParser::reset() { mState = BeginState; mName.clear(); } }