added custom function handling (compiler)

actorid
Marc Zinnschlag 15 years ago
parent a1beffc3cd
commit 32eafaa301

@ -18,8 +18,15 @@ namespace Compiler
virtual bool canDeclareLocals() const = 0; virtual bool canDeclareLocals() const = 0;
///< Is the compiler allowed to declare local variables? ///< Is the compiler allowed to declare local variables?
void setExtensions (const Extensions *extensions = 0); void setExtensions (const Extensions *extensions = 0)
///< Set compiler extensions. {
mExtensions = extensions;
}
const Extensions *getExtensions() const
{
return mExtensions;
}
}; };
} }

@ -12,6 +12,8 @@
#include "errorhandler.hpp" #include "errorhandler.hpp"
#include "locals.hpp" #include "locals.hpp"
#include "stringparser.hpp" #include "stringparser.hpp"
#include "extensions.hpp"
#include "context.hpp"
namespace Compiler namespace Compiler
{ {
@ -279,6 +281,27 @@ namespace Compiler
mNextOperand = false; mNextOperand = false;
return true; return true;
} }
else
{
// 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);
mOperands.push_back (returnType);
mNextOperand = false;
return true;
}
}
}
} }
else else
{ {

@ -1,9 +1,13 @@
#include "extensions.hpp" #include "extensions.hpp"
#include <cassert>
#include <stdexcept>
#include "generator.hpp"
namespace Compiler namespace Compiler
{ {
Extensions::Extensions() : mNextKeywordIndex (-1) {} Extensions::Extensions() : mNextKeywordIndex (-1) {}
int Extensions::searchKeyword (const std::string& keyword) const int Extensions::searchKeyword (const std::string& keyword) const
@ -15,4 +19,44 @@ namespace Compiler
return iter->second; return iter->second;
} }
bool Extensions::isFunction (int keyword, char& returnType, std::string& argumentType) const
{
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
if (iter==mFunctions.end())
return false;
returnType = iter->second.mReturn;
argumentType = iter->second.mArguments;
return true;
}
void Extensions::registerFunction (const std::string& keyword, char returnType,
const std::string& argumentType, int segment5code)
{
assert (segment5code>=33554432 && segment5code<=67108863);
int code = mNextKeywordIndex--;
mKeywords.insert (std::make_pair (keyword, code));
Function function;
function.mReturn = returnType;
function.mArguments = argumentType;
function.mCode = segment5code;
mFunctions.insert (std::make_pair (code, function));
}
void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
const
{
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
if (iter==mFunctions.end())
throw std::logic_error ("unknown custom function keyword");
Generator::segment5 (iter->second.mCode);
}
} }

@ -3,6 +3,9 @@
#include <string> #include <string>
#include <map> #include <map>
#include <vector>
#include <components/interpreter/types.hpp>
namespace Compiler namespace Compiler
{ {
@ -10,9 +13,17 @@ namespace Compiler
class Extensions class Extensions
{ {
struct Function
{
char mReturn;
std::string mArguments;
int mCode;
};
int mNextKeywordIndex; int mNextKeywordIndex;
std::map<std::string, int> mKeywords; std::map<std::string, int> mKeywords;
std::map<int, Function> mFunctions;
public: public:
Extensions(); Extensions();
@ -21,6 +32,21 @@ namespace Compiler
///< Return extension keyword code, that is assigned to the string \a keyword. ///< Return extension keyword code, that is assigned to the string \a keyword.
/// - if no match is found 0 is returned. /// - if no match is found 0 is returned.
/// - keyword must be all lower case. /// - keyword must be all lower case.
bool isFunction (int keyword, char& returnType, std::string& argumentType) const;
///< Is this keyword registered with a function? If yes, return return and argument
/// types.
void registerFunction (const std::string& keyword, char returnType,
const std::string& argumentType, int segment5code);
///< Register a custom function
/// - keyword must be all lower case.
/// - keyword must be unique
/// \note Currently only segment 5 opcodes are supported.
void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
const;
///< Append code for function to \a code.
}; };
} }

@ -9,251 +9,215 @@
#include "literals.hpp" #include "literals.hpp"
namespace namespace
{ {
Interpreter::Type_Code segment0 (unsigned int c, unsigned int arg0)
{
assert (c<64);
return (c<<24) | (arg0 & 0xffffff);
}
Interpreter::Type_Code segment1 (unsigned int c, unsigned int arg0, unsigned int arg1)
{
assert (c<64);
return 0x40000000 | (c<<24) | ((arg0 & 0xfff)<<12) | (arg1 & 0xfff);
}
Interpreter::Type_Code segment2 (unsigned int c, unsigned int arg0)
{
assert (c<1024);
return 0x80000000 | (c<<20) | (arg0 & 0xfffff);
}
Interpreter::Type_Code segment3 (unsigned int c, unsigned int arg0)
{
assert (c<1024);
return 0xc0000000 | (c<<20) | (arg0 & 0xffff);
}
Interpreter::Type_Code segment4 (unsigned int c, unsigned int arg0, unsigned int arg1)
{
assert (c<1024);
return 0xc4000000 | (c<<16) | ((arg0 & 0xff)<<8) | (arg1 & 0xff);
}
Interpreter::Type_Code segment5 (unsigned int c)
{
assert (c<67108864);
return 0xc8000000 | c;
}
void opPushInt (Compiler::Generator::CodeContainer& code, int value) void opPushInt (Compiler::Generator::CodeContainer& code, int value)
{ {
code.push_back (segment0 (0, value)); code.push_back (Compiler::Generator::segment0 (0, value));
} }
void opFetchIntLiteral (Compiler::Generator::CodeContainer& code) void opFetchIntLiteral (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (4)); code.push_back (Compiler::Generator::segment5 (4));
} }
void opFetchFloatLiteral (Compiler::Generator::CodeContainer& code) void opFetchFloatLiteral (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (5)); code.push_back (Compiler::Generator::segment5 (5));
} }
void opIntToFloat (Compiler::Generator::CodeContainer& code) void opIntToFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (3)); code.push_back (Compiler::Generator::segment5 (3));
} }
void opFloatToInt (Compiler::Generator::CodeContainer& code) void opFloatToInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (6)); code.push_back (Compiler::Generator::segment5 (6));
} }
void opStoreLocalShort (Compiler::Generator::CodeContainer& code) void opStoreLocalShort (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (0)); code.push_back (Compiler::Generator::segment5 (0));
} }
void opStoreLocalLong (Compiler::Generator::CodeContainer& code) void opStoreLocalLong (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (1)); code.push_back (Compiler::Generator::segment5 (1));
} }
void opStoreLocalFloat (Compiler::Generator::CodeContainer& code) void opStoreLocalFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (2)); code.push_back (Compiler::Generator::segment5 (2));
} }
void opNegateInt (Compiler::Generator::CodeContainer& code) void opNegateInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (7)); code.push_back (Compiler::Generator::segment5 (7));
} }
void opNegateFloat (Compiler::Generator::CodeContainer& code) void opNegateFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (8)); code.push_back (Compiler::Generator::segment5 (8));
} }
void opAddInt (Compiler::Generator::CodeContainer& code) void opAddInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (9)); code.push_back (Compiler::Generator::segment5 (9));
} }
void opAddFloat (Compiler::Generator::CodeContainer& code) void opAddFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (10)); code.push_back (Compiler::Generator::segment5 (10));
} }
void opSubInt (Compiler::Generator::CodeContainer& code) void opSubInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (11)); code.push_back (Compiler::Generator::segment5 (11));
} }
void opSubFloat (Compiler::Generator::CodeContainer& code) void opSubFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (12)); code.push_back (Compiler::Generator::segment5 (12));
} }
void opMulInt (Compiler::Generator::CodeContainer& code) void opMulInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (13)); code.push_back (Compiler::Generator::segment5 (13));
} }
void opMulFloat (Compiler::Generator::CodeContainer& code) void opMulFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (14)); code.push_back (Compiler::Generator::segment5 (14));
} }
void opDivInt (Compiler::Generator::CodeContainer& code) void opDivInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (15)); code.push_back (Compiler::Generator::segment5 (15));
} }
void opDivFloat (Compiler::Generator::CodeContainer& code) void opDivFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (16)); code.push_back (Compiler::Generator::segment5 (16));
} }
void opIntToFloat1 (Compiler::Generator::CodeContainer& code) void opIntToFloat1 (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (17)); code.push_back (Compiler::Generator::segment5 (17));
} }
void opFloatToInt1 (Compiler::Generator::CodeContainer& code) void opFloatToInt1 (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (18)); code.push_back (Compiler::Generator::segment5 (18));
} }
void opSquareRoot (Compiler::Generator::CodeContainer& code) void opSquareRoot (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (19)); code.push_back (Compiler::Generator::segment5 (19));
} }
void opReturn (Compiler::Generator::CodeContainer& code) void opReturn (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (20)); code.push_back (Compiler::Generator::segment5 (20));
} }
void opMessageBox (Compiler::Generator::CodeContainer& code, int buttons) void opMessageBox (Compiler::Generator::CodeContainer& code, int buttons)
{ {
code.push_back (segment3 (0, buttons)); code.push_back (Compiler::Generator::segment3 (0, buttons));
} }
void opFetchLocalShort (Compiler::Generator::CodeContainer& code) void opFetchLocalShort (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (21)); code.push_back (Compiler::Generator::segment5 (21));
} }
void opFetchLocalLong (Compiler::Generator::CodeContainer& code) void opFetchLocalLong (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (22)); code.push_back (Compiler::Generator::segment5 (22));
} }
void opFetchLocalFloat (Compiler::Generator::CodeContainer& code) void opFetchLocalFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (23)); code.push_back (Compiler::Generator::segment5 (23));
} }
void opJumpForward (Compiler::Generator::CodeContainer& code, int offset) void opJumpForward (Compiler::Generator::CodeContainer& code, int offset)
{ {
code.push_back (segment0 (1, offset)); code.push_back (Compiler::Generator::segment0 (1, offset));
} }
void opJumpBackward (Compiler::Generator::CodeContainer& code, int offset) void opJumpBackward (Compiler::Generator::CodeContainer& code, int offset)
{ {
code.push_back (segment0 (2, offset)); code.push_back (Compiler::Generator::segment0 (2, offset));
} }
void opSkipOnZero (Compiler::Generator::CodeContainer& code) void opSkipOnZero (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (24)); code.push_back (Compiler::Generator::segment5 (24));
} }
void opSkipOnNonZero (Compiler::Generator::CodeContainer& code) void opSkipOnNonZero (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (25)); code.push_back (Compiler::Generator::segment5 (25));
} }
void opEqualInt (Compiler::Generator::CodeContainer& code) void opEqualInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (26)); code.push_back (Compiler::Generator::segment5 (26));
} }
void opNonEqualInt (Compiler::Generator::CodeContainer& code) void opNonEqualInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (27)); code.push_back (Compiler::Generator::segment5 (27));
} }
void opLessThanInt (Compiler::Generator::CodeContainer& code) void opLessThanInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (28)); code.push_back (Compiler::Generator::segment5 (28));
} }
void opLessOrEqualInt (Compiler::Generator::CodeContainer& code) void opLessOrEqualInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (29)); code.push_back (Compiler::Generator::segment5 (29));
} }
void opGreaterThanInt (Compiler::Generator::CodeContainer& code) void opGreaterThanInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (30)); code.push_back (Compiler::Generator::segment5 (30));
} }
void opGreaterOrEqualInt (Compiler::Generator::CodeContainer& code) void opGreaterOrEqualInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (31)); code.push_back (Compiler::Generator::segment5 (31));
} }
void opEqualFloat (Compiler::Generator::CodeContainer& code) void opEqualFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (32)); code.push_back (Compiler::Generator::segment5 (32));
} }
void opNonEqualFloat (Compiler::Generator::CodeContainer& code) void opNonEqualFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (33)); code.push_back (Compiler::Generator::segment5 (33));
} }
void opLessThanFloat (Compiler::Generator::CodeContainer& code) void opLessThanFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (34)); code.push_back (Compiler::Generator::segment5 (34));
} }
void opLessOrEqualFloat (Compiler::Generator::CodeContainer& code) void opLessOrEqualFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (35)); code.push_back (Compiler::Generator::segment5 (35));
} }
void opGreaterThanFloat (Compiler::Generator::CodeContainer& code) void opGreaterThanFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (36)); code.push_back (Compiler::Generator::segment5 (36));
} }
void opGreaterOrEqualFloat (Compiler::Generator::CodeContainer& code) void opGreaterOrEqualFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (segment5 (37)); code.push_back (Compiler::Generator::segment5 (37));
} }
} }

@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <cassert>
#include <components/interpreter/types.hpp> #include <components/interpreter/types.hpp>
@ -14,6 +15,44 @@ namespace Compiler
{ {
typedef std::vector<Interpreter::Type_Code> CodeContainer; typedef std::vector<Interpreter::Type_Code> CodeContainer;
inline Interpreter::Type_Code segment0 (unsigned int c, unsigned int arg0)
{
assert (c<64);
return (c<<24) | (arg0 & 0xffffff);
}
inline Interpreter::Type_Code segment1 (unsigned int c, unsigned int arg0,
unsigned int arg1)
{
assert (c<64);
return 0x40000000 | (c<<24) | ((arg0 & 0xfff)<<12) | (arg1 & 0xfff);
}
inline Interpreter::Type_Code segment2 (unsigned int c, unsigned int arg0)
{
assert (c<1024);
return 0x80000000 | (c<<20) | (arg0 & 0xfffff);
}
inline Interpreter::Type_Code segment3 (unsigned int c, unsigned int arg0)
{
assert (c<1024);
return 0xc0000000 | (c<<20) | (arg0 & 0xffff);
}
inline Interpreter::Type_Code segment4 (unsigned int c, unsigned int arg0,
unsigned int arg1)
{
assert (c<1024);
return 0xc4000000 | (c<<16) | ((arg0 & 0xff)<<8) | (arg1 & 0xff);
}
inline Interpreter::Type_Code segment5 (unsigned int c)
{
assert (c<67108864);
return 0xc8000000 | c;
}
void pushInt (CodeContainer& code, Literals& literals, int value); void pushInt (CodeContainer& code, Literals& literals, int value);
void pushFloat (CodeContainer& code, Literals& literals, float value); void pushFloat (CodeContainer& code, Literals& literals, float value);

Loading…
Cancel
Save