diff --git a/yab2cpp.cpp b/yab2cpp.cpp index 1e83273..0bfbe7a 100644 --- a/yab2cpp.cpp +++ b/yab2cpp.cpp @@ -170,369 +170,3 @@ void compile() shutDown(); } -/* methods for operands */ -static void operands::dumpVars(ostream &out) -{ - out << "Global Variables\n"; - for(auto iter=globals.begin(); iter!=globals.end(); ++iter) - { - out << "variable " << iter->first << " has ID " << iter->second << "\n"; - } - out << endl; -} - -unsigned int operands::getOrCreateStr(ostream &k, string &s) -{ - auto iter=constStr.find(s); - if (iter!=constStr.end()) return iter->second; - ++nextID; - k << "const string k" << nextID << "=\"" << s << "\";\n"; - constStr[s]=nextID; - return nextID; -} - -unsigned int operands::createConst(ostream &k, string &s, enum TYPES t) -{ - operands *me=new operands(t); - if (t==T_INT) - { - k << "const int k"; - } - else - { - if (t==T_FLOAT) - { - k << "const double k"; - } - else - { - errorLevel=E_TYPE_MISMATCH; - exit(1); - } - } - k << me->getID() << "=" << s << ";\n"; - return me; -} - -enum TYPES operands::getSimpleVarType() -{ - switch type - { - case T_FLOAT: - case T_FLOATCALL_ARRAY: - case T_FLOATVAR: - return T_FLOATVAR; - case T_INT: - case T_INTCALL_ARRAY: - case T_INTVAR: - return T_INTVAR; - case T_STRING: - case T_STRINGCALL_ARRAY: - case T_STRINGVAR: - return T_STRINGVAR; - } - return T_NONE; -} - -enum TYPES operands::coerceTypes() -{ - if this->isBinOp() - { - if (l->getSimpleVarType()==T_INTVAR && r->getSimpleVarType()==T_FLOATVAR) - { - /* promote l to float */ - t=T_FLOATVAR; - break; - } - if (l->getSimpleVarType()==T_FLOAT && r->getSimpleVarType()==T_INT) - { - /* promote r to float */ - t=T_FLOATVAR; - break; - } - if (l->getSimpleVarType()==r->getSimpleVarType()) - { - break; - } - errorLevel=E_TYPE_MISMATCH; - exit(1); - } - else - { - if (t==T_NONE) - { - errorLevel=E_TYPE_MISMATCH; - } - } - -} - -/* operands used by expression parser and variables */ - -operands::operands(enum TYPES t) -{ - this->id = ++nextID; - this->type=t; -} - -void operands::generateBox(ostream &out) -{ - switch (this->getSimpleVarType()) - { - case T_INTVAR: - out << "int v"; - break; - case T_FLOATVAR: - out << "double v"; - break; - case T_STRINGVAR: - out << "string v"; - break; - default: - errorLevel=E_TYPE_MISMATCH; - exit(1); - break; - } - out << this->getID() << ";\n"; -} - -operands *operands::getOrCreateGlobal(ostream &heap, string &s, enum TYPES t) -{ - operands op*=operands::globals->find(s); - if (op==globals.end()) - { - op=new variable(heap, s, t); - } - return op; -} - -void operands::boxName(ostream &out) -{ - switch (this->getType()) - { - case T_STRINGVAR: - case T_INTVAR: - case T_FLOATVAR: - break; - - default: - errorLevel=E_INTERNAL; - exit(1); - break; - } - out << "v" << this->getID(); -} - -/* expression parsing routines */ - -/* binary vs. unary ops */ -bool expression::isBinOp() -{ - switch this->getOp() - { - case O_NEGATE: - case O_NOT: - case O_INVERT: - return false; - break; - } - return true; -} - -operands *expression::evaluate(ostream &scope, ostream &output_cpp) -{ - operands *l, *r; - if (this->getOp()==O_TERM) return op; - l=this->getLeft()->evaluate(); - enum TYPES t=this->coerceTypes(); - l->getSimpleVarType(); - r=(this->isBinOp()?this->getRight()->evaluate():NULL); - switch (this->getOp()) - { - case O_INVERT: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n"; - break; - case O_NEGATE: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n"; - break; - case O_NOT: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n"; - break; - /* TODO: Check for divide by zero error and modulo zero error */ - case O_REMAINDER: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=" << l->boxName() << "%" << r->boxName() << ";\n"; - break; - case O_DIVIDE: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=" << l->boxName() << "/" << r->boxName() << ";\n"; - break; - case O_PLUS: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName() << ";\n"; - break; - case O_MINUS: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=" << l->boxName() << "-" << r->boxName() << ";\n"; - break; - case O_MULTIPLY: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=" << l->boxName() << "*" << r->boxName() << ";\n"; - break; - case O_OR: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=" << l->boxName() << "|" << r->boxName() << ";\n"; - break; - case O_AND: - this->op=new operands(t); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=" << l->boxName() << "&" << r->boxName() << ";\n"; - break; - case O_GREATER: - this->op=new operands(T_INTVAR); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=(" << l->boxName() << ">" << r->boxName() << ")?-1:0;\n"; - break; - case O_LESS: - this->op=new operands(T_INTVAR); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=(" << l->boxName() << "<" << r->boxName() << ")?-1:0;\n"; - break; - case O_GREATER_EQUAL: - this->op=new operands(T_INTVAR); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=(" << l->boxName() << ">=" << r->boxName() << ")?-1:0;\n"; - break; - case O_LESS_EQUAL: - this->op=new operands(T_INTVAR); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=(" << l->boxName() << "<=" << r->boxName() << ")?-1:0;\n"; - break; - case O_EQUAL: - this->op=new operands(T_INTVAR); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=(" << l->boxName() << "==" << r->boxName() << ")?-1:0;\n"; - break; - case O_UNEQUAL: - this->op=new operands(T_INTVAR); - this->op->generateBox(scope); - output_cpp << this->op->boxName() << "=(" << l->boxName() << "!=" << r->boxName() << ")?-1:0;\n"; - break; - default: - errorLevel=E_INTERNAL; - exit(1); - break; - } - delete this->left; - this->left=NULL; - if (this->isBinOp()) - { - delete this->right; - this->right=NULL; - } - this->oper=O_TERM; - return this->op; -} - -expression::~expression() -{ - if(this->getOp()==O_TERM) - { - delete this->op; - } - else - { - delete this->left; - if (this->isBinOp()) - { - delete this->right; - } - } -} - - -/* variable definitions */ -variable::variable(ostream &scope, string &name, enum TYPES t):operands(t) -{ - this->generateBox(scope); -} - -variable *variable::getOrCreateVarName(ostream &func, ostream &heap, string &name, enum TYPES t) -{ - variable *v; - if (!scopeGlobal) - { - fn *currentFunc=fn::getCurrentSub(); - v=fn::getOrCreateVar(func, heap, t, name, false); - return v; - } - return reinterpret_castoperands::getOrCreateGlobal(heap, name); -} - -void variable::assignment(expression *value) -{ - operands *op=value->evaluate(); - enum TYPES t=op->getSimpleVarType(); - switch (this->getType()) - { - case T_FLOATVAR: - if (t==T_INTVAR) - { - /* TODO: convert int to float */ - } - else - { - if (t!=T_FLOATVAR) - { - errorLevel=E_TYPE_MISMATCH; - exit(1); - } - } - break; - default: - if (t!=this->getType()) - { - errorLevel=E_TYPE_MISMATCH; - exit(1); - } - break; - } - this->boxName(output_cpp); - output_cpp << "="; - op->boxName(output_cpp); - output_cpp << ";\n"; -} - -/* function definitions */ -fn *fn::getCurrentSub() -{ - return callStack.back; -} - -void fn::generateOnNSub(ostream &out, expression *e) -{ - this->ret=new label(); - fn::callStack.push_back(this); - label::generateOnNTo(out, e); - out << "case " << ret->getID() << ":\n"; -} - -void fn::generateGosub(ostream &out, shared_ptr