diff --git a/tester.cpp b/tester.cpp index dcd8f03..be525f5 100644 --- a/tester.cpp +++ b/tester.cpp @@ -72,7 +72,7 @@ const string CODETYPES[]={ enum COMPILE_ERRORS errorLevel=E_OK; unsigned int indentLevel=0; bool scopeGlobal=true; -unsigned int currentFunc=0; +fn *currentFunc=nullptr; bool COMPILE=false; bool DUMP=false; @@ -336,9 +336,7 @@ void testFunc() func=fn::declare(name, T_FLOATFUNC, o); logger("funkBeat"); name=string("radius"); - v=variableType::getOrCreateVar(name, T_FLOATVAR); - logger("param made"); - func->addParameter(v); + func->addParameter(name, T_FLOATVAR); logger("param added"); e=new expression(new expression(v), O_MULTIPLY, new expression(v)); logger("expression made"); diff --git a/yab2cpp.cpp b/yab2cpp.cpp index b643fba..42908b1 100644 --- a/yab2cpp.cpp +++ b/yab2cpp.cpp @@ -71,7 +71,7 @@ const string CODETYPES[]={ enum COMPILE_ERRORS errorLevel=E_OK; unsigned int indentLevel=0; bool scopeGlobal=true; -unsigned int currentFunc=0; +fn *currentFunc=nullptr; bool COMPILE=false; bool DUMP=false; diff --git a/yab2cpp.h b/yab2cpp.h index 8ce4c84..2c14acb 100644 --- a/yab2cpp.h +++ b/yab2cpp.h @@ -10,6 +10,7 @@ */ #include #include +#include #include #include #include @@ -23,6 +24,7 @@ using namespace std; #define VER_RELEASE 1 class variableType; +class fn; extern ofstream output_cpp; extern ofstream funcs_h; extern ofstream heap_h; @@ -60,9 +62,9 @@ enum COMPILE_ERRORS:unsigned int extern enum COMPILE_ERRORS errorLevel; extern unsigned int indentLevel; -/*TODO: Replace scopeGlobal with currentFunc==0*/ +/*TODO: Replace scopeGlobal with currentFunc==nullptr*/ extern bool scopeGlobal; -extern unsigned int currentFunc; +extern fn *currentFunc; /* flags used internally by the compiler */ extern bool COMPILE; @@ -111,13 +113,6 @@ enum CODES:unsigned int T_UNKNOWNFUNC }; -typedef union -{ - double d; - int i; - string *s; -}boxTypes; - /* subtypes of the T_PRINTSEPARATOR type */ enum SEPARATORS:unsigned int { @@ -131,7 +126,8 @@ enum SCOPES:unsigned int S_UNKNOWN, S_LOCAL, S_STATIC, - S_GLOBAL + S_GLOBAL, + S_PARAMETER }; enum OPERATORS:unsigned int @@ -169,11 +165,10 @@ class operands enum TYPES type; unsigned int id; static unsigned int nextID; - - /* private constructor for parameter passing only */ - explicit operands(unsigned int id, enum TYPES t); protected: void generateBox(enum SCOPES s); + /* constructor for parameter passing */ + explicit operands(unsigned int id, enum TYPES t); explicit operands(enum TYPES t); virtual ~operands() {} @@ -359,14 +354,15 @@ public: class variableType:public operands { enum SCOPES myScope; - unsigned int localID; + fn *handle; public: static variableType *getOrCreateVar(string &name, enum TYPES t); + static variableType *cloneAttributes(variableType *v); virtual string boxName(); void assignment(expression *value); /* always call generateBox() after new variableType() */ - variableType(enum SCOPES s, string &name, enum TYPES t, unsigned int fnID); + variableType(enum SCOPES s, string &name, enum TYPES t, fn *fnHandle); variableType(); ~variableType() {} @@ -408,7 +404,8 @@ class fn { static unordered_map > functions; static unsigned int nextID; - listparams; + unordered_mapparameters; + vectorparams; unsigned int id; enum CODES type; enum TYPES kind; @@ -426,7 +423,8 @@ public: enum CODES getType() const {return this->type;} unsigned int getID() const {return this->id;} size_t getNumParams() const {return this->params.size();} - void addParameter(variableType *); + variableType *getLocalVar(string &name); + void addParameter(string &name, enum TYPES t); operands *generateCall(string &name, list¶mList); /* standard return is for call */ diff --git a/yabDataStructures.cpp b/yabDataStructures.cpp index 125466d..e814daa 100644 --- a/yabDataStructures.cpp +++ b/yabDataStructures.cpp @@ -471,15 +471,14 @@ expression::~expression() } /* variable definitions */ -variableType::variableType(enum SCOPES s, string &name, enum TYPES t, unsigned int fnID):operands(t) +variableType::variableType(enum SCOPES s, string &name, enum TYPES t, fn *fnHandle):operands(t) { this->myScope=s; - this->localID=fnID; + this->handle=fnHandle; switch (s) { case S_LOCAL: - if(locals.find(name)!=locals.end() || - statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL); + if(handle->getLocalVar(name)) error(E_DUPLICATE_SYMBOL); locals[name]=unique_ptr(this); break; case S_GLOBAL: @@ -487,10 +486,13 @@ variableType::variableType(enum SCOPES s, string &name, enum TYPES t, unsigned i globals[name]=unique_ptr(this); break; case S_STATIC: - if(locals.find(name)!=locals.end() || - statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL); + if(handle->getLocalVar(name)) error(E_DUPLICATE_SYMBOL); statics[name]=unique_ptr(this); break; + case S_PARAMETER: + if (handle->getLocalVar(name)) error(E_DUPLICATE_SYMBOL); + /* parameter is added to function list by addParamter */ + break; default: error(E_INTERNAL); } @@ -501,7 +503,7 @@ string variableType::boxName() ostringstream ss; if (myScope==S_LOCAL) { - ss << "sub" << this->localID << "->v" << this->getID(); + ss << "sub" << this->handle->getID() << "->v" << this->getID(); return ss.str(); } ss << "v" << this->getID(); @@ -510,18 +512,17 @@ string variableType::boxName() variableType *variableType::getOrCreateVar(string &name, enum TYPES t) { - if (!scopeGlobal) + variableType *v; + if (currentFunc!=nullptr) { - auto i=locals.find(name); - if(i!=locals.end())return i->second.get(); - i=statics.find(name); - if(i!=statics.end())return i->second.get(); + v=currentFunc->getLocalVar(name); + if (v!=nullptr) return v; } if (globals.find(name)!=globals.end())return globals[name].get(); - variableType *v; if (scopeGlobal) { - v=new variableType(S_GLOBAL, name, t, 0); + v=new variableType(S_GLOBAL, name, t, nullptr); + } else { diff --git a/yabFunctions.cpp b/yabFunctions.cpp index 734a619..cc5700c 100644 --- a/yabFunctions.cpp +++ b/yabFunctions.cpp @@ -53,8 +53,21 @@ fn *fn::getSub(string &name) return iter->second.get(); } -void fn::addParameter(variableType *v) +variableType *fn::getLocalVar(string &name) { + auto iter=this->parameters.find(name); + if (iter!=parameters.end()) return iter->second; + auto i=locals.find(name); + if (i!=locals.end()) return i->second.get(); + i=statics.find(name); + if (i!=statics.end()) return i->second.get(); + return nullptr; +} + +void fn::addParameter(string &name, enum TYPES t) +{ + variableType *v=new variableType(S_PARAMETER, name, t, this); + this->parameters[name]=v; this->params.push_back(v); } @@ -205,7 +218,7 @@ void fn::close() } locals.clear(); statics.clear(); - currentFunc=0; + currentFunc=nullptr; scopeGlobal=true; } @@ -221,7 +234,7 @@ fn *fn::declare(string &s, enum CODES t, operands *returnCode) fn::functions.insert({s,unique_ptr(self)}); logger("fn inserted"); /* initiate local scope */ - currentFunc=self->getID(); + currentFunc=self; scopeGlobal=false; return self; } @@ -243,6 +256,5 @@ fn::fn(enum CODES t, operands *returnCode) fn::~fn() { - this->params.clear(); delete startAddr; }