#include "exprparser.hpp" #include #include "generator.hpp" #include "scanner.hpp" #include "errorhandler.hpp" namespace Compiler { char ExprParser::popUnaryOperator() { if (mOperators.empty()) return 0; char op = mOperators[mOperators.size()-1]; if (op!='m') // unary - return 0; mOperators.resize (mOperators.size()-1); return op; } char ExprParser::popOperand (std::vector& code) { Operand operand = mOperands[mOperands.size()-1]; mOperands.resize (mOperands.size()-1); if (operand.mType=='l') Generator::pushInt (code, mLiterals, operand.mInteger); else if (operand.mType=='f') Generator::pushFloat (code, mLiterals, operand.mFloat); else throw std::logic_error ("unknown expression type"); return operand.mType; } ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals, Literals& literals) : Parser (errorHandler, context), mLocals (locals), mLiterals (literals), mNextOperand (true) {} bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) { if (mNextOperand) { Operand operand; operand.mType = 'l'; operand.mInteger = value; mOperands.push_back (operand); mNextOperand = false; mTokenLoc = loc; return true; } return Parser::parseInt (value, loc, scanner); } bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner) { if (mNextOperand) { Operand operand; operand.mType = 'f'; operand.mFloat = value; mOperands.push_back (operand); mNextOperand = false; mTokenLoc = loc; return true; } return Parser::parseFloat (value, loc, scanner); } bool ExprParser::parseName (const std::string& name, const TokenLoc& loc, Scanner& scanner) { return Parser::parseName (name, loc, scanner); } bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { return Parser::parseKeyword (keyword, loc, scanner); } bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (code==Scanner::S_comma) { // end marker mTokenLoc = loc; return false; } if (code==Scanner::S_newline) { // end marker mTokenLoc = loc; scanner.putbackNewline (loc); return false; } if (code==Scanner::S_minus) { if (mNextOperand) { // unary mOperators.push_back ('m'); mTokenLoc = loc; return true; } } return Parser::parseSpecial (code, loc, scanner); } void ExprParser::reset() { mOperands.clear(); mOperators.clear(); mNextOperand = true; } char ExprParser::write (std::vector& code) { if (mOperands.empty() && mOperators.empty()) getErrorHandler().error ("missing expression", mTokenLoc); if (mNextOperand) getErrorHandler().error ("syntax error in expression", mTokenLoc); char type = ' '; while (!mOperands.empty()) { type = popOperand (code); while (char op = popUnaryOperator()) { if (op=='m') { Generator::negate (code, type); } else throw std::logic_error ("unknown unary operator"); } } return type; } }