void doCompare(ListIterator &i, ExprNode *&test) { ExprNode *trueCase, *falseCase, *right; string comp; doSum(i, test); if(!i.ended()) { if(i.token().tokenChar() == ")") i.advance(); } if(!i.ended() && i.token().isOperator()) { comp = i.token().tokenChar(); i.advance(); doSum(i, right); test = new Operation(test, comp, right); } if(!i.ended() && (i.token().tokenChar() == "?" || i.token().isOperator())) { i.advance(); doSum(i, trueCase); } if(!i.ended() && (i.token().isOperator() || i.token().tokenChar() == ":")) { i.advance(); doSum(i, falseCase); test = new Conditional(test, trueCase, falseCase); } }
void doCall(ListIterator &i, ExprNode *&node) { string name; ExprNode *parameters[10]; int p = 0; if(!i.ended()) name = i.token().tokenChar(); i.advance(); if(!i.ended()) doCompare(i, node); parameters[p] = node; p++; if(!i.ended()){ while(!i.ended() && i.token().tokenChar() != ")") { if(!i.ended()) doCompare(i, node); parameters[p] = node; p++; } } for(; p < 10; p++) parameters[p] = NULL; node = new Function(name, parameters); }
void doSum(ListIterator &i, TokenList *pf) { char oper; // For holding the operator doProduct(i, pf); // Sum = product + product if(!i.ended()) oper = i.token().tokenChar(); // Grab an operator, only if current != NULL while(((oper == '+') || (oper == '-')) && !i.ended() ) { i.advance(); // Move to next token, an int or a '(' doProduct(i, pf); Token t(oper); pf->push_back(t); // Add the operator the the expression if(!i.ended()) oper = i.token().tokenChar(); // Grab the next operator } }
void doAssign(ListIterator &i, ExprNode *&node) { ExprNode *left, *right; string eq; ListIterator temp = i; node = new Variable(i.token().tokenChar()); if(!i.ended()) i.advance(); if(!i.ended()) eq = i.token().tokenChar(); if(eq == "=" && !i.ended()) { while(eq == "=" && !i.ended()) { if(!i.ended()) i.advance(); if(!i.ended()) doSum(i, right); node = new Operation(node, eq, right); if(!i.ended()) eq = i.token().tokenChar(); else eq = "Done"; } } else if(!i.ended() && (i.token().tokenChar() != "(")) i = temp; else if(!i.ended() && (i.token().tokenChar() == "(")) { i = temp; doCall(i, node); } }
void doDefine(ListIterator &i, FunctionDef &fmap) { string n; string parameters[10]; ExprNode *body; int p = 0; i.advance(); // i is now on the function name if(!i.ended()) n = i.token().tokenChar(); i.advance(); // i is now on open paren of parameters i.advance(); // i is now on the first parameter if(!i.ended()) parameters[p] = i.token().tokenChar(); p++; i.advance(); // i is now on comma separating parameters or close paren while(i.token().tokenChar() == "," && !i.ended()) { i.advance(); // i is now on next parameter if(!i.ended()) parameters[p] = i.token().tokenChar(); p++; i.advance(); // i is on new comma or close paren } i.advance(); // i is now on "=" i.advance(); if(!i.ended()) doCompare(i, body); fmap[n].name = n; for(int i = 0; i < p; i++) { fmap[n].parameter[i] = parameters[i]; } fmap[n].functionBody = body; fmap[n].locals = new VarTree(); cout << *fmap[n].functionBody << endl; }
void doProduct(ListIterator & i, ExprNode *&node) { ExprNode *left, *right; string oper; doFactor(i, node); if(!i.ended()) oper = i.token().tokenChar(); while(oper == "*" || oper == "/" || oper == "%") { i.advance(); doFactor(i, right); node = new Operation(node, oper, right); if(!i.ended()) oper = i.token().tokenChar(); else oper = "Done"; } }
void doProduct(ListIterator &i, TokenList *pf) // Works exactly the same way as doSum(), except { // here, left and right are factors int left, right; char oper; doFactor(i, pf); // product = factor * factor if(!i.ended()) oper = i.token().tokenChar(); while(((oper == '*') || (oper == '/') || (oper =='%')) && !i.ended()) { i.advance(); doFactor(i, pf); Token t(oper); pf->push_back(t); if(!i.ended()) oper = i.token().tokenChar(); } }
void doFactor(ListIterator &i, TokenList *pf) // Grabs a factor; evaluates if needed; return { int left; // factor = int || factor = (int + int) if(i.token().tokenChar() == '(') { i.advance(); doSum(i, pf); } else { left = i.token().integerValue(); // grab the factor Token t(left); pf->push_back(t); // add it to the list } if(!i.ended()) i.advance(); }
void doFactor(ListIterator &i, ExprNode *&node) { ExprNode *left; if(i.token().tokenChar() == "(") { i.advance(); doSum(i, node); } else { if(i.token().isInteger()) { node = new Value(i.token().integerValue()); } else if(!i.token().isOperator()) doAssign(i, node); else doCompare(i, node); } if(!i.ended()) i.advance(); }
int evaluate(const char str[]) { TokenList l(str); // Declare and construct our linked list TokenList *pf = new TokenList; // List for postfix expression static int ans = 0; // For handling previous answers ListIterator i = l.begin(); if((!i.token().isInteger()) && (i.token().tokenChar() != '(')) { // Complicated condition: evaluates as true if l.head is an operator // but not a parenthesis. // In this case, we want to push the previous answer to the front Token newHead(ans); l.push_front(newHead); i = l.begin(); } doSum(i, pf); // Here begins the Conversion cout << l << endl; cout << *pf << endl; TokenList *stack = new TokenList; // Stack for holding operators ListIterator eval = pf->begin(); // Iterator to parse postfix expression Token left, right; // Containers while(!eval.ended()) { if(eval.token().isInteger()) // While there are integers, push them onto the stack stack->push_front(eval.token()); else { right = stack->pop(); // grab the operands in order left = stack->pop(); switch(eval.token().tokenChar()) // Evaluate each piece of postfix { case '+': left = (left.integerValue() + right.integerValue()); break; case '-': left = (left.integerValue() - right.integerValue()); break; case '*': left = (left.integerValue() * right.integerValue()); break; case '/': left = (left.integerValue() / right.integerValue()); break; case '%': left = (left.integerValue() % right.integerValue()); break; } stack->push_front(left); } eval.advance(); } ans = left.integerValue(); return ans; }