#include #include using namespace std; using namespace Latan; // Math Bison/Flex parser declaration int _Math_parse(MathParserState* state); /****************************************************************************** * MathNode implementation * ******************************************************************************/ // constructor ///////////////////////////////////////////////////////////////// MathNode::MathNode(const string& init_str, NodeType::Type init_type) : str(init_str), type(init_type) {} MathNode::MathNode(const std::string& init_str, NodeType::Type init_type,\ const unsigned int narg, ...) : str(init_str), type(init_type), arg(narg) { va_list va; va_start(va,narg); for (unsigned int i=0;i::iterator i; for (i=arg.begin();i!=arg.end();++i) { delete *i; } } // access ////////////////////////////////////////////////////////////////////// const string& MathNode::String(void) const { return str; } NodeType::Type MathNode::Type(void) const { return type; } unsigned int MathNode::NArg(void) const { return static_cast(arg.size()); } // operator //////////////////////////////////////////////////////////////////// const MathNode& MathNode::operator[](const unsigned int i) const { return *arg[i]; } /****************************************************************************** * MathParserState implementation * ******************************************************************************/ // constructor ///////////////////////////////////////////////////////////////// MathParserState::MathParserState(std::istream* pt_stream, std::string* pt_name,\ MathNode** pt_data) : ParserState(pt_stream,pt_name,pt_data) { init_scanner(); } // destructor ////////////////////////////////////////////////////////////////// MathParserState::~MathParserState(void) { destroy_scanner(); } /****************************************************************************** * Instruction set * ******************************************************************************/ #define CODE_WIDTH 6 #define CODE_MOD setw(CODE_WIDTH) << left Instruction::~Instruction(void) {} void Instruction::Print(std::ostream &out) const { out << CODE_MOD << "" << CODE_MOD << "ABSTRACT INSTRUCTION!"; } ostream& Latan::operator<<(ostream& out, const Instruction& ins) { ins.Print(out); return out; } Push::Push(const double& init_cst) : type(Constant), cst(init_cst), vname("") {} Push::Push(const string& init_vname) : type(Variable), cst(0.0), vname(init_vname) {} void Push::operator()(std::stack &dstack, VarTable &vtable) { if (type == Constant) { dstack.push(cst); } else { dstack.push(vtable[vname]); } } void Push::Print(std::ostream &out) const { out << CODE_MOD << "push"; if (type == Constant) { out << CODE_MOD << cst; } else { out << CODE_MOD << vname; } } Pop::Pop(const string& init_vname) : vname(init_vname) {} void Pop::operator()(std::stack &dstack, VarTable &vtable) { vtable[vname] = dstack.top(); dstack.pop(); } void Pop::Print(std::ostream &out) const { out << CODE_MOD << "pop" << CODE_MOD << vname; } #define DEF_OP(name,narg,exp,code_name)\ void name::operator()(stack& dstack, VarTable& vtable __dumb)\ {\ double x[narg];\ for (int i=0;i(0) {} ostream& Latan::operator<<(ostream& out,const VirtualProgram& prog) { for (unsigned int i=0;i"), state(NULL), root(NULL), out(), status(0) {} MathCompiler::MathCompiler(const std::string& code_str) { Init(code_str); } // destructor ////////////////////////////////////////////////////////////////// MathCompiler::~MathCompiler(void) { Reset(); } // public methods ////////////////////////////////////////////////////////////// void MathCompiler::Init(const std::string &code_str) { if (status) { Reset(); } code = new stringstream(code_str); code_name = ""; state = new MathParserState(code,&code_name,&root); status |= Initialised; } const VirtualProgram& MathCompiler::operator()(void) { if (!(status & Parsed)) { Parse(); } if (!(status & Compiled)) { Compile(*root); } return out; } // private methods ///////////////////////////////////////////////////////////// void MathCompiler::Parse(void) { _Math_parse(state); status |= Parsed; status -= status & Compiled; } #define IFOP(name,narg) if ((N.String() == name)&&(N.NArg() == narg)) #define ELIFOP(name,narg) else IFOP(name,narg) #define ELSE else void MathCompiler::Compile(const MathNode& N) { switch (N.Type()) { case NodeType::Constant: out.push_back(new Push(ato(N.String()))); break; case NodeType::Variable: out.push_back(new Push(N.String())); break; case NodeType::Operator: for (unsigned int i=0;i