diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e044d3d0..52704c2bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,7 +171,8 @@ endif (APPLE) option(BUILD_MWCOMPILER "build standalone Morrowind script compiler" ON) if (BUILD_MWCOMPILER) -set(TOOLS_MWCOMPILER ${COMPILER} apps/mwcompiler/main.cpp) +set(TOOLS_MWCOMPILER ${COMPILER} apps/mwcompiler/main.cpp apps/mwcompiler/context.cpp + apps/mwcompiler/context.hpp) add_executable(mwcompiler ${TOOLS_MWCOMPILER}) endif() diff --git a/apps/mwcompiler/context.cpp b/apps/mwcompiler/context.cpp new file mode 100644 index 000000000..72e3aa490 --- /dev/null +++ b/apps/mwcompiler/context.cpp @@ -0,0 +1,11 @@ + +#include "context.hpp" + +namespace SACompiler +{ + bool Context::canDeclareLocals() const + { + return true; + } +} + diff --git a/apps/mwcompiler/context.hpp b/apps/mwcompiler/context.hpp new file mode 100644 index 000000000..23188ecf2 --- /dev/null +++ b/apps/mwcompiler/context.hpp @@ -0,0 +1,18 @@ +#ifndef MWCOMPILER_CONTEXT_H_INCLUDED +#define MWCOMPILER_CONTEXT_H_INCLUDED + +#include + +namespace SACompiler +{ + class Context : public Compiler::Context + { + public: + + virtual bool canDeclareLocals() const; + ///< Is the compiler allowed to declare local variables? + }; +} + +#endif + diff --git a/apps/mwcompiler/main.cpp b/apps/mwcompiler/main.cpp index 231496846..a4ec9a573 100644 --- a/apps/mwcompiler/main.cpp +++ b/apps/mwcompiler/main.cpp @@ -7,14 +7,15 @@ #include #include #include -#include #include +#include "context.hpp" + int main (int argc, char **argv) { try { - Compiler::Context context; + SACompiler::Context context; Compiler::StreamErrorHandler errorHandler (std::cout); Compiler::FileParser parser (errorHandler, context); diff --git a/components/compiler/context.hpp b/components/compiler/context.hpp index 795514cfd..d5284ffc9 100644 --- a/components/compiler/context.hpp +++ b/components/compiler/context.hpp @@ -5,7 +5,12 @@ namespace Compiler { class Context { - + public: + + virtual ~Context() {} + + virtual bool canDeclareLocals() const = 0; + ///< Is the compiler allowed to declare local variables? }; } diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 8d1fa70aa..f90352559 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -1,12 +1,16 @@ #include "lineparser.hpp" +#include + #include "scanner.hpp" +#include "context.hpp" +#include "errorhandler.hpp" namespace Compiler { LineParser::LineParser (ErrorHandler& errorHandler, Context& context) - : Parser (errorHandler, context) + : Parser (errorHandler, context), mState (BeginState) {} bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) @@ -22,22 +26,45 @@ namespace Compiler 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); + + std::cout << "declaring local variable: " << name << std::endl; + mState = EndState; + return true; + } + return Parser::parseName (name, loc, scanner); } bool LineParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { + if (mState==BeginState) + { + switch (keyword) + { + case Scanner::K_short: mState = ShortState; return true; + case Scanner::K_long: mState = LongState; return true; + case Scanner::K_float: mState = FloatState; 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; + return Parser::parseSpecial (code, loc, scanner); } void LineParser::reset() { - + mState = BeginState; } } diff --git a/components/compiler/lineparser.hpp b/components/compiler/lineparser.hpp index 8b11dcf4a..420315551 100644 --- a/components/compiler/lineparser.hpp +++ b/components/compiler/lineparser.hpp @@ -9,6 +9,15 @@ namespace Compiler class LineParser : public Parser { + enum State + { + BeginState, + ShortState, LongState, FloatState, + EndState + }; + + State mState; + public: LineParser (ErrorHandler& errorHandler, Context& context);