diff --git a/components/compiler/context.hpp b/components/compiler/context.hpp index d5284ffc9..e79416498 100644 --- a/components/compiler/context.hpp +++ b/components/compiler/context.hpp @@ -3,14 +3,23 @@ namespace Compiler { + class Extensions; + class Context { + const Extensions *mExtensions; + public: + Context() : mExtensions (0) {} + virtual ~Context() {} virtual bool canDeclareLocals() const = 0; ///< Is the compiler allowed to declare local variables? + + void setExtensions (const Extensions *extensions = 0); + ///< Set compiler extensions. }; } diff --git a/components/compiler/extensions.cpp b/components/compiler/extensions.cpp new file mode 100644 index 000000000..31f530d9e --- /dev/null +++ b/components/compiler/extensions.cpp @@ -0,0 +1,18 @@ + +#include "extensions.hpp" + +namespace Compiler +{ + + Extensions::Extensions() : mNextKeywordIndex (-1) {} + + int Extensions::searchKeyword (const std::string& keyword) const + { + std::map::const_iterator iter = mKeywords.find (keyword); + + if (iter==mKeywords.end()) + return 0; + + return iter->second; + } +} diff --git a/components/compiler/extensions.hpp b/components/compiler/extensions.hpp new file mode 100644 index 000000000..7bf758b2e --- /dev/null +++ b/components/compiler/extensions.hpp @@ -0,0 +1,28 @@ +#ifndef COMPILER_EXTENSIONS_H_INCLUDED +#define COMPILER_EXTENSINOS_H_INCLUDED + +#include +#include + +namespace Compiler +{ + /// \brief Collection of compiler extensions + + class Extensions + { + int mNextKeywordIndex; + std::map mKeywords; + + public: + + Extensions(); + + int searchKeyword (const std::string& keyword) const; + ///< Return extension keyword code, that is assigned to the string \a keyword. + /// - if no match is found 0 is returned. + /// - keyword must be all lower case. + }; +} + +#endif + diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index f0001fe85..11338eeb2 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -9,6 +9,7 @@ #include "exception.hpp" #include "errorhandler.hpp" #include "parser.hpp" +#include "extensions.hpp" namespace Compiler { @@ -271,8 +272,22 @@ namespace Compiler if (lowerCase==keywords[i]) break; - cont = - keywords[i] ? parser.parseKeyword (i, loc, *this) : parser.parseName (name, loc, *this); + if (keywords[i]) + { + cont = parser.parseKeyword (i, loc, *this); + return true; + } + + if (mExtensions) + { + if (int keyword = mExtensions->searchKeyword (lowerCase)) + { + cont = parser.parseKeyword (keyword, loc, *this); + return true; + } + } + + cont = parser.parseName (name, loc, *this); return true; } @@ -445,8 +460,10 @@ namespace Compiler // constructor - Scanner::Scanner (ErrorHandler& errorHandler, std::istream& inputStream) - : mErrorHandler (errorHandler), mStream (inputStream), mPutback (Putback_None) + Scanner::Scanner (ErrorHandler& errorHandler, std::istream& inputStream, + const Extensions *extensions) + : mErrorHandler (errorHandler), mStream (inputStream), mExtensions (extensions), + mPutback (Putback_None) { } diff --git a/components/compiler/scanner.hpp b/components/compiler/scanner.hpp index 2dd13d5df..8c0f078c6 100644 --- a/components/compiler/scanner.hpp +++ b/components/compiler/scanner.hpp @@ -10,6 +10,7 @@ namespace Compiler { class ErrorHandler; class Parser; + class Extensions; /// \brief Scanner /// @@ -28,6 +29,7 @@ namespace Compiler TokenLoc mLoc; TokenLoc mPrevLoc; std::istream& mStream; + const Extensions *mExtensions; putback_type mPutback; int mPutbackCode; int mPutbackInteger; @@ -86,7 +88,8 @@ namespace Compiler public: - Scanner (ErrorHandler& errorHandler, std::istream& inputStream); + Scanner (ErrorHandler& errorHandler, std::istream& inputStream, + const Extensions *extensions = 0); ///< constructor void scan (Parser& parser);