void writecode_vtables(){ PCLASSE lc = definedClasses; while(lc){ int n = count_methods(lc->name); writecode("ALLOC "); writecodeiln(n); int written[n]; int i; for(i=0;i<n;i++) written[i]=0; PCLASSE lc2 = lc; while(lc2){ PMETH lm = lc2->lmethodes; while(lm){ int index = get_meth_index(lc->name,lm->name); if(!written[index]){ writecodeln("DUPN 1"); writecode("PUSHA "); writecodeln(lbl(lm->label)); writecode("STORE "); writecodeiln(index); written[index] = 1; } lm = lm->suiv; } lc2 = get_class(lc2->name_parent); } lc = lc->suiv; } }
void lcdaddr(uchar DDRAM) { if (DDRAM<=16) { writecode(0x80+DDRAM-1); } else { writecode(0x80+DDRAM+0x2f); } }
void writecode_class( PCLASSE cl ){ PMETH lm = cl->lmethodes; current_class_name = cl->name; parent_current_class_name = cl->name_parent; while(lm){ PATT m = lm->lparams; lm->lparams2 = NULL; PATT m2 = lm->lparams2; PATT prec = NULL; while(m){ m2 = NEW(1,ATTRIBUT); if( prec == NULL ) lm->lparams2 = m2; if( prec != NULL ) prec->suiv = m2; memcpy(m2,m,sizeof(ATTRIBUT)); m2->suiv = NULL; prec = m2; m2 = m2->suiv; m = m->suiv; } m = lm->lparams2; while(m){ m = m->suiv; } int label = newlbl(); writecode(lbl(label)); writecodeln(":NOP"); current_method = lm; if(cl->lattributs){ AttributsEnvironnement = NEW(1,ATTRIBUT); memcpy(AttributsEnvironnement,cl->lattributs,sizeof(ATTRIBUT)); }else AttributsEnvironnement = NULL; PATT local_fin_env = enrichissement_att_environnement(cl->name_parent,lm->lparams); writecode_exp(lm->expression, local_fin_env ); desenrichissement_att_environnement(local_fin_env); lm->label = label; writecode("STOREL -"); int c = count_params(lm); writecodeiln(2+c); writecodeln("RETURN"); lm = lm->suiv; } current_class_name = NULL; parent_current_class_name = NULL; }
void writecode_exp(PARBRE arbre, PATT super_fin_env) { char * typeg = NULL; char * typed = NULL; PATT local_fin_env = NULL; char * id = arbre->gauche.S; if(arbre) switch (arbre->op) { case New : { writecodeln("--NEW"); int c=0; writecode("ALLOC "); PCLASSE lc = get_class(arbre->gauche.A->gauche.S); while(lc){ PATT att = lc->lattributs; while(att){ c++; att = att->suiv; } lc = get_class(lc->name_parent); } writecodeiln(1+c); writecodeln("DUPN 1"); writecode("PUSHG "); writecodeiln( (get_class(arbre->gauche.A->gauche.S))->index ); writecodeln("STORE 0"); writecodeln("--NEWEND"); } break; case Bloc : { writecodeln("--BLOC"); local_fin_env = enrichissement_att_environnement(NULL,arbre->droit.lattributs); //Allouer les variables PATT att = arbre->droit.lattributs; int c = 0; while(att){ c++; att = att->suiv; } writecode("PUSHN "); writecodeiln(c); writecode_exp( arbre->gauche.A, local_fin_env ); int i; for(i=0;i<c;i++){ writecodeln("SWAP"); writecodeln("POPN 1"); } desenrichissement_att_environnement(local_fin_env); writecodeln("--BLOCEND"); } break; case Self : writecodeln("PUSHL -1"); //return current_class_name; break; case Id : { int index = get_var_index( super_fin_env, id ); if( current_method == NULL ){ //Main writecode("PUSHL "); writecodeiln(index + count_classes(definedClasses)); }else{ if( index > -1 ){ writecode("PUSHL "); writecodeiln(index); }else{ int indexparam = index_param( current_method , id ); int n = count_params( current_method ); if( indexparam ){ writecode("PUSHL -"); writecodeiln( n + 2 - indexparam ); }else{ int indexatt = index_att( current_class_name , id ); if( indexatt >=0 ){ writecodeln("PUSHL -1"); writecode("LOAD "); writecodeiln(indexatt + 1); } } } } } break; case Fct :{ writecodeln("--APPEL"); writecodeln("PUSHN 1"); //Pour le retour de la fonction //Met self au dessus de la pile writecodeln("PUSHL -1"); PFONC f = arbre->gauche.F; PARG arg = f->largs; int c = 0; while(arg){ writecode_exp( arg->expression, super_fin_env ); writecodeln("SWAP"); c++; arg = arg->suiv; } writecodeln("DUPN 1"); writecodeln("LOAD 0"); writecode("LOAD "); writecodeiln( (get_meth_index( check_type(arbre->gauche.A , NULL, super_fin_env), f->name) ) ); writecodeln("CALL"); writecode("POPN "); writecodeiln( c + 1 ); //Dépile le destinataire et les paramètres writecodeln("--APPELEND"); } break; case Aff: { writecodeln("--AFF"); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("DUPN 1"); if( arbre->gauche.A->op == '.' ){ //C'est le champ d'un objet writecode_exp(arbre->gauche.A->gauche.A, super_fin_env); int indexatt = index_att( check_type( arbre->gauche.A->gauche.A, NULL, super_fin_env ) , arbre->gauche.A->droit.S ); writecodeln("SWAP"); writecode("STORE "); writecodeiln(indexatt + 2); }else { //C'est un id int index = get_var_index( super_fin_env, arbre->gauche.A->gauche.S ); if( current_method == NULL ){ //Main writecode("STOREL "); writecodeiln(index + count_classes(definedClasses)); }else{ if( index > -1 ){ writecode("STOREL "); writecodeiln(index); }else{ int indexparam = index_param( current_method , arbre->gauche.A->gauche.S ); if( indexparam ){ int n = count_params( current_method ); writecode("STOREL -"); writecodeiln( n + 2 - indexparam ); }else{ int indexatt = index_att( current_class_name , arbre->gauche.A->gauche.S ); if( indexatt >= 0 ){ writecodeln("PUSHL -1"); writecodeln("SWAP"); writecode("STORE "); writecodeiln(indexatt + 1); } } } } }writecodeln("--AFFEND"); } break; case ';': if( arbre->droit.A != NULL ){ writecode_exp( arbre->gauche.A, super_fin_env ); writecodeln("POPN 1"); writecode_exp( arbre->droit.A, super_fin_env ); } break; case '.' : { if( arbre->droit.A->op == Id ){ writecode_exp( arbre->gauche.A, super_fin_env ); int index = index_att( check_type( arbre->gauche.A, NULL, super_fin_env ) , arbre->droit.A->gauche.S ); writecode("LOAD "); writecodeiln(index + 2); }else if( arbre->droit.A->op == Fct ){ int imprimer = 0; PFONC f = arbre->droit.A->gauche.F; if( strcmp(f->name,"imprimer")==0 ){ if( strcmp(check_type( arbre->gauche.A, NULL, super_fin_env ),"Entier")==0 ){ writecode_exp( arbre->gauche.A, super_fin_env ); writecodeln("DUPN 1"); writecodeln("WRITEI"); imprimer=1; } if( strcmp(check_type( arbre->gauche.A, NULL, super_fin_env ),"Chaine")==0 ){ writecode_exp( arbre->gauche.A, super_fin_env ); writecodeln("DUPN 1"); writecodeln("WRITES"); imprimer=1; } } if( !imprimer && arbre->gauche.A->op == Super ){ writecodeln("--APPEL"); writecodeln("PUSHN 1"); //Pour le retour de la fonction PARG arg = f->largs; int c = 0; while(arg){ writecode_exp( arg->expression, super_fin_env ); c++; arg = arg->suiv; } writecodeln("PUSHL -1"); int index = get_class(parent_current_class_name)->index; writecode("PUSHG "); writecodeiln(index); writecode("LOAD "); writecodeiln( (get_meth_index( check_type(arbre->gauche.A, NULL ,super_fin_env), f->name) ) ); writecodeln("CALL"); writecode("POPN "); writecodeiln( c + 1 ); //Dépile le destinataire et les paramètres writecodeln("--APPELEND"); }else if(!imprimer){ writecodeln("--APPEL"); writecodeln("PUSHN 1"); //Pour le retour de la fonction writecode_exp( arbre->gauche.A, super_fin_env ); PFONC f = arbre->droit.A->gauche.F; PARG arg = f->largs; int c = 0; while(arg){ writecode_exp( arg->expression, super_fin_env ); writecodeln("SWAP"); c++; arg = arg->suiv; } writecodeln("DUPN 1"); writecodeln("LOAD 0"); writecode("LOAD "); writecodeiln( (get_meth_index( check_type(arbre->gauche.A, NULL, super_fin_env), f->name) ) ); writecodeln("CALL"); writecode("POPN "); writecodeiln( c + 1 ); //Dépile le destinataire et les paramètres writecodeln("--APPELEND"); } } } break; case Cste: writecode("PUSHI "); writecodeiln(arbre->gauche.E); break; case String: writecode("PUSHS "); writecodeln(arbre->gauche.S); break; case '+': writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("ADD"); break; case '-': writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("SUB"); break; case '*': writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("MUL"); break; case '/': writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("DIV"); break; case ITE : writecode_exp(arbre->gauche.A, super_fin_env); int lblelse = newlbl(); int lblend = newlbl(); writecode("JZ "); writecodeln(lbl(lblelse)); writecode_exp( arbre->droit.A->gauche.A, super_fin_env ); writecode("JUMP "); writecodeln(lbl(lblend)); writecode(lbl(lblelse)); writecodeln(": NOP"); writecode_exp( arbre->droit.A->droit.A, super_fin_env ); writecode(lbl(lblend)); writecodeln(": NOP"); break; case LT : writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("INF"); break; case LE : writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("INFEQ"); break; case GT : writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("SUP"); break; case GE : writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("SUPEQ"); break; case EQ : writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("EQUAL"); break; case NEQ : writecode_exp(arbre->gauche.A, super_fin_env); writecode_exp(arbre->droit.A, super_fin_env); writecodeln("EQUAL"); writecodeln("NOT"); break; } }