//Input: A conditional expression x (at AND level) //Output: The conditional expression !x NC* negateConditionalExpression( NC *cond ) { NC *negCond; if(cond == NULL) return NULL; negCond = (NC*) malloc (sizeof(NC)); negCond->list = NULL; negCond->type = 'A'; negCond->inc = 0; negCond->link = computeNegation(cond->link); return negCond; }
//Input: A conditional expression x (at OR level) //Output: The conditional expression !x NC* computeNegation( NC *cond ) { NC *retOr, *oldOr, *newOr; NC *iRel, *oneRel; NC *retNegCond, *jRet; //base case if(cond->list == NULL) { for(iRel = cond->link; iRel != NULL; iRel = iRel->list) { oneRel = (NC*) malloc (sizeof(NC)); oneRel->list = NULL; oneRel->type = 'R'; oneRel->inc = negateoperator(iRel->inc); oneRel->link = copylist(iRel->link); newOr = (NC*) malloc (sizeof(NC)); newOr->list = NULL; newOr->type = 'O'; newOr->inc = 0; newOr->link = oneRel; if(iRel == cond->link) retOr = newOr; else oldOr->list = newOr; oldOr = newOr; } return retOr; } //inductive case retNegCond = computeNegation( cond->list ); for(iRel = cond->link; iRel != NULL; iRel = iRel->list) { for(jRet = retNegCond; jRet != NULL; jRet = jRet->list) { oneRel = (NC*) malloc (sizeof(NC)); oneRel->list = copylist(jRet->link); oneRel->type = 'R'; oneRel->inc = negateoperator(iRel->inc); oneRel->link = copylist(iRel->link); newOr = (NC*) malloc (sizeof(NC)); newOr->list = NULL; newOr->type = 'O'; newOr->inc = 0; newOr->link = oneRel; if(iRel == cond->link) retOr = newOr; else oldOr->list = newOr; oldOr = newOr; } } return retOr; }
int computeOperation(astNode* exprNode, symTab* symtab) { astNode* lhs = exprNode->leftMostChild; if(lhs != NULL && lhs->type == OPERATOR) return(computeNegation(lhs, symtab)); astNode* operator = lhs->rightSibling; astNode* rhs = operator->leftMostChild; short rhsReg = -1; short lhsReg = -1; /* Left Hand Side */ if (lhs == NULL || lhs->type == NULLNODE) { lhsReg = -1; } else if(lhs->type == EXPR || lhs->type == OPERATION) { if(computeExpression(lhs, symtab) >= 0) { lhsReg = 0; } } else if(lhs->type == NUMBER) { // Loading number into temp fprintf(yyoutasm, "\tli\t$t0, %d\t\t# Load %d into $t0\n", lhs->intVal, lhs->intVal); lhsReg = 0; pushStackReg("$t0", symtab); } else if (lhs->type == VAR){ varToStack(lhs, symtab); lhsReg = 0; } /* Right Hand Side */ if (rhs == NULL || rhs->type == NULLNODE) { rhsReg = -1; } else if(rhs->type == EXPR || rhs->type == OPERATION) { if(computeExpression(rhs, symtab) >= 0) { rhsReg = 1; } } else if(rhs->type == NUMBER) { // Loading number into temp fprintf(yyoutasm, "\tli\t$t1, %d\n", rhs->intVal); rhsReg = 1; pushStackReg("$t1", symtab); } else if (rhs->type == VAR){ varToStack(rhs, symtab); rhsReg = 1; } fprintf(yyoutasm, "\t# Operation\n"); if(lhsReg < 0 && rhsReg < 0) { fprintf(yyoutasm, "\t# End operation\n"); return 0; } else if(lhsReg < 0) { fprintf(yyoutasm, "\t# End operation\n"); return 1; } else if(rhsReg < 0) { fprintf(yyoutasm, "\t# End operation\n"); return 1; } else { popStackReg("$t1", symtab); // RHS popStackReg("$t0", symtab); // LHS switch(operator->operator) { case '+': fprintf(yyoutasm, "\tadd\t$t2, $t0, $t1\t# Add $t0 and $t1 and store in $t2\n"); break; case '-': fprintf(yyoutasm, "\tsub\t$t2, $t0, $t1\t# Subtract $t0 and $t1 and store in $t2\n"); break; case '*': fprintf(yyoutasm, "\tmult\t$t0, $t1\t# Multiply $t0 and $t1\n"); fprintf(yyoutasm, "\tmflo\t$t2\t# Store result in $t2\n"); break; case '/': fprintf(yyoutasm, "\tdiv\t$t0, $t1\t# Divide $t0 and $t1\n"); fprintf(yyoutasm, "\tmflo\t$t2\t# Store result in $t2\n"); break; case '<': fprintf(yyoutasm, "\tli\t$t2, -1\n"); // True fprintf(yyoutasm, "\tblt\t$t0, $t1, e%d\n", labelCount); // If lhs < rhs, jump next stmt fprintf(yyoutasm, "\tnop\n"); fprintf(yyoutasm, "\tli\t$t2, 0\n"); // False fprintf(yyoutasm, "e%d:\n", labelCount++); break; case '=': fprintf(yyoutasm, "\tli\t$t2, -1\n"); // True fprintf(yyoutasm, "\tbeq\t$t0, $t1, e%d\n", labelCount); // If lhs = rhs, jump next stmt fprintf(yyoutasm, "\tnop\n"); fprintf(yyoutasm, "\tli\t$t2, 0\n"); // False fprintf(yyoutasm, "e%d:\n", labelCount++); break; case '&': fprintf(yyoutasm, "\tli\t$t2, 0\n"); // False fprintf(yyoutasm, "\tbeq\t$t0, $0, e%d\n", labelCount); // If lhs = 0 (false), we jump over the whole stmt and evaluate to false fprintf(yyoutasm, "\tnop\n"); fprintf(yyoutasm, "\tbeq\t$t1, $0, e%d\n", labelCount); // Otherwise, lhs is true and we evaluate rhs fprintf(yyoutasm, "\tnop\n"); fprintf(yyoutasm, "\tli\t$t2, -1\n"); // True fprintf(yyoutasm, "e%d:\n", labelCount++); break; case '|': fprintf(yyoutasm, "\tli\t$t2, -1\n"); // True fprintf(yyoutasm, "\tbne\t$t0, $0, e%d\n", labelCount); // If lhs != 0 (true), we jump over the whole stmt and evaluate to true fprintf(yyoutasm, "\tnop\n"); fprintf(yyoutasm, "\tbne\t$t1, $0, e%d\n", labelCount); // Otherwise, lhs is false and we evaluate rhs fprintf(yyoutasm, "\tnop\n"); fprintf(yyoutasm, "\tli\t$t2, 0\n"); // False fprintf(yyoutasm, "e%d:\n", labelCount++); break; default: break; } } pushStackReg("$t2", symtab); // Push on stack fprintf(yyoutasm, "\t# End operation\n"); return 1; }