expr* arithmetic_op( iopcode op, expr* expr1, expr* expr2, expr* result){ expr_t type1 = expr1->type; expr_t type2 = expr2->type; int i; if((type1 == var_e || type1 == tableitem_e || type1 == arithexpr_e || type1 == assignexpr_e || type1 == constnum_e) && (type2 == var_e || type2 == tableitem_e || type2 == arithexpr_e || type2 == assignexpr_e || type2 == constnum_e)){ if(type1 == constnum_e && type2 == constnum_e){ result = newexpr(constnum_e); result -> sym = newtemp(); if(op == ADD){ result -> numConst = expr1 -> numConst + expr2 -> numConst; }else if(op == SUB){ result -> numConst = expr1 -> numConst - expr2 -> numConst; }else if(op == MUL){ result -> numConst = expr1 -> numConst * expr2 -> numConst; }else if(op == DIV){ result -> numConst = expr1 -> numConst / expr2 -> numConst; }else if(op == MOD){ result -> numConst = fmod(expr1 -> numConst, expr2 -> numConst); } } else{ result = newexpr(arithexpr_e); result -> sym = newtemp(); emit(op, expr1, expr2, result, 0, yylineno); } return result; } return NULL; }
struct expr_s* make_call(expr* lvalue, expr* elist){ expr* func = emit_iftableitem(lvalue); expr* this = elist; expr* result = NULL; expr* next = NULL; expr* new_root = NULL; while(this!=NULL){ next = this->next; this->next = new_root; new_root = this; this = next; } this = new_root; while(this!=NULL){ emit(PARAM, this, NULL, NULL, 0, yylineno); this = this->next; } emit(CALL, func, NULL, NULL, 0, yylineno); result = newexpr(var_e); result->sym = newtemp(); emit(GETRETVAL, NULL, NULL, result, 0, yylineno); return result; }
expr* boolean_op(iopcode op, expr* expr1, expr* expr2, expr* result){ result = newexpr(boolexpr_e); result -> sym = newtemp(); emit(op, expr1, expr2, result, 0, yylineno); return result; }
expr* member_item(expr*lvalue,char* name){ lvalue=emit_iftableitem(lvalue); expr*item=newexpr(TABLEITEM_E); item->sym=lvalue->sym; if(name==NULL)printf("Name variable in member_item is NULL\n"); item->index=newexpr_conststring(name); return item; }
expr* emit_iftableitem(expr* e){ if(e->type!=TABLEITEM_E) return e; else{ expr* result=newexpr(VAR_E); result->sym=newtemp(); emit(TABLEGETELEM,e,e->index,result,0,0); return result; } }
expr* member_item(expr* lvalue, char* name){ expr* item; lvalue = emit_iftableitem(lvalue); item = newexpr(tableitem_e); item -> sym = lvalue -> sym; item -> index = newexpr_conststring(name); return item; }
expr* equal_op(iopcode op, expr* expr1, expr* expr2, expr* result){ if(expr1->type == expr2->type){ if (expr1 -> type == constnum_e){ result = newexpr(boolexpr_e); result -> sym = newtemp(); if(op == IF_EQ){ result -> boolConst = expr1 -> numConst == expr2 -> numConst; }else{ result -> boolConst = expr1 -> numConst != expr2 -> numConst; } emit(ASSIGN, newexpr_constbool(result -> boolConst), NULL, result, 0, yylineno); }else{ result = newexpr(boolexpr_e); result -> sym = newtemp(); emit(op, expr1, expr2, NULL, nextquadlabel()+3, yylineno); emit(ASSIGN, newexpr_constbool(0), NULL, result, 0, yylineno); emit(JUMP, NULL, NULL, NULL, nextquadlabel()+2, yylineno); emit(ASSIGN, newexpr_constbool(1), NULL, result, 0, yylineno); } return result; }else if((expr1 -> type == newtable_e && expr2 -> type == nil_e) || (expr1 -> type == nil_e && expr2 -> type == newtable_e)){ if(op == IF_EQ){ result = newexpr(boolexpr_e); result -> sym = newtemp(); // emit(op, expr1, expr2, NULL, nextquadlabel()+3, yylineno); emit(ASSIGN, newexpr_constbool(0), NULL, result, 0, yylineno); // emit(JUMP, NULL, NULL, NULL, nextquadlabel()+2, yylineno); // emit(ASSIGN, newexpr_constbool(1), NULL, result, 0, yylineno); }else{ result = newexpr(boolexpr_e); result -> sym = newtemp(); // emit(op, expr1, expr2, NULL, nextquadlabel()+3, yylineno); // emit(ASSIGN, newexpr_constbool(0), NULL, result, 0, yylineno); // emit(JUMP, NULL, NULL, NULL, nextquadlabel()+2, yylineno); emit(ASSIGN, newexpr_constbool(1), NULL, result, 0, yylineno); } return result; } return NULL; }
expr* logical_expr(listNode* truelist, listNode* falselist, expr* result){ result = newexpr(boolexpr_e); result -> sym = newtemp(); patchlabel(-1, nextquadlabel(), truelist); patchlabel(-1, nextquadlabel()+2, falselist); emit(ASSIGN, newexpr_constbool(1), NULL, result, 0, yylineno); emit(JUMP, NULL, NULL, NULL, nextquadlabel()+2, yylineno); emit(ASSIGN, newexpr_constbool(0), NULL, result, 0, yylineno); return result; }
expr* make_call(expr* lvalue,expr* elist){ expr* func=emit_iftableitem(lvalue); if(elist!=NULL){ expr* temp=elist->first; while(temp!=NULL){ emit(PARAM,temp,NULL,NULL,-1,yylineno); temp=temp->next; } } emit(CALL,func,NULL,NULL,-1,yylineno); expr* result=newexpr(VAR_E); result->sym=newtemp(); emit(GETRETVAL,result,NULL,NULL,-1,yylineno); return result; }
expr* emit_iftableitem(expr* e){ if (e->type != tableitem_e) return e; else { expr* result = newexpr(var_e); result->sym = newtemp(); emit( TABLEGETELEM, e, e->index, result, 0, yylineno ); return result; } }
expr* newexpr_constnum(double i){ expr* e=newexpr(CONSTNUM_E); e->numConst=i; return e; }
expr* newexpr_constbool(const char* b){ expr *e; e=(expr*)newexpr(CONSTSTRING_E); e->boolConst= strdup(b); return e; }
expr* newexpr_conststring(char *s){ expr *e; e=(expr*)newexpr(CONSTSTRING_E); e->strConst=strdup(s); return e; }
expr* newexpr_conststring (char* s){ expr* e = newexpr(conststring_e); e->strConst = strdup(s); return e; }
expr* newexpr_nil(){ expr *e; e=(expr*)newexpr(NIL_E); e->strConst= strdup("nil"); return e; }
expr* newexpr_constnum (double i){ expr* e = newexpr(constnum_e); e->numConst=i; return e; }
expr* newexpr_constbool(unsigned char i){ expr* e = newexpr(constbool_e); e->boolConst = i; return e; }