1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2025-04-10 19:20:44 +01:00

significant optimisation of the math interpreter using integer address tables for variables and functions

This commit is contained in:
Antonin Portelli 2014-04-08 19:48:52 +01:00
parent b0f6c30445
commit 47e159e041
9 changed files with 239 additions and 144 deletions

View File

@ -21,7 +21,7 @@ int main(int argc, char* argv[])
RunContext context; RunContext context;
cout << "-- Source code:" << endl << source << endl << endl; cout << "-- Source code:" << endl << source << endl << endl;
interpreter.compile(); interpreter.compile(context);
cout << "-- Abstract Syntax Tree:" << endl; cout << "-- Abstract Syntax Tree:" << endl;
if (interpreter.getAST()) if (interpreter.getAST())
{ {
@ -32,7 +32,18 @@ int main(int argc, char* argv[])
cout << "<null>" << endl << endl; cout << "<null>" << endl << endl;
} }
cout << "-- Program:" << endl << interpreter << endl; cout << "-- Program:" << endl << interpreter << endl;
StdMath::addStdMathFunc(context.fTable); cout << "-- Variable table:" << endl;
for (auto &v: context.vTable)
{
cout << "'" << v.first << "': " << v.second << endl;
}
cout << endl;
cout << "-- Function table:" << endl;
for (auto &f: context.fTable)
{
cout << "'" << f.first << "': " << f.second << endl;
}
cout << endl;
interpreter(context); interpreter(context);
if (!context.dStack.empty()) if (!context.dStack.empty())
{ {

View File

@ -44,7 +44,23 @@ void CompiledDoubleFunction::setCode(const string &code)
{ {
interpreter_.reset(new MathInterpreter(code)); interpreter_.reset(new MathInterpreter(code));
context_.reset(new RunContext); context_.reset(new RunContext);
StdMath::addStdMathFunc(context_->fTable); varAddress_.reset(new std::vector<unsigned int>);
isCompiled_.reset(new bool(false));
}
// compile /////////////////////////////////////////////////////////////////////
void CompiledDoubleFunction::compile(void) const
{
if (!*isCompiled_)
{
interpreter_->compile(*(context_));
varAddress_->clear();
for (Index i = 0; i < getNArg(); ++i)
{
varAddress_->push_back(context_->vTable.at("x_" + strFrom(i)));
}
*isCompiled_ = true;
}
} }
// function call /////////////////////////////////////////////////////////////// // function call ///////////////////////////////////////////////////////////////
@ -52,9 +68,10 @@ double CompiledDoubleFunction::operator()(const double *arg) const
{ {
double result; double result;
for (Index i = 0; i < getNArg(); ++i) compile();
for (unsigned int i = 0; i < getNArg(); ++i)
{ {
context_->vTable["x_" + strFrom(i)] = arg[i]; context_->vMem[(*varAddress_)[i]] = arg[i];
} }
(*interpreter_)(*context_); (*interpreter_)(*context_);
if (!context_->dStack.empty()) if (!context_->dStack.empty())
@ -74,7 +91,7 @@ double CompiledDoubleFunction::operator()(const double *arg) const
// IO ////////////////////////////////////////////////////////////////////////// // IO //////////////////////////////////////////////////////////////////////////
ostream & Latan::operator<<(ostream &out, CompiledDoubleFunction &f) ostream & Latan::operator<<(ostream &out, CompiledDoubleFunction &f)
{ {
f.interpreter_->compile(); f.compile();
out << *(f.interpreter_); out << *(f.interpreter_);
return out; return out;

View File

@ -46,8 +46,13 @@ public:
friend std::ostream & operator<<(std::ostream &out, friend std::ostream & operator<<(std::ostream &out,
CompiledDoubleFunction &f); CompiledDoubleFunction &f);
private: private:
std::shared_ptr<MathInterpreter> interpreter_; // compile
std::shared_ptr<RunContext> context_; void compile(void) const;
private:
std::shared_ptr<MathInterpreter> interpreter_;
std::shared_ptr<RunContext> context_;
std::shared_ptr<std::vector<unsigned int>> varAddress_;
std::shared_ptr<bool> isCompiled_;
}; };
std::ostream & operator<<(std::ostream &out, CompiledDoubleFunction &f); std::ostream & operator<<(std::ostream &out, CompiledDoubleFunction &f);

View File

@ -46,7 +46,29 @@ void CompiledDoubleModel::setCode(const std::string &code)
{ {
interpreter_.reset(new MathInterpreter(code)); interpreter_.reset(new MathInterpreter(code));
context_.reset(new RunContext); context_.reset(new RunContext);
StdMath::addStdMathFunc(context_->fTable); varAddress_.reset(new std::vector<unsigned int>);
parAddress_.reset(new std::vector<unsigned int>);
isCompiled_.reset(new bool(false));
}
// compile /////////////////////////////////////////////////////////////////////
void CompiledDoubleModel::compile(void) const
{
if (!*isCompiled_)
{
interpreter_->compile(*(context_));
varAddress_->clear();
parAddress_->clear();
for (Index i = 0; i < getNArg(); ++i)
{
varAddress_->push_back(context_->vTable.at("x_" + strFrom(i)));
}
for (Index j = 0; j < getNPar(); ++j)
{
parAddress_->push_back(context_->vTable.at("p_" + strFrom(j)));
}
*isCompiled_ = true;
}
} }
// function call /////////////////////////////////////////////////////////////// // function call ///////////////////////////////////////////////////////////////
@ -55,13 +77,14 @@ double CompiledDoubleModel::operator()(const double *arg,
{ {
double result; double result;
for (Index i = 0; i < getNArg(); ++i) compile();
for (unsigned int i = 0; i < getNArg(); ++i)
{ {
context_->vTable["x_" + strFrom(i)] = arg[i]; context_->vMem[(*varAddress_)[i]] = arg[i];
} }
for (Index j = 0; j < getNPar(); ++j) for (unsigned int j = 0; j < getNPar(); ++j)
{ {
context_->vTable["p_" + strFrom(j)] = par[j]; context_->vMem[(*parAddress_)[j]] = par[j];
} }
(*interpreter_)(*context_); (*interpreter_)(*context_);
if (!context_->dStack.empty()) if (!context_->dStack.empty())
@ -81,7 +104,7 @@ double CompiledDoubleModel::operator()(const double *arg,
// IO ////////////////////////////////////////////////////////////////////////// // IO //////////////////////////////////////////////////////////////////////////
ostream & Latan::operator<<(std::ostream &out, CompiledDoubleModel &m) ostream & Latan::operator<<(std::ostream &out, CompiledDoubleModel &m)
{ {
m.interpreter_->compile(); m.compile();
out << *(m.interpreter_); out << *(m.interpreter_);
return out; return out;

View File

@ -48,8 +48,13 @@ public:
friend std::ostream & operator<<(std::ostream &out, friend std::ostream & operator<<(std::ostream &out,
CompiledDoubleModel &f); CompiledDoubleModel &f);
private: private:
std::shared_ptr<MathInterpreter> interpreter_; // compile
std::shared_ptr<RunContext> context_; void compile(void) const;
private:
std::shared_ptr<MathInterpreter> interpreter_;
std::shared_ptr<RunContext> context_;
std::shared_ptr<std::vector<unsigned int>> varAddress_, parAddress_;
std::shared_ptr<bool> isCompiled_;
}; };
std::ostream & operator<<(std::ostream &out, CompiledDoubleModel &f); std::ostream & operator<<(std::ostream &out, CompiledDoubleModel &f);

View File

@ -90,63 +90,3 @@ DEF_STD_FUNC_2ARG(fmin)
// Absolute value // Absolute value
DEF_STD_FUNC_1ARG(fabs) DEF_STD_FUNC_1ARG(fabs)
#define ADD_FUNC(func) fTable[#func] = &STDMATH_NAMESPACE::func
void STDMATH_NAMESPACE::addStdMathFunc(FunctionTable &fTable)
{
// Trigonometric functions
ADD_FUNC(cos);
ADD_FUNC(sin);
ADD_FUNC(tan);
ADD_FUNC(acos);
ADD_FUNC(asin);
ADD_FUNC(atan);
ADD_FUNC(atan2);
// Hyperbolic functions
ADD_FUNC(cosh);
ADD_FUNC(sinh);
ADD_FUNC(tanh);
ADD_FUNC(acosh);
ADD_FUNC(asinh);
ADD_FUNC(atanh);
// Exponential and logarithmic functions
ADD_FUNC(exp);
ADD_FUNC(log);
ADD_FUNC(log10);
ADD_FUNC(exp2);
ADD_FUNC(expm1);
ADD_FUNC(log1p);
ADD_FUNC(log2);
// Power functions
ADD_FUNC(pow);
ADD_FUNC(sqrt);
ADD_FUNC(cbrt);
ADD_FUNC(hypot);
// Error and gamma functions
ADD_FUNC(erf);
ADD_FUNC(erfc);
ADD_FUNC(tgamma);
ADD_FUNC(lgamma);
// Rounding and remainder functions
ADD_FUNC(ceil);
ADD_FUNC(floor);
ADD_FUNC(fmod);
ADD_FUNC(trunc);
ADD_FUNC(round);
ADD_FUNC(rint);
ADD_FUNC(nearbyint);
ADD_FUNC(remainder);
// Minimum, maximum, difference functions
ADD_FUNC(fdim);
ADD_FUNC(fmax);
ADD_FUNC(fmin);
// Absolute value
ADD_FUNC(fabs);
}

View File

@ -95,9 +95,6 @@ DECL_STD_FUNC(fabs)
namespace STDMATH_NAMESPACE namespace STDMATH_NAMESPACE
{ {
// Add standard math functions to a table for the math compiler
void addStdMathFunc(FunctionTable &fTable);
// Constants // Constants
const double pi = 3.1415926535897932384626433832795028841970; const double pi = 3.1415926535897932384626433832795028841970;
} }

View File

@ -19,6 +19,7 @@
#include <LatAnalyze/MathInterpreter.hpp> #include <LatAnalyze/MathInterpreter.hpp>
#include <LatAnalyze/includes.hpp> #include <LatAnalyze/includes.hpp>
#include <LatAnalyze/Math.hpp>
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
@ -41,12 +42,14 @@ ostream &Latan::operator<<(ostream& out, const Instruction& ins)
Push::Push(const double val) Push::Push(const double val)
: type_(ArgType::Constant) : type_(ArgType::Constant)
, val_(val) , val_(val)
, address_(0)
, name_("") , name_("")
{} {}
Push::Push(const string &name) Push::Push(const unsigned int address, const string &name)
: type_(ArgType::Variable) : type_(ArgType::Variable)
, val_(0.0) , val_(0.0)
, address_(address)
, name_(name) , name_(name)
{} {}
@ -61,7 +64,7 @@ void Push::operator()(RunContext &context) const
{ {
try try
{ {
context.dStack.push(context.vTable.at(name_)); context.dStack.push(context.vMem[address_]);
} }
catch (out_of_range) catch (out_of_range)
{ {
@ -81,13 +84,14 @@ void Push::print(ostream &out) const
} }
else else
{ {
out << CODE_MOD << name_; out << CODE_MOD << name_ << " @v" << address_;
} }
} }
// Pop constructor ///////////////////////////////////////////////////////////// // Pop constructor /////////////////////////////////////////////////////////////
Pop::Pop(const string &name) Pop::Pop(const unsigned int address, const string &name)
: name_(name) : address_(address)
, name_(name)
{} {}
// Pop execution /////////////////////////////////////////////////////////////// // Pop execution ///////////////////////////////////////////////////////////////
@ -95,7 +99,7 @@ void Pop::operator()(RunContext &context) const
{ {
if (!name_.empty()) if (!name_.empty())
{ {
context.vTable[name_] = context.dStack.top(); context.vMem[address_] = context.dStack.top();
} }
context.dStack.pop(); context.dStack.pop();
context.insIndex++; context.insIndex++;
@ -104,12 +108,13 @@ void Pop::operator()(RunContext &context) const
// Pop print /////////////////////////////////////////////////////////////////// // Pop print ///////////////////////////////////////////////////////////////////
void Pop::print(ostream &out) const void Pop::print(ostream &out) const
{ {
out << CODE_MOD << "pop" << CODE_MOD << name_; out << CODE_MOD << "pop" << CODE_MOD << name_ << " @v" << address_;
} }
// Store constructor /////////////////////////////////////////////////////////// // Store constructor ///////////////////////////////////////////////////////////
Store::Store(const string &name) Store::Store(const unsigned int address, const string &name)
: name_(name) : address_(address)
, name_(name)
{} {}
// Store execution ///////////////////////////////////////////////////////////// // Store execution /////////////////////////////////////////////////////////////
@ -117,7 +122,7 @@ void Store::operator()(RunContext &context) const
{ {
if (!name_.empty()) if (!name_.empty())
{ {
context.vTable[name_] = context.dStack.top(); context.vMem[address_] = context.dStack.top();
} }
context.insIndex++; context.insIndex++;
} }
@ -125,12 +130,13 @@ void Store::operator()(RunContext &context) const
// Store print ///////////////////////////////////////////////////////////////// // Store print /////////////////////////////////////////////////////////////////
void Store::print(ostream &out) const void Store::print(ostream &out) const
{ {
out << CODE_MOD << "store" << CODE_MOD << name_; out << CODE_MOD << "store" << CODE_MOD << name_ << " @v" << address_;
} }
// Call constructor //////////////////////////////////////////////////////////// // Call constructor ////////////////////////////////////////////////////////////
Call::Call(const string &name) Call::Call(const unsigned int address, const string &name)
: name_(name) : address_(address)
, name_(name)
{} {}
// Call execution ////////////////////////////////////////////////////////////// // Call execution //////////////////////////////////////////////////////////////
@ -138,7 +144,7 @@ void Call::operator()(RunContext &context) const
{ {
try try
{ {
context.dStack.push((*context.fTable.at(name_))(context.dStack)); context.dStack.push((*context.fMem[address_])(context.dStack));
} }
catch (out_of_range) catch (out_of_range)
{ {
@ -150,7 +156,7 @@ void Call::operator()(RunContext &context) const
// Call print ////////////////////////////////////////////////////////////////// // Call print //////////////////////////////////////////////////////////////////
void Call::print(ostream &out) const void Call::print(ostream &out) const
{ {
out << CODE_MOD << "call" << CODE_MOD << name_; out << CODE_MOD << "call" << CODE_MOD << name_ << " @f" << address_;
} }
// Math operations ///////////////////////////////////////////////////////////// // Math operations /////////////////////////////////////////////////////////////
@ -263,23 +269,40 @@ ostream &Latan::operator<<(ostream &out, const ExprNode &n)
return out; return out;
} }
#define PUSH_INS(program, type, ...) \ #define PUSH_INS(program, type, ...)\
program.push_back(unique_ptr<type>(new type(__VA_ARGS__))) program.push_back(unique_ptr<type>(new type(__VA_ARGS__)))
#define GET_ADDRESS(address, table, name)\
try\
{\
address = (table).at(name);\
}\
catch (out_of_range)\
{\
address = static_cast<unsigned int>((table).size());\
(table)[(name)] = address;\
}\
// VarNode compile ///////////////////////////////////////////////////////////// // VarNode compile /////////////////////////////////////////////////////////////
void VarNode::compile(Program &program) const void VarNode::compile(Program &program, AddressTable &vTable,
AddressTable &fTable __unused) const
{ {
PUSH_INS(program, Push, getName()); unsigned int address;
GET_ADDRESS(address, vTable, getName());
PUSH_INS(program, Push, address, getName());
} }
// CstNode compile ///////////////////////////////////////////////////////////// // CstNode compile /////////////////////////////////////////////////////////////
void CstNode::compile(Program &program) const void CstNode::compile(Program &program, AddressTable &nextVAddress __unused,
AddressTable &nextFAddress __unused) const
{ {
PUSH_INS(program, Push, strTo<double>(getName())); PUSH_INS(program, Push, strTo<double>(getName()));
} }
// SemicolonNode compile /////////////////////////////////////////////////////// // SemicolonNode compile ///////////////////////////////////////////////////////
void SemicolonNode::compile(Program &program) const void SemicolonNode::compile(Program &program, AddressTable &vTable,
AddressTable &fTable) const
{ {
auto &n = *this; auto &n = *this;
@ -291,28 +314,31 @@ void SemicolonNode::compile(Program &program) const
if (isAssign||isSemiColumn||isKeyword) if (isAssign||isSemiColumn||isKeyword)
{ {
n[i].compile(program); n[i].compile(program, vTable, fTable);
} }
} }
} }
// AssignNode compile ////////////////////////////////////////////////////////// // AssignNode compile //////////////////////////////////////////////////////////
void AssignNode::compile(Program &program) const void AssignNode::compile(Program &program, AddressTable &vTable,
AddressTable &fTable) const
{ {
auto &n = *this; auto &n = *this;
if (isDerivedFrom<VarNode>(&n[0])) if (isDerivedFrom<VarNode>(&n[0]))
{ {
bool hasSemicolonParent = isDerivedFrom<SemicolonNode>(getParent()); bool hasSemicolonParent = isDerivedFrom<SemicolonNode>(getParent());
unsigned int address;
n[1].compile(program); n[1].compile(program, vTable, fTable);
GET_ADDRESS(address, vTable, n[0].getName());
if (hasSemicolonParent) if (hasSemicolonParent)
{ {
PUSH_INS(program, Pop, n[0].getName()); PUSH_INS(program, Pop, address, n[0].getName());
} }
else else
{ {
PUSH_INS(program, Store, n[0].getName()); PUSH_INS(program, Store, address, n[0].getName());
} }
} }
else else
@ -326,13 +352,14 @@ void AssignNode::compile(Program &program) const
#define ELIFNODE(name, nArg) else IFNODE(name, nArg) #define ELIFNODE(name, nArg) else IFNODE(name, nArg)
#define ELSE else #define ELSE else
void MathOpNode::compile(Program &program) const void MathOpNode::compile(Program &program, AddressTable &vTable,
AddressTable &fTable) const
{ {
auto &n = *this; auto &n = *this;
for (Index i = 0; i < n.getNArg(); ++i) for (Index i = 0; i < n.getNArg(); ++i)
{ {
n[i].compile(program); n[i].compile(program, vTable, fTable);
} }
IFNODE("-", 1) PUSH_INS(program, Neg,); IFNODE("-", 1) PUSH_INS(program, Neg,);
ELIFNODE("+", 2) PUSH_INS(program, Add,); ELIFNODE("+", 2) PUSH_INS(program, Add,);
@ -344,23 +371,27 @@ void MathOpNode::compile(Program &program) const
} }
// FuncNode compile //////////////////////////////////////////////////////////// // FuncNode compile ////////////////////////////////////////////////////////////
void FuncNode::compile(Program &program) const void FuncNode::compile(Program &program, AddressTable &vTable,
AddressTable &fTable) const
{ {
auto &n = *this; auto &n = *this;
unsigned int address;
for (Index i = 0; i < n.getNArg(); ++i) for (Index i = 0; i < n.getNArg(); ++i)
{ {
n[i].compile(program); n[i].compile(program, vTable, fTable);
} }
PUSH_INS(program, Call, getName()); GET_ADDRESS(address, fTable, getName());
PUSH_INS(program, Call, address, getName());
} }
// ReturnNode compile //////////////////////////////////////////////////////////// // ReturnNode compile ////////////////////////////////////////////////////////////
void ReturnNode::compile(Program &program) const void ReturnNode::compile(Program &program, AddressTable &vTable,
AddressTable &fTable) const
{ {
auto &n = *this; auto &n = *this;
n[0].compile(program); n[0].compile(program, vTable, fTable);
program.push_back(nullptr); program.push_back(nullptr);
} }
@ -439,7 +470,57 @@ void MathInterpreter::parse(void)
} }
// interpreter ///////////////////////////////////////////////////////////////// // interpreter /////////////////////////////////////////////////////////////////
void MathInterpreter::compile(void) #define ADD_FUNC(context, func)\
try\
{\
(context).fMem[(context).fTable.at(#func)] = &STDMATH_NAMESPACE::func;\
}\
catch (out_of_range)\
{}
#define ADD_STDMATH_FUNCS(context)\
ADD_FUNC(context, cos);\
ADD_FUNC(context, sin);\
ADD_FUNC(context, tan);\
ADD_FUNC(context, acos);\
ADD_FUNC(context, asin);\
ADD_FUNC(context, atan);\
ADD_FUNC(context, atan2);\
ADD_FUNC(context, cosh);\
ADD_FUNC(context, sinh);\
ADD_FUNC(context, tanh);\
ADD_FUNC(context, acosh);\
ADD_FUNC(context, asinh);\
ADD_FUNC(context, atanh);\
ADD_FUNC(context, exp);\
ADD_FUNC(context, log);\
ADD_FUNC(context, log10);\
ADD_FUNC(context, exp2);\
ADD_FUNC(context, expm1);\
ADD_FUNC(context, log1p);\
ADD_FUNC(context, log2);\
ADD_FUNC(context, pow);\
ADD_FUNC(context, sqrt);\
ADD_FUNC(context, cbrt);\
ADD_FUNC(context, hypot);\
ADD_FUNC(context, erf);\
ADD_FUNC(context, erfc);\
ADD_FUNC(context, tgamma);\
ADD_FUNC(context, lgamma);\
ADD_FUNC(context, ceil);\
ADD_FUNC(context, floor);\
ADD_FUNC(context, fmod);\
ADD_FUNC(context, trunc);\
ADD_FUNC(context, round);\
ADD_FUNC(context, rint);\
ADD_FUNC(context, nearbyint);\
ADD_FUNC(context, remainder);\
ADD_FUNC(context, fdim);\
ADD_FUNC(context, fmax);\
ADD_FUNC(context, fmin);\
ADD_FUNC(context, fabs);
void MathInterpreter::compile(RunContext &context)
{ {
bool gotReturn = false; bool gotReturn = false;
@ -449,34 +530,43 @@ void MathInterpreter::compile(void)
status_ |= Status::parsed; status_ |= Status::parsed;
status_ -= status_ & Status::compiled; status_ -= status_ & Status::compiled;
} }
if (root_) if (!(status_ & Status::compiled))
{ {
root_->compile(program_); if (root_)
for (unsigned int i = 0; i < program_.size(); ++i)
{ {
if (!program_[i]) context.vTable.clear();
context.fTable.clear();
root_->compile(program_, context.vTable, context.fTable);
for (unsigned int i = 0; i < program_.size(); ++i)
{ {
gotReturn = true; if (!program_[i])
program_.resize(i); {
program_.shrink_to_fit(); gotReturn = true;
break; program_.resize(i);
program_.shrink_to_fit();
break;
}
} }
context.vMem.resize(context.vTable.size());
context.fMem.resize(context.fTable.size());
ADD_STDMATH_FUNCS(context);
} }
if (!root_||!gotReturn)
{
LATAN_ERROR(Syntax, "expected 'return' in program '" + codeName_
+ "'");
}
status_ |= Status::compiled;
} }
if (!root_||!gotReturn)
{
LATAN_ERROR(Syntax, "expected 'return' in program '" + codeName_ + "'");
}
status_ |= Status::compiled;
} }
// execution /////////////////////////////////////////////////////////////////// // execution ///////////////////////////////////////////////////////////////////
void MathInterpreter::operator()(RunContext &context) void MathInterpreter::operator()(RunContext &context)
{ {
if (!(status_ & Status::compiled)) if (!(status_ & Status::compiled))
{ {
compile(); compile(context);
} }
execute(context); execute(context);
} }

View File

@ -36,15 +36,15 @@ BEGIN_NAMESPACE
/****************************************************************************** /******************************************************************************
* Instruction classes * * Instruction classes *
******************************************************************************/ ******************************************************************************/
typedef std::map<std::string, double> VarTable; typedef std::map<std::string, unsigned int> AddressTable;
typedef std::map<std::string, DoubleFunction *> FunctionTable;
struct RunContext struct RunContext
{ {
unsigned int insIndex; unsigned int insIndex;
std::stack<double> dStack; std::stack<double> dStack;
VarTable vTable; std::vector<double> vMem;
FunctionTable fTable; std::vector<DoubleFunction *> fMem;
AddressTable vTable, fTable;
}; };
// Abstract base // Abstract base
@ -77,15 +77,16 @@ private:
public: public:
//constructors //constructors
explicit Push(const double val); explicit Push(const double val);
explicit Push(const std::string &name); explicit Push(const unsigned int address, const std::string &name);
// instruction execution // instruction execution
virtual void operator()(RunContext &context) const; virtual void operator()(RunContext &context) const;
private: private:
virtual void print(std::ostream& out) const; virtual void print(std::ostream& out) const;
private: private:
ArgType type_; ArgType type_;
double val_; double val_;
std::string name_; unsigned int address_;
std::string name_;
}; };
// Pop // Pop
@ -93,12 +94,13 @@ class Pop: public Instruction
{ {
public: public:
//constructor //constructor
explicit Pop(const std::string &name); explicit Pop(const unsigned int address, const std::string &name);
// instruction execution // instruction execution
virtual void operator()(RunContext &context) const; virtual void operator()(RunContext &context) const;
private: private:
virtual void print(std::ostream& out) const; virtual void print(std::ostream& out) const;
private: private:
unsigned int address_;
std::string name_; std::string name_;
}; };
@ -107,12 +109,13 @@ class Store: public Instruction
{ {
public: public:
//constructor //constructor
explicit Store(const std::string &name); explicit Store(const unsigned int address, const std::string &name);
// instruction execution // instruction execution
virtual void operator()(RunContext &context) const; virtual void operator()(RunContext &context) const;
private: private:
virtual void print(std::ostream& out) const; virtual void print(std::ostream& out) const;
private: private:
unsigned int address_;
std::string name_; std::string name_;
}; };
@ -121,12 +124,13 @@ class Call: public Instruction
{ {
public: public:
//constructor //constructor
explicit Call(const std::string &name); explicit Call(const unsigned int address, const std::string &name);
// instruction execution // instruction execution
virtual void operator()(RunContext &context) const; virtual void operator()(RunContext &context) const;
private: private:
virtual void print(std::ostream& out) const; virtual void print(std::ostream& out) const;
private: private:
unsigned int address_;
std::string name_; std::string name_;
}; };
@ -167,7 +171,8 @@ public:
// operator // operator
const ExprNode &operator[](const Index i) const; const ExprNode &operator[](const Index i) const;
// compile // compile
virtual void compile(Program &program) const = 0; virtual void compile(Program &program, AddressTable &vTable,
AddressTable &fTable) const = 0;
private: private:
std::string name_; std::string name_;
std::vector<std::unique_ptr<ExprNode>> arg_; std::vector<std::unique_ptr<ExprNode>> arg_;
@ -181,7 +186,8 @@ class name: public base\
{\ {\
public:\ public:\
using base::base;\ using base::base;\
virtual void compile(Program &program) const;\ virtual void compile(Program &program, AddressTable &vTable,\
AddressTable &fTable) const;\
} }
DECL_NODE(ExprNode, VarNode); DECL_NODE(ExprNode, VarNode);
@ -195,7 +201,8 @@ class KeywordNode: public ExprNode
{ {
public: public:
using ExprNode::ExprNode; using ExprNode::ExprNode;
virtual void compile(Program &program) const = 0; virtual void compile(Program &program, AddressTable &vTable,
AddressTable &fTable) const = 0;
}; };
DECL_NODE(KeywordNode, ReturnNode); DECL_NODE(KeywordNode, ReturnNode);
@ -245,7 +252,7 @@ public:
// initialization // initialization
void setCode(const std::string &code); void setCode(const std::string &code);
// interpreter // interpreter
void compile(void); void compile(RunContext &context);
// execution // execution
void operator()(RunContext &context); void operator()(RunContext &context);
// IO // IO