mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2025-04-10 19:20:44 +01:00
Math interpreter: significant improvement of runtime context handling
This commit is contained in:
parent
0fdd76b19d
commit
bbeaec9ed3
@ -33,21 +33,21 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
cout << "-- Program:" << endl << interpreter << endl;
|
cout << "-- Program:" << endl << interpreter << endl;
|
||||||
cout << "-- Variable table:" << endl;
|
cout << "-- Variable table:" << endl;
|
||||||
for (auto &v: context.vTable)
|
for (auto &v: context.getVariableTable())
|
||||||
{
|
{
|
||||||
cout << "'" << v.first << "': " << v.second << endl;
|
cout << "'" << v.first << "': " << v.second << endl;
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
cout << "-- Function table:" << endl;
|
cout << "-- Function table:" << endl;
|
||||||
for (auto &f: context.fTable)
|
for (auto &f: context.getFunctionTable())
|
||||||
{
|
{
|
||||||
cout << "'" << f.first << "': " << f.second << endl;
|
cout << "'" << f.first << "': " << f.second << endl;
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
interpreter(context);
|
interpreter(context);
|
||||||
if (!context.dStack.empty())
|
if (!context.stack().empty())
|
||||||
{
|
{
|
||||||
cout << "-- Result: " << context.dStack.top() << endl;
|
cout << "-- Result: " << context.stack().top() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -53,12 +53,12 @@ void CompiledDoubleFunction::compile(void) const
|
|||||||
{
|
{
|
||||||
if (!*isCompiled_)
|
if (!*isCompiled_)
|
||||||
{
|
{
|
||||||
interpreter_->compile(*(context_));
|
|
||||||
varAddress_->clear();
|
varAddress_->clear();
|
||||||
for (Index i = 0; i < getNArg(); ++i)
|
for (Index i = 0; i < getNArg(); ++i)
|
||||||
{
|
{
|
||||||
varAddress_->push_back(context_->vTable.at("x_" + strFrom(i)));
|
varAddress_->push_back(context_->addVariable("x_" + strFrom(i)));
|
||||||
}
|
}
|
||||||
|
interpreter_->compile(*(context_));
|
||||||
*isCompiled_ = true;
|
*isCompiled_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,13 +71,13 @@ double CompiledDoubleFunction::operator()(const double *arg) const
|
|||||||
compile();
|
compile();
|
||||||
for (unsigned int i = 0; i < getNArg(); ++i)
|
for (unsigned int i = 0; i < getNArg(); ++i)
|
||||||
{
|
{
|
||||||
context_->vMem[(*varAddress_)[i]] = arg[i];
|
context_->setVariable((*varAddress_)[i], arg[i]);
|
||||||
}
|
}
|
||||||
(*interpreter_)(*context_);
|
(*interpreter_)(*context_);
|
||||||
if (!context_->dStack.empty())
|
if (!context_->stack().empty())
|
||||||
{
|
{
|
||||||
result = context_->dStack.top();
|
result = context_->stack().top();
|
||||||
context_->dStack.pop();
|
context_->stack().pop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -56,17 +56,17 @@ void CompiledDoubleModel::compile(void) const
|
|||||||
{
|
{
|
||||||
if (!*isCompiled_)
|
if (!*isCompiled_)
|
||||||
{
|
{
|
||||||
interpreter_->compile(*(context_));
|
|
||||||
varAddress_->clear();
|
varAddress_->clear();
|
||||||
parAddress_->clear();
|
parAddress_->clear();
|
||||||
for (Index i = 0; i < getNArg(); ++i)
|
for (Index i = 0; i < getNArg(); ++i)
|
||||||
{
|
{
|
||||||
varAddress_->push_back(context_->vTable.at("x_" + strFrom(i)));
|
varAddress_->push_back(context_->addVariable("x_" + strFrom(i)));
|
||||||
}
|
}
|
||||||
for (Index j = 0; j < getNPar(); ++j)
|
for (Index j = 0; j < getNPar(); ++j)
|
||||||
{
|
{
|
||||||
parAddress_->push_back(context_->vTable.at("p_" + strFrom(j)));
|
parAddress_->push_back(context_->addVariable("p_" + strFrom(j)));
|
||||||
}
|
}
|
||||||
|
interpreter_->compile(*(context_));
|
||||||
*isCompiled_ = true;
|
*isCompiled_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,17 +80,17 @@ double CompiledDoubleModel::operator()(const double *arg,
|
|||||||
compile();
|
compile();
|
||||||
for (unsigned int i = 0; i < getNArg(); ++i)
|
for (unsigned int i = 0; i < getNArg(); ++i)
|
||||||
{
|
{
|
||||||
context_->vMem[(*varAddress_)[i]] = arg[i];
|
context_->setVariable((*varAddress_)[i], arg[i]);
|
||||||
}
|
}
|
||||||
for (unsigned int j = 0; j < getNPar(); ++j)
|
for (unsigned int j = 0; j < getNPar(); ++j)
|
||||||
{
|
{
|
||||||
context_->vMem[(*parAddress_)[j]] = par[j];
|
context_->setVariable((*parAddress_)[j], par[j]);
|
||||||
}
|
}
|
||||||
(*interpreter_)(*context_);
|
(*interpreter_)(*context_);
|
||||||
if (!context_->dStack.empty())
|
if (!context_->stack().empty())
|
||||||
{
|
{
|
||||||
result = context_->dStack.top();
|
result = context_->stack().top();
|
||||||
context_->dStack.pop();
|
context_->stack().pop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,6 @@ BEGIN_NAMESPACE
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* compiled double model class *
|
* compiled double model class *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
class CompiledDoubleModel: public DoubleModel
|
class CompiledDoubleModel: public DoubleModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -24,6 +24,193 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Latan;
|
using namespace Latan;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* RunContext implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
unsigned int RunContext::addFunction(const string &name, DoubleFunction *init)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setFunction(name, init);
|
||||||
|
|
||||||
|
return getFunctionAddress(name);
|
||||||
|
}
|
||||||
|
catch (Exceptions::Definition)
|
||||||
|
{
|
||||||
|
unsigned int address = fTable_.size();
|
||||||
|
|
||||||
|
fMem_.push_back(init);
|
||||||
|
fTable_[name] = address;
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int RunContext::addVariable(const string &name, double init)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setVariable(name, init);
|
||||||
|
|
||||||
|
return getVariableAddress(name);
|
||||||
|
}
|
||||||
|
catch (Exceptions::Definition)
|
||||||
|
{
|
||||||
|
unsigned int address = vTable_.size();
|
||||||
|
|
||||||
|
vMem_.push_back(init);
|
||||||
|
vTable_[name] = address;
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DoubleFunction * RunContext::getFunction(const string &name) const
|
||||||
|
{
|
||||||
|
return getFunction(getFunctionAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
DoubleFunction * RunContext::getFunction(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (address >= fTable_.size())
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Range, "function address " + strFrom(address)
|
||||||
|
+ " out of range");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fMem_[address];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int RunContext::getFunctionAddress(const string &name) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return fTable_.at(name);
|
||||||
|
}
|
||||||
|
catch (out_of_range)
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Definition, "undefined function '" + name + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const RunContext::AddressTable & RunContext::getFunctionTable(void) const
|
||||||
|
{
|
||||||
|
return fTable_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int RunContext::getInsIndex(void) const
|
||||||
|
{
|
||||||
|
return insIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
double RunContext::getVariable(const string &name) const
|
||||||
|
{
|
||||||
|
return getVariable(getVariableAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
double RunContext::getVariable(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (address >= vTable_.size())
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Range, "variable address " + strFrom(address)
|
||||||
|
+ " out of range");
|
||||||
|
|
||||||
|
return 0.;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return vMem_[address];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const RunContext::AddressTable & RunContext::getVariableTable(void) const
|
||||||
|
{
|
||||||
|
return vTable_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int RunContext::getVariableAddress(const string &name) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return vTable_.at(name);
|
||||||
|
}
|
||||||
|
catch (out_of_range)
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Definition, "undefined variable '" + name + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunContext::incrementInsIndex(const unsigned int inc)
|
||||||
|
{
|
||||||
|
setInsIndex(getInsIndex() + inc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunContext::setFunction(const string &name, DoubleFunction *f)
|
||||||
|
{
|
||||||
|
|
||||||
|
setFunction(getFunctionAddress(name), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunContext::setFunction(const unsigned int address, DoubleFunction *f)
|
||||||
|
{
|
||||||
|
if (address >= fTable_.size())
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Range, "function address " + strFrom(address)
|
||||||
|
+ " out of range");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fMem_[address] = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunContext::setInsIndex(const unsigned index)
|
||||||
|
{
|
||||||
|
insIndex_ = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunContext::setVariable(const string &name, const double value)
|
||||||
|
{
|
||||||
|
setVariable(getVariableAddress(name), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunContext::setVariable(const unsigned int address, const double value)
|
||||||
|
{
|
||||||
|
if (address >= vTable_.size())
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Range, "variable address " + strFrom(address)
|
||||||
|
+ " out of range");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vMem_[address] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stack<double> & RunContext::stack(void)
|
||||||
|
{
|
||||||
|
return dStack_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset ///////////////////////////////////////////////////////////////////////
|
||||||
|
void RunContext::reset(void)
|
||||||
|
{
|
||||||
|
insIndex_ = 0;
|
||||||
|
while (!dStack_.empty())
|
||||||
|
{
|
||||||
|
dStack_.pop();
|
||||||
|
}
|
||||||
|
vMem_.clear();
|
||||||
|
fMem_.clear();
|
||||||
|
vTable_.clear();
|
||||||
|
fTable_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Instruction set *
|
* Instruction set *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -58,20 +245,13 @@ void Push::operator()(RunContext &context) const
|
|||||||
{
|
{
|
||||||
if (type_ == ArgType::Constant)
|
if (type_ == ArgType::Constant)
|
||||||
{
|
{
|
||||||
context.dStack.push(val_);
|
context.stack().push(val_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
context.stack().push(context.getVariable(address_));
|
||||||
{
|
|
||||||
context.dStack.push(context.vMem[address_]);
|
|
||||||
}
|
|
||||||
catch (out_of_range)
|
|
||||||
{
|
|
||||||
LATAN_ERROR(Range, "unknown variable '" + name_ + "'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
context.insIndex++;
|
context.incrementInsIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push print //////////////////////////////////////////////////////////////////
|
// Push print //////////////////////////////////////////////////////////////////
|
||||||
@ -99,10 +279,10 @@ void Pop::operator()(RunContext &context) const
|
|||||||
{
|
{
|
||||||
if (!name_.empty())
|
if (!name_.empty())
|
||||||
{
|
{
|
||||||
context.vMem[address_] = context.dStack.top();
|
context.setVariable(address_, context.stack().top());
|
||||||
}
|
}
|
||||||
context.dStack.pop();
|
context.stack().pop();
|
||||||
context.insIndex++;
|
context.incrementInsIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop print ///////////////////////////////////////////////////////////////////
|
// Pop print ///////////////////////////////////////////////////////////////////
|
||||||
@ -122,9 +302,9 @@ void Store::operator()(RunContext &context) const
|
|||||||
{
|
{
|
||||||
if (!name_.empty())
|
if (!name_.empty())
|
||||||
{
|
{
|
||||||
context.vMem[address_] = context.dStack.top();
|
context.setVariable(address_, context.stack().top());
|
||||||
}
|
}
|
||||||
context.insIndex++;
|
context.incrementInsIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store print /////////////////////////////////////////////////////////////////
|
// Store print /////////////////////////////////////////////////////////////////
|
||||||
@ -142,15 +322,8 @@ Call::Call(const unsigned int address, const string &name)
|
|||||||
// Call execution //////////////////////////////////////////////////////////////
|
// Call execution //////////////////////////////////////////////////////////////
|
||||||
void Call::operator()(RunContext &context) const
|
void Call::operator()(RunContext &context) const
|
||||||
{
|
{
|
||||||
try
|
context.stack().push((*context.getFunction(address_))(context.stack()));
|
||||||
{
|
context.incrementInsIndex();
|
||||||
context.dStack.push((*context.fMem[address_])(context.dStack));
|
|
||||||
}
|
|
||||||
catch (out_of_range)
|
|
||||||
{
|
|
||||||
LATAN_ERROR(Range, "unknown function '" + name_ + "'");
|
|
||||||
}
|
|
||||||
context.insIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call print //////////////////////////////////////////////////////////////////
|
// Call print //////////////////////////////////////////////////////////////////
|
||||||
@ -166,11 +339,11 @@ void name::operator()(RunContext &context) const\
|
|||||||
double x[nArg];\
|
double x[nArg];\
|
||||||
for (int i = 0; i < nArg; ++i)\
|
for (int i = 0; i < nArg; ++i)\
|
||||||
{\
|
{\
|
||||||
x[nArg-1-i] = context.dStack.top();\
|
x[nArg-1-i] = context.stack().top();\
|
||||||
context.dStack.pop();\
|
context.stack().pop();\
|
||||||
}\
|
}\
|
||||||
context.dStack.push(exp);\
|
context.stack().push(exp);\
|
||||||
context.insIndex++;\
|
context.incrementInsIndex();\
|
||||||
}\
|
}\
|
||||||
void name::print(ostream &out) const\
|
void name::print(ostream &out) const\
|
||||||
{\
|
{\
|
||||||
@ -283,26 +456,19 @@ catch (out_of_range)\
|
|||||||
}\
|
}\
|
||||||
|
|
||||||
// VarNode compile /////////////////////////////////////////////////////////////
|
// VarNode compile /////////////////////////////////////////////////////////////
|
||||||
void VarNode::compile(Program &program, AddressTable &vTable,
|
void VarNode::compile(Program &program, RunContext &context) const
|
||||||
AddressTable &fTable __unused) const
|
|
||||||
{
|
{
|
||||||
unsigned int address;
|
PUSH_INS(program, Push, context.getVariableAddress(getName()), getName());
|
||||||
|
|
||||||
GET_ADDRESS(address, vTable, getName());
|
|
||||||
PUSH_INS(program, Push, address, getName());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CstNode compile /////////////////////////////////////////////////////////////
|
// CstNode compile /////////////////////////////////////////////////////////////
|
||||||
void CstNode::compile(Program &program, AddressTable &nextVAddress __unused,
|
void CstNode::compile(Program &program, RunContext &context __unused) const
|
||||||
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, AddressTable &vTable,
|
void SemicolonNode::compile(Program &program, RunContext &context) const
|
||||||
AddressTable &fTable) const
|
|
||||||
{
|
{
|
||||||
auto &n = *this;
|
auto &n = *this;
|
||||||
|
|
||||||
@ -314,14 +480,13 @@ void SemicolonNode::compile(Program &program, AddressTable &vTable,
|
|||||||
|
|
||||||
if (isAssign||isSemiColumn||isKeyword)
|
if (isAssign||isSemiColumn||isKeyword)
|
||||||
{
|
{
|
||||||
n[i].compile(program, vTable, fTable);
|
n[i].compile(program, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssignNode compile //////////////////////////////////////////////////////////
|
// AssignNode compile //////////////////////////////////////////////////////////
|
||||||
void AssignNode::compile(Program &program, AddressTable &vTable,
|
void AssignNode::compile(Program &program, RunContext &context) const
|
||||||
AddressTable &fTable) const
|
|
||||||
{
|
{
|
||||||
auto &n = *this;
|
auto &n = *this;
|
||||||
|
|
||||||
@ -330,8 +495,8 @@ void AssignNode::compile(Program &program, AddressTable &vTable,
|
|||||||
bool hasSemicolonParent = isDerivedFrom<SemicolonNode>(getParent());
|
bool hasSemicolonParent = isDerivedFrom<SemicolonNode>(getParent());
|
||||||
unsigned int address;
|
unsigned int address;
|
||||||
|
|
||||||
n[1].compile(program, vTable, fTable);
|
n[1].compile(program, context);
|
||||||
GET_ADDRESS(address, vTable, n[0].getName());
|
address = context.addVariable(n[0].getName());
|
||||||
if (hasSemicolonParent)
|
if (hasSemicolonParent)
|
||||||
{
|
{
|
||||||
PUSH_INS(program, Pop, address, n[0].getName());
|
PUSH_INS(program, Pop, address, n[0].getName());
|
||||||
@ -352,14 +517,13 @@ void AssignNode::compile(Program &program, AddressTable &vTable,
|
|||||||
#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, AddressTable &vTable,
|
void MathOpNode::compile(Program &program, RunContext &context) const
|
||||||
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, vTable, fTable);
|
n[i].compile(program, context);
|
||||||
}
|
}
|
||||||
IFNODE("-", 1) PUSH_INS(program, Neg,);
|
IFNODE("-", 1) PUSH_INS(program, Neg,);
|
||||||
ELIFNODE("+", 2) PUSH_INS(program, Add,);
|
ELIFNODE("+", 2) PUSH_INS(program, Add,);
|
||||||
@ -371,27 +535,23 @@ void MathOpNode::compile(Program &program, AddressTable &vTable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FuncNode compile ////////////////////////////////////////////////////////////
|
// FuncNode compile ////////////////////////////////////////////////////////////
|
||||||
void FuncNode::compile(Program &program, AddressTable &vTable,
|
void FuncNode::compile(Program &program, RunContext &context) const
|
||||||
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, vTable, fTable);
|
n[i].compile(program, context);
|
||||||
}
|
}
|
||||||
GET_ADDRESS(address, fTable, getName());
|
PUSH_INS(program, Call, context.addFunction(getName()), getName());
|
||||||
PUSH_INS(program, Call, address, getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReturnNode compile ////////////////////////////////////////////////////////////
|
// ReturnNode compile ////////////////////////////////////////////////////////////
|
||||||
void ReturnNode::compile(Program &program, AddressTable &vTable,
|
void ReturnNode::compile(Program &program, RunContext &context) const
|
||||||
AddressTable &fTable) const
|
|
||||||
{
|
{
|
||||||
auto &n = *this;
|
auto &n = *this;
|
||||||
|
|
||||||
n[0].compile(program, vTable, fTable);
|
n[0].compile(program, context);
|
||||||
program.push_back(nullptr);
|
program.push_back(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,9 +633,9 @@ void MathInterpreter::parse(void)
|
|||||||
#define ADD_FUNC(context, func)\
|
#define ADD_FUNC(context, func)\
|
||||||
try\
|
try\
|
||||||
{\
|
{\
|
||||||
(context).fMem[(context).fTable.at(#func)] = &STDMATH_NAMESPACE::func;\
|
(context).setFunction(#func, &STDMATH_NAMESPACE::func);\
|
||||||
}\
|
}\
|
||||||
catch (out_of_range)\
|
catch (Exceptions::Definition)\
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#define ADD_STDMATH_FUNCS(context)\
|
#define ADD_STDMATH_FUNCS(context)\
|
||||||
@ -534,9 +694,7 @@ void MathInterpreter::compile(RunContext &context)
|
|||||||
{
|
{
|
||||||
if (root_)
|
if (root_)
|
||||||
{
|
{
|
||||||
context.vTable.clear();
|
root_->compile(program_, context);
|
||||||
context.fTable.clear();
|
|
||||||
root_->compile(program_, context.vTable, context.fTable);
|
|
||||||
for (unsigned int i = 0; i < program_.size(); ++i)
|
for (unsigned int i = 0; i < program_.size(); ++i)
|
||||||
{
|
{
|
||||||
if (!program_[i])
|
if (!program_[i])
|
||||||
@ -547,8 +705,6 @@ void MathInterpreter::compile(RunContext &context)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context.vMem.resize(context.vTable.size());
|
|
||||||
context.fMem.resize(context.fTable.size());
|
|
||||||
ADD_STDMATH_FUNCS(context);
|
ADD_STDMATH_FUNCS(context);
|
||||||
}
|
}
|
||||||
if (!root_||!gotReturn)
|
if (!root_||!gotReturn)
|
||||||
@ -573,10 +729,10 @@ void MathInterpreter::operator()(RunContext &context)
|
|||||||
|
|
||||||
void MathInterpreter::execute(RunContext &context) const
|
void MathInterpreter::execute(RunContext &context) const
|
||||||
{
|
{
|
||||||
context.insIndex = 0;
|
context.setInsIndex(0);
|
||||||
while (context.insIndex != program_.size())
|
while (context.getInsIndex() != program_.size())
|
||||||
{
|
{
|
||||||
(*(program_[context.insIndex]))(context);
|
(*(program_[context.getInsIndex()]))(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,19 +34,55 @@
|
|||||||
BEGIN_NAMESPACE
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Instruction classes *
|
* Class for runtime context *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
typedef std::map<std::string, unsigned int> AddressTable;
|
class RunContext
|
||||||
|
|
||||||
struct RunContext
|
|
||||||
{
|
{
|
||||||
unsigned int insIndex;
|
public:
|
||||||
std::stack<double> dStack;
|
typedef std::map<std::string, unsigned int> AddressTable;
|
||||||
std::vector<double> vMem;
|
public:
|
||||||
std::vector<DoubleFunction *> fMem;
|
// constructor
|
||||||
AddressTable vTable, fTable;
|
RunContext(void) = default;
|
||||||
|
// destructor
|
||||||
|
~RunContext(void) = default;
|
||||||
|
// access
|
||||||
|
unsigned int addFunction(const std::string &name,
|
||||||
|
DoubleFunction *init = nullptr);
|
||||||
|
unsigned int addVariable(const std::string &name,
|
||||||
|
const double init = 0.);
|
||||||
|
DoubleFunction * getFunction(const std::string &name) const;
|
||||||
|
DoubleFunction * getFunction(const unsigned int address) const;
|
||||||
|
unsigned int getFunctionAddress(const std::string &name) const;
|
||||||
|
const AddressTable & getFunctionTable(void) const;
|
||||||
|
unsigned int getInsIndex(void) const;
|
||||||
|
double getVariable(const std::string &name) const;
|
||||||
|
double getVariable(const unsigned int address) const;
|
||||||
|
unsigned int getVariableAddress(const std::string &name) const;
|
||||||
|
const AddressTable & getVariableTable(void) const;
|
||||||
|
void incrementInsIndex(const unsigned int inc = 1);
|
||||||
|
void setFunction(const std::string &name,
|
||||||
|
DoubleFunction *f);
|
||||||
|
void setFunction(const unsigned int address,
|
||||||
|
DoubleFunction *f);
|
||||||
|
void setInsIndex(const unsigned index);
|
||||||
|
void setVariable(const std::string &name,
|
||||||
|
const double value);
|
||||||
|
void setVariable(const unsigned int address,
|
||||||
|
const double value);
|
||||||
|
std::stack<double> & stack(void);
|
||||||
|
// reset
|
||||||
|
void reset(void);
|
||||||
|
private:
|
||||||
|
unsigned int insIndex_;
|
||||||
|
std::stack<double> dStack_;
|
||||||
|
std::vector<double> vMem_;
|
||||||
|
std::vector<DoubleFunction *> fMem_;
|
||||||
|
AddressTable vTable_, fTable_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Instruction classes *
|
||||||
|
******************************************************************************/
|
||||||
// Abstract base
|
// Abstract base
|
||||||
class Instruction
|
class Instruction
|
||||||
{
|
{
|
||||||
@ -171,8 +207,7 @@ public:
|
|||||||
// operator
|
// operator
|
||||||
const ExprNode &operator[](const Index i) const;
|
const ExprNode &operator[](const Index i) const;
|
||||||
// compile
|
// compile
|
||||||
virtual void compile(Program &program, AddressTable &vTable,
|
virtual void compile(Program &program, RunContext &context) const = 0;
|
||||||
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_;
|
||||||
@ -186,8 +221,7 @@ class name: public base\
|
|||||||
{\
|
{\
|
||||||
public:\
|
public:\
|
||||||
using base::base;\
|
using base::base;\
|
||||||
virtual void compile(Program &program, AddressTable &vTable,\
|
virtual void compile(Program &program, RunContext &context) const;\
|
||||||
AddressTable &fTable) const;\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_NODE(ExprNode, VarNode);
|
DECL_NODE(ExprNode, VarNode);
|
||||||
@ -201,8 +235,7 @@ class KeywordNode: public ExprNode
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using ExprNode::ExprNode;
|
using ExprNode::ExprNode;
|
||||||
virtual void compile(Program &program, AddressTable &vTable,
|
virtual void compile(Program &program, RunContext &context) const = 0;
|
||||||
AddressTable &fTable) const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DECL_NODE(KeywordNode, ReturnNode);
|
DECL_NODE(KeywordNode, ReturnNode);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user