diff --git a/tester.cpp b/tester.cpp index 27aa1d5..a996a98 100644 --- a/tester.cpp +++ b/tester.cpp @@ -10,9 +10,9 @@ #include "yab2cpp.h" #include -unordered_map >globals; -unordered_map >locals; -unordered_map >statics; +unordered_map >globals; +unordered_map >locals; +unordered_map >statics; /* These correspond to the enum COMPILE_ERRORS. */ const char *COMPILE_ERROR_NAMES[]={ @@ -27,7 +27,8 @@ const char *COMPILE_ERROR_NAMES[]={ "value returned from gosub call", "undefined subroutine name", "too many parameters in function call", - "value cannot be assigned" + "value cannot be assigned", + "undimensioned array or undeclared function" }; /* These correspond to the types of enum TYPES. */ @@ -214,8 +215,8 @@ void setUp() [[noreturn]] void error(enum COMPILE_ERRORS e) { - cerr << COMPILE_ERROR_NAMES[e] << endl; errorLevel=e; + shutDown(); exit(1); } @@ -245,6 +246,8 @@ void shutDown() { if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl; + logger("Purging tempVar queues"); + tempVar::eraseQueues(); logger("Dumping stack."); if (DUMP && (logfile)) fn::dumpCallStack(); if (DUMP) @@ -271,17 +274,14 @@ void shutDown() statics.clear(); } -shared_ptrname; -shared_ptrv; -shared_ptrprint; +variableType *v; +printSegment *print; void testInt() { - name=shared_ptr(new string("v")); - v=variableType::getOrCreateVar(*name, T_INTVAR); - v->assignment(shared_ptr(new expression( - shared_ptr(new constOp("2", T_INT))))); - print=shared_ptr( - new printSegment(shared_ptr(new expression(v)))); + string name=string("v"); + v=variableType::getOrCreateVar(name, T_INTVAR); + v->assignment(new expression(new constOp("2", T_INT))); + print=new printSegment(new expression(v)); print->generate(); label::generateEnd(); } diff --git a/yab2cpp.cpp b/yab2cpp.cpp index 72eda75..5a29d1c 100644 --- a/yab2cpp.cpp +++ b/yab2cpp.cpp @@ -7,10 +7,11 @@ ** */ #include "yab2cpp.h" +#include -unordered_map >globals; -unordered_map >locals; -unordered_map >statics; +unordered_map >globals; +unordered_map >locals; +unordered_map >statics; /* These correspond to the enum COMPILE_ERRORS. */ const char *COMPILE_ERROR_NAMES[]={ @@ -25,7 +26,8 @@ const char *COMPILE_ERROR_NAMES[]={ "value returned from gosub call", "undefined subroutine name", "too many parameters in function call", - "value cannot be assigned" + "value cannot be assigned", + "undimensioned array or undeclared function" }; /* These correspond to the types of enum TYPES. */ @@ -92,7 +94,6 @@ void shutDown(); /* process command line parameters */ int main(int argc, char *argv[]) { - atexit(shutDown); switch (argc) { case 1: @@ -150,6 +151,7 @@ int main(int argc, char *argv[]) helpText(argv[0]); break; } + cout << "program exiting" <\n#include \"consts.h\"\n" + output_cpp << "#include \"../runtime/runtime.h\"\n#include \"consts.h\"\n" << "#include \"heap.h\"\n#include \"functions.h\"\n" - << "int main(int argc, char *argv[])\n{\n" - << "unsigned int state=start;\nint run(){\nwhile (state>=start){\n" - << "switch(state){\ncase start:" << endl; - if (DUMP) - { - varNames.open("varnames.txt"); - } + << "unsigned int state=START;\nunsigned int run(){\n" + << "while (state>=START){\n" + << "switch(state){\ncase START:" << endl; + } + else + { + output_cpp.open("/dev/null"); + funcs_h.open("/dev/null"); + consts_h.open("/dev/null"); + heap_h.open("/dev/null"); + } + if (DUMP) + { + varNames.open("varnames.log"); + } + else + { + varNames.open("/dev/null"); } if (DEBUG) { @@ -193,11 +206,16 @@ void setUp() logfile.open("parse.log"); logger("Setup complete."); } + else + { + logfile.open("/dev/null"); + } } [[noreturn]] void error(enum COMPILE_ERRORS e) { errorLevel=e; + shutDown(); exit(1); } @@ -218,27 +236,41 @@ void logger(string s) if (DEBUG) { indent(); - logfile << s << endl; + logfile << s << "\n"; } } /* shutdown the compiler and exit */ void shutDown() { - if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl; + if (errorLevel != E_OK) cerr << "\nERROR: " + << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl; + logger("Purging tempVar queues"); + tempVar::eraseQueues(); logger("Dumping stack."); - if (DUMP && (logfile)) + if (DUMP && (logfile)) fn::dumpCallStack(); + if (DUMP) { - fn::dumpCallStack(); - } - varNames << "Global Variables\n"; - for(auto iter=globals.begin(); iter!=globals.end(); ++iter) - { - varNames << "variable " << iter->first << " has ID " << iter->second << "\n"; - } - varNames << endl; + varNames << "Global Variables\n"; + for(auto iter=globals.begin(); iter!=globals.end(); ++iter) + { + varNames << "variable " << iter->first + << " has ID " << iter->second->getID() << "\n"; + } + varNames << endl; label::dumpLabels(); - output_cpp << "}\n}return state;\n}"<< endl; + } + if (COMPILE) + { + output_cpp << "default:\nstate=UNDEFINED_STATE_ERROR;\n" + << "break;\n}\n}\nreturn state;\n}"<< endl; + funcs_h.flush(); + consts_h.flush(); + heap_h.flush(); + } + globals.clear(); + locals.clear(); + statics.clear(); } /* open files and compile */ @@ -250,4 +282,3 @@ void compile() shutDown(); } - diff --git a/yab2cpp.h b/yab2cpp.h index 7a19bdb..7249c63 100644 --- a/yab2cpp.h +++ b/yab2cpp.h @@ -29,9 +29,9 @@ extern ofstream heap_h; extern ofstream consts_h; extern ofstream logfile; extern ofstream varNames; -extern unordered_map >globals; -extern unordered_map >locals; -extern unordered_map >statics; +extern unordered_map >globals; +extern unordered_map >locals; +extern unordered_map >statics; extern const string CODETYPES[]; extern const string TYPENAMES[]; @@ -41,7 +41,8 @@ extern const string TYPENAMES[]; ** Note: There must be a corresponding error message ** to each entry in the COMPILE_ERROR_NAMES constant array. */ -enum COMPILE_ERRORS { +enum COMPILE_ERRORS:unsigned int +{ E_OK=0, E_BAD_SYNTAX, E_TYPE_MISMATCH, @@ -68,7 +69,7 @@ extern bool DEBUG; extern bool TRACE; /* list of all variableType and constant types */ -enum TYPES +enum TYPES:unsigned int { T_UNKNOWN=0, T_NONE, @@ -85,7 +86,7 @@ enum TYPES }; /* list of all kinds of other code structures */ -enum CODES +enum CODES:unsigned int { T_PRINT=0, T_PRINTSEGMENT, @@ -116,14 +117,14 @@ typedef union }boxTypes; /* subtypes of the T_PRINTSEPARATOR type */ -enum SEPARATORS +enum SEPARATORS:unsigned int { S_COMMA, S_SEMICOLON, S_LINEFEED }; -enum SCOPES +enum SCOPES:unsigned int { S_UNKNOWN, S_LOCAL, @@ -131,7 +132,7 @@ enum SCOPES S_GLOBAL }; -enum OPERATORS +enum OPERATORS:unsigned int { O_PLUS, O_MINUS, @@ -165,20 +166,46 @@ 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); + explicit operands(enum TYPES t); + virtual ~operands() + {} public: enum TYPES getType() const {return type;} unsigned int getID() const {return id;} enum TYPES getSimpleVarType(); - void generateBox(enum SCOPES s); virtual string boxName(); - enum TYPES coerceTypes(); + static enum TYPES getSimpleVarType(enum TYPES t); - explicit operands(enum TYPES t); - virtual ~operands() + /* abstract factory */ + static operands *createOp(enum TYPES t); + virtual void dispose(); +}; + +class tempVar:public operands +{ + static listintQueue; + static listfloatQueue; + static liststringQueue; + + /* private constructor called by getOrCreateVar */ + explicit tempVar(enum TYPES t); + /* private destructor called by eraseQueues */ + virtual ~tempVar() {} +public: + /* factory method to recycle existing tempVar */ + static tempVar *getOrCreateVar(enum TYPES t); + + /* purge queues at end of compile */ + static void eraseQueues(); + /* recycle tempVar in a queue */ + virtual void dispose(); }; /* constant operands */ @@ -203,36 +230,23 @@ public: /* expression can be terminal or non-terminal node */ class expression { - shared_ptrop; - shared_ptrleft; - shared_ptrright; + operands *op; + expression *left; + expression *right; enum OPERATORS oper; public: enum OPERATORS getOp() const {return oper;} - shared_ptrgetLeft() const {return left;} - shared_ptrgetRight() const {return right;} + expression *getLeft() const {return left;} + expression *getRight() const {return right;} bool isBinOp(); - shared_ptrevaluate(); - shared_ptrstringEval(shared_ptrl, - shared_ptrr); + operands *evaluate(); /* r is NULL for unary operators */ - expression(shared_ptrl, enum OPERATORS o, - shared_ptrr=NULL) - { - this->left=l; - this->right=r; - this->oper=o; - } + expression(expression *l, enum OPERATORS o, expression *r=nullptr); /* Terminal expression node */ - expression(shared_ptrx) - { - op=x; - oper=O_TERM; - } - /*TODO: Recycle temporary variableTypes when not in debug mode*/ + expression(operands *x); virtual ~expression() {} }; @@ -252,7 +266,7 @@ class label { unsigned int id; static unsigned int nextID; - static unordered_map > lookup; + static unordered_map > lookup; public: static void dumpLabels(); static void generateEnd(); @@ -262,19 +276,18 @@ public: void generateJumpTo(); /* pass generateOnNSkip as second paramater to generateOnNTo or generateOnNSub */ - unsigned int generateOnNSkip(list >&dest); - static void generateOnNTo(shared_ptre, unsigned int skip); - void generateCondJump(shared_ptre); + unsigned int generateOnNSkip(list