virtual void asyncupdateRoutine(float32 dt) { if(getState()==State_Active) { if(IRoutine *routine = getRoutine()) { routine->asyncupdate(dt); } } }
data eval_routine(routineNode rout, symrec ** symTable, list * routineList){ data res; //recupera la routine e controlla se esiste routine * r = getRoutine(rout.name, routineList); if(r==NULL){ yyerror("accessing unexisting procedure or function.."); exit(NO_SUCH_PROCEDURE); } //dalla routine prendi gli i parametri form * forms; forms = r->parameters; //dal nodo passato prendi gli argomenti actual * aes; aes = rout.args; //HERE HAPPENS typechecking //we do minimal typechecking on length - the rest is left as exercise int flen = formLength(forms); int alen = actLength(aes); if(flen!=alen){ yyerror("args len is different from formal length"); } //qui fai il bind tra parametri e argomenti, mettendoli nella symbol TABLE // da ripassare a tutta la funzione di eval, usando il nodo expr come funzione di partenza symrec * rSymrec; rSymrec = NULL; for(int i = 0; i< flen; i++){ form * f = getFormAtIndex(i,forms); if(f == NULL){ //TODO place here the number of forms already used yyerror("execeed form list"); exit(FORM_LIST_EXCEEDED); } actual * a = getActualAtIndex(i,aes); if (a == NULL){ //TODO place here the number of args already used yyerror("execeed args list"); exit(ARGS_LIST_EXCEEDED); } //eseguo dichiarazione e assegnazione nella symbol table che userà la routine type * t = basicDec(f->bt); //TODO: considered only basic type treeNode * dec = varDec(f->name,false,t); eval_identifier_declaration(dec->value.dec,&rSymrec,routineList); //cerca la var appena inserita e fai l'assignement identifier id; id.name = malloc(strlen(f->name)+1); strcpy(id.name,f->name); if (f->byref){ if (a->expr->type != identifier_type){ yyerror("incompatible arg for pass by ref"); exit(ARGS_LIST_EXCEEDED); } symrec * tmp = getSymbolFromIdentifier(id,&rSymrec); symrec * tmp2 = getSymbolFromIdentifier(a->expr->value.id, symTable); tmp->value = tmp2->value; } else { //eval expr in current env, then assign it symrec * tmp = getSymbolFromIdentifier(id,&rSymrec); data e = eval(a->expr, symTable,routineList); spec_assignment(tmp,e, &rSymrec, routineList); } // printf("%s", ); } //eventually with return res = eval... eval(r->statementList, &rSymrec,routineList); if(r->type == procedure){ res.type = no_op; }else{ //qui cerca nella routine, nel suo return value il valore, puliscilo e resituicilo res = *r->returnValue; r->returnValue = NULL; } return res; }
data eval_expr(node expr, symrec ** symTable,list * routineList){ data res; switch (expr.operator) { case SEMICOLON: { //c'è sempre uno statement da valutare //valuto il primo eval(expr.op[0],symTable,routineList); if(expr.noperands>1){ //valuto il secondo, non è possibile per la struttura del parser averne più di due return eval(expr.op[1], symTable, routineList); } } break; case PRINT: { //statement data e = eval(expr.op[0], symTable,routineList); printData(e); res.type = no_op; return res; } break; case EQUALS: //statement { symrec * s = getSymbolFromIdentifier(expr.op[0]->value.id,symTable); //check if the variable is function routine * r = getRoutine(expr.op[0]->value.id.name, routineList); if(s == NULL && r == NULL){ yyerror("during assignment found unknown variable or function"); exit(NO_SUCH_VARIABLE); } //else data res; if(s!=NULL){ res = assignment(s,expr.op[1],symTable,routineList); } if(r!=NULL){ //TODO check if this is a function or a procedure res = r_assignment(r,expr.op[1], symTable,routineList); } return res; } break; case WHILE: //statement { // in ro con ambiente delta valuto <while e to c, omega> --> c <c; while e do c, omega> solo se in ro con ambiente delta posso valutare e a boleano vedi pag 54 semantica opearzionale data bool_guard = eval(expr.op[0],symTable,routineList); //here typechecking for correct return type of bool_guard...must be boolean if(bool_guard.b.b == true){ eval(expr.op[1],symTable,routineList); //ho fatto il comando c, ora rimetto a valutazione la stessa operazione treeNode * newWhile = opr(WHILE,2,expr.op[0],expr.op[1]); eval(newWhile,symTable,routineList); //free(newWhile) } data res; res.type = no_op; return res; } break; case IF: //statement { data bool_guard = eval(expr.op[0],symTable,routineList); //here typechecking for correct return type of bool_guard...must be boolean if(bool_guard.b.b == true){ eval(expr.op[1],symTable,routineList); }else if(expr.noperands == 3){ //se c'è il branch else eval(expr.op[2],symTable,routineList); } data res; res.type = no_op; return res; } break; case FOR: //statement { symrec * s = getSymbolFromIdentifier(expr.op[0]->value.id,symTable); if(s == NULL){ yyerror("NO_SUCH_VARIABLE"); exit(NO_SUCH_VARIABLE); } assignment(s,expr.op[1],symTable,routineList); identifier index; index.name = malloc(strlen(s->name)+1); strcpy(index.name,s->name); data id = eval_identifier(index, symTable,routineList); //consider only LT data guard = eval(expr.op[2],symTable,routineList); data comparison = operation(LT, id,guard); //here happens typechecking if(comparison.b.b == true){ eval(expr.op[3],symTable,routineList); //incremento la variable, assume only integers treeNode * nextValue = constantNode(basic_int_value, id.b.i + 1); //assignment(s,nextValue,symTable); treeNode * newFor = opr(FOR,4,expr.op[0],nextValue,expr.op[2],expr.op[3]); eval(newFor,symTable,routineList); //free(newFor); //free(nextValue); } } break; case UMINUS: { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); return negate(e1); } case MINUS: { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(MINUS, e1,e2); } break; case PLUS : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(PLUS, e1,e2); } break; case MULTIPLY: { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(MULTIPLY, e1,e2); } break; case DIVIDE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(DIVIDE, e1,e2); } break; case LT : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(LT, e1,e2); } break; case GT : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(GT, e1,e2); } break; case GE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(GE, e1,e2); } break; case LE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(LE, e1,e2); } break; case NE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(NE, e1,e2); } break; case EQ : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(EQ, e1,e2); } break; default: yyerror("eval_expr new type not implemented"); exit(NOT_IMPLEMENTED_YET); break; } return res; }