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;
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;

@ -5,6 +5,7 @@
#include <stdexcept>
#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<Interpreter::Type_Code>& code)
const
void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
Literals& literals, const std::string& id) const
{
std::map<int, Function>::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<Interpreter::Type_Code>& code)
std::vector<Interpreter::Type_Code>& code, Literals& literals, const std::string& id)
const
{
std::map<int, Instruction>::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));
}
}

@ -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<Interpreter::Type_Code>& code)
const;
void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
Literals& literals, const std::string& id) const;
///< Append code for function to \a code.
void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
const;
void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
Literals& literals, const std::string& id) const;
///< Append code for function to \a code.
};
}

@ -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)
{

Loading…
Cancel
Save