enhanced compiler extenion system to support new instructions and functions with explicit references

actorid
Marc Zinnschlag 15 years ago
parent 69e607e140
commit 71c710f9f6

@ -324,6 +324,27 @@ namespace Compiler
mNextOperand = false; mNextOperand = false;
return true; 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); return Parser::parseKeyword (keyword, loc, scanner);
@ -418,7 +439,7 @@ namespace Compiler
mTokenLoc = loc; mTokenLoc = loc;
parseArguments (argumentType, scanner); parseArguments (argumentType, scanner);
extensions->generateFunctionCode (keyword, mCode); extensions->generateFunctionCode (keyword, mCode, mLiterals, "");
mOperands.push_back (returnType); mOperands.push_back (returnType);
mNextOperand = false; mNextOperand = false;

@ -5,6 +5,7 @@
#include <stdexcept> #include <stdexcept>
#include "generator.hpp" #include "generator.hpp"
#include "literals.hpp"
namespace Compiler namespace Compiler
{ {
@ -44,7 +45,7 @@ namespace Compiler
} }
void Extensions::registerFunction (const std::string& keyword, char returnType, 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); assert (segment5code>=33554432 && segment5code<=67108863);
@ -56,12 +57,13 @@ namespace Compiler
function.mReturn = returnType; function.mReturn = returnType;
function.mArguments = argumentType; function.mArguments = argumentType;
function.mCode = segment5code; function.mCode = segment5code;
function.mCodeExplicit = segment5codeExplicit;
mFunctions.insert (std::make_pair (code, function)); mFunctions.insert (std::make_pair (code, function));
} }
void Extensions::registerInstruction (const std::string& keyword, 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); assert (segment5code>=33554432 && segment5code<=67108863);
@ -72,23 +74,31 @@ namespace Compiler
Instruction instruction; Instruction instruction;
instruction.mArguments = argumentType; instruction.mArguments = argumentType;
instruction.mCode = segment5code; instruction.mCode = segment5code;
instruction.mCodeExplicit = segment5codeExplicit;
mInstructions.insert (std::make_pair (code, instruction)); mInstructions.insert (std::make_pair (code, instruction));
} }
void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code) void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
const Literals& literals, const std::string& id) const
{ {
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword); std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
if (iter==mFunctions.end()) if (iter==mFunctions.end())
throw std::logic_error ("unknown custom function keyword"); 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, void Extensions::generateInstructionCode (int keyword,
std::vector<Interpreter::Type_Code>& code) std::vector<Interpreter::Type_Code>& code, Literals& literals, const std::string& id)
const const
{ {
std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword); std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword);
@ -96,6 +106,13 @@ namespace Compiler
if (iter==mInstructions.end()) if (iter==mInstructions.end())
throw std::logic_error ("unknown custom instruction keyword"); 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));
} }
} }

@ -9,6 +9,8 @@
namespace Compiler namespace Compiler
{ {
class Literals;
/// \brief Collection of compiler extensions /// \brief Collection of compiler extensions
class Extensions class Extensions
@ -18,12 +20,14 @@ namespace Compiler
char mReturn; char mReturn;
std::string mArguments; std::string mArguments;
int mCode; int mCode;
int mCodeExplicit;
}; };
struct Instruction struct Instruction
{ {
std::string mArguments; std::string mArguments;
int mCode; int mCode;
int mCodeExplicit;
}; };
int mNextKeywordIndex; int mNextKeywordIndex;
@ -48,25 +52,27 @@ namespace Compiler
///< Is this keyword registered with a function? If yes, return argument types. ///< Is this keyword registered with a function? If yes, return argument types.
void registerFunction (const std::string& keyword, char returnType, 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 ///< Register a custom function
/// - keyword must be all lower case. /// - keyword must be all lower case.
/// - keyword must be unique /// - keyword must be unique
/// - if explicit references are not supported, segment5codeExplicit must be set to -1
/// \note Currently only segment 5 opcodes are supported. /// \note Currently only segment 5 opcodes are supported.
void registerInstruction (const std::string& keyword, 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 ///< Register a custom instruction
/// - keyword must be all lower case. /// - keyword must be all lower case.
/// - keyword must be unique /// - keyword must be unique
/// - if explicit references are not supported, segment5codeExplicit must be set to -1
/// \note Currently only segment 5 opcodes are supported. /// \note Currently only segment 5 opcodes are supported.
void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code) void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
const; Literals& literals, const std::string& id) const;
///< Append code for function to \a code. ///< Append code for function to \a code.
void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code) void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
const; Literals& literals, const std::string& id) const;
///< Append code for function to \a code. ///< Append code for function to \a code.
}; };
} }

@ -157,6 +157,21 @@ namespace Compiler
mState = EndState; mState = EndState;
return true; 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) if (mState==BeginState)
@ -189,21 +204,6 @@ namespace Compiler
mState = EndState; mState = EndState;
return true; 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) else if (mState==SetLocalVarState && keyword==Scanner::K_to)
{ {

Loading…
Cancel
Save