void PRINTF(void){ /*printf ::= <KW_PRINTF> "(" assignment ")"*/ switch(l){ case KW_PRINTF: eat(KW_PRINTF); eat('('); ASSIGNMENT(); eat(')'); return; default: StdError(__func__); } }
void IFSTATEMENT(void){ /*ifstatement ::= <KW_IF> "(" assignment ")" block*/ switch(l){ case KW_IF: eat(KW_IF); eat('('); ASSIGNMENT(); eat(')'); BLOCK(); return; /*expand parse tree with these 5 nodes, then expand the leftmost, then the next, ...*/ default: StdError(__func__); } }
void RESTOF_STATICASSIGNMENT_OR_FUNCTIONCALL(void){ /*restof_statassignment_or_functioncall ::= "=" assignment | ( assignmentlist )*/ switch(l){ case '=': eat('='); ASSIGNMENT(); return; case KW_FLOAT: eat('('); ASSIGNMENTLIST(); eat(')'); return; default: StdError(__func__); } }
void ASSIGNMENTLIST_TAIL(void){ /*assignmentlist = , assignment assignmentlist_tail | epsilon*/ switch(l){ case ',': eat(','); ASSIGNMENT(); ASSIGNMENTLIST_TAIL(); return; case ')': return; default: StdError(__func__); } }
void RETURNSTATEMENTS_ASSIGNMENT(void){ /*returnstatements_assignment :== assignment | epsilon*/ switch(l){ case ID: case '-': case CONST_INT: case CONST_FLOAT: case CONST_BOOLEAN: case '(': ASSIGNMENT(); return; case ';': return; /*apply rule 2. lookahead is in follow(returnstatements_assignment) = {;}*/ default: StdError(__func__); } }
void ASSIGNMENTLIST(void){ /*assignmentlist = assignment assignmentlist_tail | epsilon*/ switch(l){ case ID: case '-': case CONST_INT: case CONST_FLOAT: case CONST_BOOLEAN: case '(': ASSIGNMENT(); ASSIGNMENTLIST_TAIL(); return; case ')': return; default: StdError(__func__); } }
void ASSIGNMENT(void){ /*assignment = id "=" assignment | expr*/ /*Note that FIRST(id = assignment) and FIRST(EXPR) both contain ID*/ switch(l){ case '-': case CONST_INT: case CONST_FLOAT: case CONST_BOOLEAN: case '(': EXPR(); return; case ID: if (l2 == '=') {eat(ID); eat('='); ASSIGNMENT(); return;} /*expand according to rule 1*/ else /*note that EXPR can only derive into something that starts with an ID by deriving into id restof_functioncall_or_epsilon. Strings derived from the latter nonterminal either start with '(' or with something in FOLLOW(restof_functioncall_or_epsilon). The latter set does not contain =. It is '*'||'/'||AND||'+'||'-'||OR||LSS||GRT||LEQ||GEQ||EQ||NEQ||')'||';'||',').*/ {EXPR(); return;} /*rule 2*/ default: StdError(__func__); } }
void FACTOR(void){ /*factor ::= <CONST_INT> | <CONST_FLOAT> | <CONST_BOOLEAN> | id restof_functioncall_or_epsilon | "(" assignment ")"*/ switch(l){ case CONST_INT: eat(CONST_INT); return; case CONST_FLOAT: eat(CONST_FLOAT); return; case CONST_BOOLEAN: eat(CONST_BOOLEAN); return; case ID: eat(ID); RESTOF_FUNCTIONCALL_OR_EPSILON(); return; case '(': eat('('); ASSIGNMENT(); eat(')'); return; default: StdError(__func__); } }
/** Register reduction for assignment. */ static int packRegsForAssign (iCode *ic, eBBlock *ebp) { iCode *dic, *sic; if (!IS_ITEMP (IC_RIGHT (ic)) || OP_SYMBOL (IC_RIGHT (ic))->isind || OP_LIVETO (IC_RIGHT (ic)) > ic->seq) return 0; /* Avoid having multiple named address spaces in one iCode. */ if (IS_SYMOP (IC_RESULT (ic)) && SPEC_ADDRSPACE (OP_SYMBOL (IC_RESULT (ic))->etype)) return 0; /* find the definition of iTempNN scanning backwards if we find a a use of the true symbol in before we find the definition then we cannot */ for (dic = ic->prev; dic; dic = dic->prev) { /* PENDING: Don't pack across function calls. */ if (dic->op == CALL || dic->op == PCALL) { dic = NULL; break; } if (SKIP_IC2 (dic)) continue; if (dic->op == IFX) { if (IS_SYMOP (IC_COND (dic)) && (IC_COND (dic)->key == IC_RESULT (ic)->key || IC_COND (dic)->key == IC_RIGHT (ic)->key)) { dic = NULL; break; } } else { if (IS_TRUE_SYMOP (IC_RESULT (dic)) && IS_OP_VOLATILE (IC_RESULT (dic))) { dic = NULL; break; } if (IS_SYMOP (IC_RESULT (dic)) && IC_RESULT (dic)->key == IC_RIGHT (ic)->key) { if (POINTER_SET (dic)) dic = NULL; break; } if (IS_SYMOP (IC_RIGHT (dic)) && (IC_RIGHT (dic)->key == IC_RESULT (ic)->key || IC_RIGHT (dic)->key == IC_RIGHT (ic)->key)) { dic = NULL; break; } if (IS_SYMOP (IC_LEFT (dic)) && (IC_LEFT (dic)->key == IC_RESULT (ic)->key || IC_LEFT (dic)->key == IC_RIGHT (ic)->key)) { dic = NULL; break; } if (IS_SYMOP (IC_RESULT (dic)) && IC_RESULT (dic)->key == IC_RESULT (ic)->key) { dic = NULL; break; } } } if (!dic) return 0; /* did not find */ /* if assignment then check that right is not a bit */ if (ASSIGNMENT (ic) && !POINTER_SET (ic)) { sym_link *etype = operandType (IC_RESULT (dic)); if (IS_BITFIELD (etype)) { /* if result is a bit too then it's ok */ etype = operandType (IC_RESULT (ic)); if (!IS_BITFIELD (etype)) { return 0; } } } /* if the result is on stack or iaccess then it must be the same atleast one of the operands */ if (OP_SYMBOL (IC_RESULT (ic))->onStack || OP_SYMBOL (IC_RESULT (ic))->iaccess) { /* the operation has only one symbol operator then we can pack */ if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) || (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic)))) goto pack; if (!((IC_LEFT (dic) && IC_RESULT (ic)->key == IC_LEFT (dic)->key) || (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key))) return 0; } pack: /* found the definition */ /* replace the result with the result of */ /* this assignment and remove this assignment */ bitVectUnSetBit (OP_SYMBOL (IC_RESULT (dic))->defs, dic->key); IC_RESULT (dic) = IC_RESULT (ic); if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) { OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq; } /* delete from liverange table also delete from all the points inbetween and the new one */ for (sic = dic; sic != ic; sic = sic->next) { bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key); if (IS_ITEMP (IC_RESULT (dic))) bitVectSetBit (sic->rlive, IC_RESULT (dic)->key); } remiCodeFromeBBlock (ebp, ic); // PENDING: Check vs mcs51 bitVectUnSetBit (OP_SYMBOL (IC_RESULT (ic))->defs, ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); return 1; }