From 71c710f9f65f809ced7000259b997a6926fbb9dd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Jul 2010 22:01:24 +0200 Subject: [PATCH] enhanced compiler extenion system to support new instructions and functions with explicit references --- components/compiler/exprparser.cpp | 23 +++++++++++++++++++++- components/compiler/extensions.cpp | 31 +++++++++++++++++++++++------- components/compiler/extensions.hpp | 18 +++++++++++------ components/compiler/lineparser.cpp | 30 ++++++++++++++--------------- 4 files changed, 73 insertions(+), 29 deletions(-) diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index 2938bbae3..db7f8a2d2 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -324,6 +324,27 @@ namespace Compiler mNextOperand = false; return true; } + + // check for custom extensions + if (const Extensions *extensions = getContext().getExtensions()) + { + char returnType; + std::string argumentType; + + if (extensions->isFunction (keyword, returnType, argumentType)) + { + mTokenLoc = loc; + parseArguments (argumentType, scanner); + + extensions->generateFunctionCode (keyword, mCode, mLiterals, mExplicit); + mOperands.push_back (returnType); + mExplicit.clear(); + mRefOp = false; + + mNextOperand = false; + return true; + } + } } return Parser::parseKeyword (keyword, loc, scanner); @@ -418,7 +439,7 @@ namespace Compiler mTokenLoc = loc; parseArguments (argumentType, scanner); - extensions->generateFunctionCode (keyword, mCode); + extensions->generateFunctionCode (keyword, mCode, mLiterals, ""); mOperands.push_back (returnType); mNextOperand = false; diff --git a/components/compiler/extensions.cpp b/components/compiler/extensions.cpp index ff05208de..9a6ea7f63 100644 --- a/components/compiler/extensions.cpp +++ b/components/compiler/extensions.cpp @@ -5,6 +5,7 @@ #include #include "generator.hpp" +#include "literals.hpp" namespace Compiler { @@ -44,7 +45,7 @@ namespace Compiler } void Extensions::registerFunction (const std::string& keyword, char returnType, - const std::string& argumentType, int segment5code) + const std::string& argumentType, int segment5code, int segment5codeExplicit) { assert (segment5code>=33554432 && segment5code<=67108863); @@ -56,12 +57,13 @@ namespace Compiler function.mReturn = returnType; function.mArguments = argumentType; function.mCode = segment5code; + function.mCodeExplicit = segment5codeExplicit; mFunctions.insert (std::make_pair (code, function)); } void Extensions::registerInstruction (const std::string& keyword, - const std::string& argumentType, int segment5code) + const std::string& argumentType, int segment5code, int segment5codeExplicit) { assert (segment5code>=33554432 && segment5code<=67108863); @@ -72,23 +74,31 @@ namespace Compiler Instruction instruction; instruction.mArguments = argumentType; instruction.mCode = segment5code; + instruction.mCodeExplicit = segment5codeExplicit; mInstructions.insert (std::make_pair (code, instruction)); } - void Extensions::generateFunctionCode (int keyword, std::vector& code) - const + void Extensions::generateFunctionCode (int keyword, std::vector& code, + Literals& literals, const std::string& id) const { std::map::const_iterator iter = mFunctions.find (keyword); if (iter==mFunctions.end()) throw std::logic_error ("unknown custom function keyword"); - code.push_back (Generator::segment5 (iter->second.mCode)); + if (!id.empty()) + { + int index = literals.addString (id); + Generator::pushInt (code, literals, index); + } + + code.push_back (Generator::segment5 ( + id.empty() ? iter->second.mCode : iter->second.mCodeExplicit)); } void Extensions::generateInstructionCode (int keyword, - std::vector& code) + std::vector& code, Literals& literals, const std::string& id) const { std::map::const_iterator iter = mInstructions.find (keyword); @@ -96,6 +106,13 @@ namespace Compiler if (iter==mInstructions.end()) throw std::logic_error ("unknown custom instruction keyword"); - code.push_back (Generator::segment5 (iter->second.mCode)); + if (!id.empty()) + { + int index = literals.addString (id); + Generator::pushInt (code, literals, index); + } + + code.push_back (Generator::segment5 ( + id.empty() ? iter->second.mCode : iter->second.mCodeExplicit)); } } diff --git a/components/compiler/extensions.hpp b/components/compiler/extensions.hpp index f864daf1b..f1a856818 100644 --- a/components/compiler/extensions.hpp +++ b/components/compiler/extensions.hpp @@ -9,6 +9,8 @@ namespace Compiler { + class Literals; + /// \brief Collection of compiler extensions class Extensions @@ -18,12 +20,14 @@ namespace Compiler char mReturn; std::string mArguments; int mCode; + int mCodeExplicit; }; struct Instruction { std::string mArguments; int mCode; + int mCodeExplicit; }; int mNextKeywordIndex; @@ -48,25 +52,27 @@ namespace Compiler ///< Is this keyword registered with a function? If yes, return argument types. void registerFunction (const std::string& keyword, char returnType, - const std::string& argumentType, int segment5code); + const std::string& argumentType, int segment5code, int segment5codeExplicit = -1); ///< Register a custom function /// - keyword must be all lower case. /// - keyword must be unique + /// - if explicit references are not supported, segment5codeExplicit must be set to -1 /// \note Currently only segment 5 opcodes are supported. void registerInstruction (const std::string& keyword, - const std::string& argumentType, int segment5code); + const std::string& argumentType, int segment5code, int segment5codeExplicit = -1); ///< Register a custom instruction /// - keyword must be all lower case. /// - keyword must be unique + /// - if explicit references are not supported, segment5codeExplicit must be set to -1 /// \note Currently only segment 5 opcodes are supported. - void generateFunctionCode (int keyword, std::vector& code) - const; + void generateFunctionCode (int keyword, std::vector& code, + Literals& literals, const std::string& id) const; ///< Append code for function to \a code. - void generateInstructionCode (int keyword, std::vector& code) - const; + void generateInstructionCode (int keyword, std::vector& code, + Literals& literals, const std::string& id) const; ///< Append code for function to \a code. }; } diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index d46d5f093..3be38bce4 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -157,6 +157,21 @@ namespace Compiler mState = EndState; return true; } + + // check for custom extensions + if (const Extensions *extensions = getContext().getExtensions()) + { + std::string argumentType; + + if (extensions->isInstruction (keyword, argumentType)) + { + mExprParser.parseArguments (argumentType, scanner, mCode, true); + + extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit); + mState = EndState; + return true; + } + } } if (mState==BeginState) @@ -189,21 +204,6 @@ namespace Compiler mState = EndState; return true; } - - // check for custom extensions - if (const Extensions *extensions = getContext().getExtensions()) - { - std::string argumentType; - - if (extensions->isInstruction (keyword, argumentType)) - { - mExprParser.parseArguments (argumentType, scanner, mCode, true); - - extensions->generateInstructionCode (keyword, mCode); - mState = EndState; - return true; - } - } } else if (mState==SetLocalVarState && keyword==Scanner::K_to) {