From bceb7ebcbd61047dc68b220b6c1d6985229e0f2b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Jun 2010 10:22:55 +0200 Subject: [PATCH] reimplemented expression parsing as a separate parser (still only handling non-negative integers) --- CMakeLists.txt | 11 +---- components/compiler/exprparser.cpp | 65 +++++++++++++++++++++++++++++ components/compiler/exprparser.hpp | 67 ++++++++++++++++++++++++++++++ components/compiler/generator.cpp | 37 +++++++++++++---- components/compiler/generator.hpp | 8 ++-- components/compiler/lineparser.cpp | 26 ++++++------ components/compiler/lineparser.hpp | 2 + 7 files changed, 183 insertions(+), 33 deletions(-) create mode 100644 components/compiler/exprparser.cpp create mode 100644 components/compiler/exprparser.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b9815041f..97b34058b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,18 +66,11 @@ set(MISC_HEADER components/misc/fileops.hpp components/misc/slice_array.hpp components/misc/stringops.hpp) source_group(misc FILES ${MISC} ${MISC_HEADER}) -set(COMPILER components/compiler/errorhandler.cpp - components/compiler/fileparser.cpp components/compiler/scriptparser.cpp - components/compiler/lineparser.cpp components/compiler/skipparser.cpp - components/compiler/parser.cpp components/compiler/scanner.cpp - components/compiler/streamerrorhandler.cpp - components/compiler/locals.cpp components/compiler/literals.cpp - components/compiler/output.cpp components/compiler/generator.cpp) +file(GLOB COMPILER components/compiler/*.cpp) file(GLOB COMPILER_HEADER components/compiler/*.hpp) source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER}) -set(INTERPRETER components/interpreter/runtime.cpp components/interpreter/interpreter.cpp - components/interpreter/installopcodes.cpp) +file(GLOB INTERPRETER components/interpreter/*.cpp) file(GLOB INTERPRETER_HEADER components/interpreter/*.hpp) source_group(interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER}) diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp new file mode 100644 index 000000000..117da6b75 --- /dev/null +++ b/components/compiler/exprparser.cpp @@ -0,0 +1,65 @@ + +#include "exprparser.hpp" + +#include + +#include "generator.hpp" + +namespace Compiler +{ + ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals, + Literals& literals) + : Parser (errorHandler, context), mLocals (locals), mLiterals (literals) + {} + + bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) + { + Operand operand; + operand.mType = 'l'; + operand.mInteger = value; + + mOperands.push_back (operand); + + return false; + } + + bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner) + { + 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) + { + return Parser::parseSpecial (code, loc, scanner); + } + + void ExprParser::reset() + { + mOperands.clear(); + } + + char ExprParser::write (std::vector& code) + { + if (mOperands.empty()) + throw std::logic_error ("empty expression"); + + Operand operand = mOperands[mOperands.size()-1]; + mOperands.clear(); + + Generator::pushInt (code, mLiterals, operand.mInteger); + + return operand.mType; + } +} + diff --git a/components/compiler/exprparser.hpp b/components/compiler/exprparser.hpp new file mode 100644 index 000000000..5f58930f4 --- /dev/null +++ b/components/compiler/exprparser.hpp @@ -0,0 +1,67 @@ +#ifndef COMPILER_EXPRPARSER_H_INCLUDED +#define COMPILER_EXPRPARSER_H_INCLUDED + +#include + +#include + +#include "parser.hpp" + +namespace Compiler +{ + class Locals; + class Literals; + + class ExprParser : public Parser + { + struct Operand + { + char mType; + int mInteger; + float mFloat; + }; + + Locals& mLocals; + Literals& mLiterals; + std::vector mOperands; + + public: + + ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals, + Literals& literals); + ///< constructor + + char getType() const; + ///< Return type of parsed expression ('l' integer, 'f' float) + + virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); + ///< Handle an int token. + /// \return fetch another token? + + virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner); + ///< Handle a float token. + /// \return fetch another token? + + virtual bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner); + ///< Handle a name token. + /// \return fetch another token? + + virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + ///< Handle a keyword token. + /// \return fetch another token? + + virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + ///< Handle a special character token. + /// \return fetch another token? + + void reset(); + ///< Reset parser to clean state. + + char write (std::vector& code); + ///< Generate code for parsed expression. + /// \return Type ('l': integer, 'f': float) + }; +} + +#endif diff --git a/components/compiler/generator.cpp b/components/compiler/generator.cpp index e73909d90..8f70a7863 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -2,6 +2,8 @@ #include "generator.hpp" #include +#include +#include #include "literals.hpp" @@ -63,6 +65,11 @@ namespace code.push_back (segment5 (3)); } + void opFloatToInt (Compiler::Generator::CodeContainer& code) + { + assert (0); // not implemented + } + void opStoreLocalShort (Compiler::Generator::CodeContainer& code) { code.push_back (segment5 (0)); @@ -83,20 +90,36 @@ namespace Compiler { namespace Generator { - void assignIntToLocal (CodeContainer& code, Literals& literals, char localType, - int localIndex, int value) + void pushInt (CodeContainer& code, Literals& literals, int value) { - int index = literals.addInteger (value); + int index = literals.addInteger (value); + opPushInt (code, index); + opFetchIntLiteral (code); + } + void assignToLocal (CodeContainer& code, char localType, + int localIndex, const CodeContainer& value, char valueType) + { opPushInt (code, localIndex); - opPushInt (code, index); - opFetchIntLiteral (code); + + std::copy (value.begin(), value.end(), std::back_inserter (code)); + + if (localType!=valueType) + { + if (localType=='f' && valueType=='l') + { + opIntToFloat (code); + } + else if ((localType=='l' || localType=='s') && valueType=='f') + { + opFloatToInt (code); + } + } switch (localType) { case 'f': - opIntToFloat (code); opStoreLocalFloat (code); break; @@ -113,7 +136,7 @@ namespace Compiler default: assert (0); - } + } } } } diff --git a/components/compiler/generator.hpp b/components/compiler/generator.hpp index cab5f3bda..a055b3c71 100644 --- a/components/compiler/generator.hpp +++ b/components/compiler/generator.hpp @@ -12,9 +12,11 @@ namespace Compiler namespace Generator { typedef std::vector CodeContainer; - - void assignIntToLocal (CodeContainer& code, Literals& literals, char localType, - int localIndex, int value); + + void pushInt (CodeContainer& code, Literals& literals, int value); + + void assignToLocal (CodeContainer& code, char localType, + int localIndex, const CodeContainer& value, char valueType); } } diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 47346b814..1685af848 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -13,22 +13,11 @@ 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) + mState (BeginState), mExprParser (errorHandler, context, locals, literals) {} bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) - { - if (mState==SetLocalToState) - { - Generator::assignIntToLocal (mCode, mLiterals, mLocals.getType (mName), - mLocals.getIndex (mName), value); - - mState = EndState; - mName.clear(); - - return true; - } - + { return Parser::parseInt (value, loc, scanner); } @@ -104,7 +93,16 @@ namespace Compiler } else if (mState==SetLocalVarState && keyword==Scanner::K_to) { - mState = SetLocalToState; + mExprParser.reset(); + scanner.scan (mExprParser); + + std::vector code; + char type = mExprParser.write (code); + + Generator::assignToLocal (mCode, mLocals.getType (mName), + mLocals.getIndex (mName), code, type); + + mState = EndState; return true; } diff --git a/components/compiler/lineparser.hpp b/components/compiler/lineparser.hpp index b69ac803e..2f195902d 100644 --- a/components/compiler/lineparser.hpp +++ b/components/compiler/lineparser.hpp @@ -6,6 +6,7 @@ #include #include "parser.hpp" +#include "exprparser.hpp" namespace Compiler { @@ -29,6 +30,7 @@ namespace Compiler std::vector& mCode; State mState; std::string mName; + ExprParser mExprParser; public: