En cours de clean
This commit is contained in:
parent
afbc1461c4
commit
bbd3585d96
14 changed files with 543 additions and 1353 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,3 +9,4 @@ Tables/Fonctions/test
|
||||||
Lex_Yacc/as.output
|
Lex_Yacc/as.output
|
||||||
Lex_Yacc/as.tab.*
|
Lex_Yacc/as.tab.*
|
||||||
Lex_Yacc/lex.yy.*
|
Lex_Yacc/lex.yy.*
|
||||||
|
Lex_Yacc/as.dot
|
||||||
|
|
Binary file not shown.
|
@ -1,52 +0,0 @@
|
||||||
les fonctions (avec parametres)
|
|
||||||
le if
|
|
||||||
le while
|
|
||||||
les declarations
|
|
||||||
les affectations
|
|
||||||
les operations arith.
|
|
||||||
le retour de fonction
|
|
||||||
l'invocation de fonctions
|
|
||||||
|
|
||||||
|
|
||||||
C : Fonctions ;
|
|
||||||
Fonctions : Fonction Fonctions | Fonction ;
|
|
||||||
|
|
||||||
Fonction : tInt tID tPO Params tPF Body ;
|
|
||||||
|
|
||||||
Params : | Param SuiteParams ;
|
|
||||||
Param : tInt tID ;
|
|
||||||
|
|
||||||
SuiteParams : tVirgule Param SuiteParams | ;
|
|
||||||
|
|
||||||
// Ps : P Ps | ;
|
|
||||||
// P : tInt tID tVirgule
|
|
||||||
// Ps =>* tInt tID tVirgule tInt tID tVirgule
|
|
||||||
// Ps => P Ps => P P Ps ...
|
|
||||||
|
|
||||||
Body : tAO Instructions tAF ;
|
|
||||||
|
|
||||||
Instructions : Instruction Instructions | ;
|
|
||||||
|
|
||||||
Instruction : Aff | If | While | Return | Decl | Invocation tPV ;
|
|
||||||
|
|
||||||
Aff : tID tEQ E tPV ;
|
|
||||||
|
|
||||||
E : tNB | tID | E tADD E | E tMUL E | E tMINUS E | E tDIV E | Invocation | tPO E tPF | tMINUS E ;
|
|
||||||
|
|
||||||
// E : tID tADD tID | ...
|
|
||||||
|
|
||||||
If : tIF tPO Cond tPF Body ;
|
|
||||||
|
|
||||||
Cond : Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | tNOT Cond ;
|
|
||||||
|
|
||||||
Invocation : tID tPO Args tPF ;
|
|
||||||
|
|
||||||
Args : .... cf params
|
|
||||||
|
|
||||||
Return : tRET E tPV ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,17 +30,17 @@ Copie la valeur val à l'adresse @X
|
||||||
|
|
||||||
Copie la valeur contenue dans @C à l'adresse @X en considérant que ce qui est copié est une adresse (et donc il faut ajouter BP)
|
Copie la valeur contenue dans @C à l'adresse @X en considérant que ce qui est copié est une adresse (et donc il faut ajouter BP)
|
||||||
|
|
||||||
## AFCA @X addr
|
## AFCA @X val
|
||||||
|
|
||||||
Copie la valeur addr à l'adresse @X en considérant que ce qui est copié est une adresse (et donc il faut ajouter BP)
|
Copie la val à l'adresse @X en considérant que ce qui est copié est une adresse (et donc il faut ajouter BP)
|
||||||
|
|
||||||
## JMP lig
|
## JMP ins
|
||||||
|
|
||||||
Saute vers la ligne lig dans le code sans condition
|
Saute vers la ligne ins dans le code sans condition
|
||||||
|
|
||||||
## JMF @X lig
|
## JMF @X ins
|
||||||
|
|
||||||
Saute vers la ligne lig dans le code si la valeur à l'adresse @X est 0
|
Saute vers la ligne ins dans le code si la valeur à l'adresse @X est 0
|
||||||
|
|
||||||
## INF @X @A @B
|
## INF @X @A @B
|
||||||
|
|
||||||
|
@ -62,14 +62,15 @@ Va mettre à l'adresse @X ce qui est à l'addresse contenue à l'adresse @Y (on
|
||||||
|
|
||||||
Va mettre le contenu de @Y dans l'adresse qui est la valeur dans @X (on considère que @X est un pointeur et on écrit dans l'adresse qui est contenue dans @X). Attention, considérer des addresses globales (pas relatives).
|
Va mettre le contenu de @Y dans l'adresse qui est la valeur dans @X (on considère que @X est un pointeur et on écrit dans l'adresse qui est contenue dans @X). Attention, considérer des addresses globales (pas relatives).
|
||||||
|
|
||||||
##CALL lig taille_pile_fonction_appelante
|
##CALL ins taille_pile_fonction_appelante
|
||||||
|
|
||||||
|
Appelle la fonction dont la première ligne est ins et taille_pile_fonction_appelante est la taille de la zone mémoire utilisée par la fonction appelante (avant le push des arguments !)
|
||||||
|
|
||||||
Appelle la fonction dont la première ligne est lig et taille_pile_fonction_appelante est la taille de la zone mémoire utilisée par la fonction appelante (avant le push des args !)
|
|
||||||
##RET
|
##RET
|
||||||
|
|
||||||
Bouge BP et saute à l'adresse de retour (selon les valeur qui sont dans la pile de contrôle).
|
Restore BP et saute à l'adresse de retour (selon les valeur qui sont dans la pile de contrôle).
|
||||||
|
|
||||||
##STOP
|
##STOP val
|
||||||
|
|
||||||
Arrete le processeur (à mettre à la fin de l'ASM)
|
Arrete le processeur si val vaut 0 (à mettre à la fin de l'ASM), ou, arrete le processeur pour val tick d'horloge (si val > 0)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%{
|
%{ // Ne pas toucher
|
||||||
#include "as.tab.h"
|
#include "as.tab.h"
|
||||||
int yywrap(void){return 1;}
|
int yywrap(void){return 1;}
|
||||||
void
|
void
|
||||||
|
@ -11,44 +11,57 @@ yyerror (char const *s)
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
"main" { return tMAIN ;}
|
|
||||||
"{" { return tOBRACKET;}
|
"main" { return tMAIN; } // Token de la fonction main
|
||||||
"}" { return tCBRACKET; }
|
|
||||||
"(" { return tOBRACE; }
|
"{" { return tOBRACKET; } // Token accolade ouvrante
|
||||||
")" { return tCBRACE; }
|
"}" { return tCBRACKET; } // Token accolade fermante
|
||||||
"const" { return tCONST; }
|
"(" { return tOBRACE; } // Token parenthèse ouvrante
|
||||||
"int" { return tINT; }
|
")" { return tCBRACE; } // Token parenthèse fermante
|
||||||
"printf" { return tPRINTF; } //Degeu mais à degager
|
|
||||||
"if" { return tIF; }
|
"const" { return tCONST; } // Token constante
|
||||||
"while" { return tWHILE; }
|
"int" { return tINT; } // Token type int
|
||||||
"return" {return tRETURN; }
|
|
||||||
"<" { return tLT; }
|
"if" { return tIF; } // Token if
|
||||||
">" { return tGT; }
|
"else" { return tELSE; } // Token else
|
||||||
"==" { return tEQCOND; }
|
"while" { return tWHILE; } // Token while
|
||||||
"&&" { return tAND; }
|
|
||||||
"||" { return tOR; }
|
"return" {return tRETURN; } // Token return
|
||||||
"else" { return tELSE;}
|
|
||||||
"&" { return tADDR;}
|
"<" { return tLT; } // Token plus petit que
|
||||||
"[" { return tOCROCH;}
|
">" { return tGT; } // Token plus grand que
|
||||||
"]" { return tCCROCH;}
|
"==" { return tEQCOND; } // Token égal comparaison
|
||||||
"get" { return tGET;}
|
|
||||||
"stop" { return tSTOP;}
|
"&&" { return tAND; } // Token ET
|
||||||
|
"||" { return tOR; } // Token OU
|
||||||
|
|
||||||
|
"&" { return tADDR; } // Token adresse
|
||||||
|
"[" { return tOCROCH; } // Token crochet ouvrante
|
||||||
|
"]" { return tCCROCH; } // Token crochet ouvrante
|
||||||
|
|
||||||
|
"get" { return tGET; } // Token fonction get
|
||||||
|
"printf" { return tPRINTF; } // Token fonction print
|
||||||
|
"stop" { return tSTOP; } // Token fonction stop
|
||||||
|
|
||||||
|
"+" { return tADD; } // Token addition
|
||||||
|
"-" { return tSUB; } // Token soustraction
|
||||||
|
"*" { return tMUL; } // Token multiplication
|
||||||
|
"/" { return tDIV; } // Token division
|
||||||
|
|
||||||
|
"=" { return tEQ; } // Token egal affectation
|
||||||
|
|
||||||
|
";" { return tPV; }
|
||||||
|
"," { return tCOMA; }
|
||||||
|
|
||||||
|
[0-9]+ { yylval.nombre = atoi(yytext); return tNB; } // Token nombre au format classique
|
||||||
|
[0-9]+e[0-9]+ { yylval.nombre = -1; return tNB; } // Token nombre au format exponentiel
|
||||||
|
|
||||||
|
[a-zA-Z][a-zA-Z0-9_]* { strcpy(yylval.id, yytext); return tID; } // Chaine de caractère (identifiant variable, fonction..)
|
||||||
|
|
||||||
|
|
||||||
[0-9]+ { yylval.nombre = atoi(yytext); return tNB; }
|
" " {} //Ne pas les retourner à Yacc (espace)
|
||||||
[0-9]+e[0-9]+ { yylval.nombre = -1; return tNBEXP; } //Renvoyer le token tNB et pas tNBEXP
|
" " {} //Ne pas les retourner à Yacc (tabulation)
|
||||||
"+" { return tADD; }
|
"\n" {} //Ne pas les retourner à Yacc (retour chariot)
|
||||||
"-" { return tSUB; }
|
|
||||||
"*" { return tMUL; }
|
|
||||||
"/" { return tDIV; }
|
|
||||||
"=" { return tEQ; }
|
|
||||||
";" { return tPV; }
|
|
||||||
" " {} //Ne pas les retourner à Yacc
|
|
||||||
" " {} //Ne pas les retourner à Yacc
|
|
||||||
"," { return tCOMA; }
|
|
||||||
"\n" {} //Ne pas les retourner à Yacc
|
|
||||||
[a-zA-Z][a-zA-Z0-9_]* { strcpy(yylval.id, yytext); return tID; }
|
|
||||||
. { }//return tERROR; }
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
1048
Lex_Yacc/as.dot
1048
Lex_Yacc/as.dot
File diff suppressed because it is too large
Load diff
484
Lex_Yacc/as.y
484
Lex_Yacc/as.y
|
@ -14,12 +14,13 @@
|
||||||
struct type_t type_courant;
|
struct type_t type_courant;
|
||||||
struct type_t return_type_fonc;
|
struct type_t return_type_fonc;
|
||||||
|
|
||||||
|
// Tableau pour le management des patchs des JMP
|
||||||
int instructions_ligne_to_patch[10][20];
|
int instructions_ligne_to_patch[10][20];
|
||||||
int nbs_instructions_to_patch[10];
|
int nbs_instructions_to_patch[10];
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Récupération des tokens
|
||||||
%token tMAIN
|
%token tMAIN
|
||||||
%token tOBRACKET tCBRACKET
|
%token tOBRACKET tCBRACKET
|
||||||
%token<nombre> tOBRACE tCBRACE
|
%token<nombre> tOBRACE tCBRACE
|
||||||
|
@ -45,134 +46,411 @@ int nbs_instructions_to_patch[10];
|
||||||
%left tADD tSUB
|
%left tADD tSUB
|
||||||
%left tMUL tDIV
|
%left tMUL tDIV
|
||||||
|
|
||||||
%type<nombre> E DebutAff SuiteAffPointeur DebutAffPointeur EBis Invocation Args ArgSuite Arg SuiteParams Params Get
|
%type<nombre> E SuiteAffPointeur DebutAffPointeur EBis Invocation Args ArgSuite Arg SuiteParams Params Get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//%type<nombre> E
|
|
||||||
|
|
||||||
/******************************************** FAIRE LA GENERATION DU CODE ASSEMBLEUR DANS UN TABLEAU AVEC UN FPRINTF *******************/
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/*********** Programme C *************/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Un programme C correspond a des focntion et un main, une fois que le programme est compilé, on ajoute le STOP et l'on exporte l'assembleur.
|
||||||
|
C : Fonctions Main {add_operation(STOP,0,0,0);
|
||||||
|
create_asm();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
C : Fonction Fonctions {add_operation(STOP,0,0,0); create_asm();};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/************ Fonctions **************/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Des fonctions sont une suite de fonctions (possiblement nulle)
|
||||||
Fonctions : Fonction Fonctions;
|
Fonctions : Fonction Fonctions;
|
||||||
Fonctions : ;
|
Fonctions : ;
|
||||||
|
|
||||||
Main : tINT {printf("Déclaration du main\n"); create_jump_to_main(get_current_index());} tMAIN tOBRACE Args tCBRACE Body { print(); } ;
|
|
||||||
|
|
||||||
Fonction : Type tID {return_type_fonc = type_courant; printf("Déclaration de la fonction %s\n", $2);} tOBRACE {inc_prof();} Args {decrement_prof(); push_fonction($2,return_type_fonc,get_current_index(), $6);} tCBRACE Body { print_fonctions(); add_operation(RET,0,0,0);} ;
|
|
||||||
Fonction : Main {print_fonctions();};
|
|
||||||
|
|
||||||
Get : tGET tOBRACE tCBRACE {int addr = push("0_TEMPORARY", 0, integer); add_operation(GET,addr,0,0); $$ = addr;};
|
|
||||||
|
|
||||||
Stop : tSTOP tOBRACE tNB tCBRACE {add_operation(STOP,$3,0,0);};
|
|
||||||
|
|
||||||
Return : tRETURN E tPV {add_operation(COP,0,$2,0); pop(); };
|
|
||||||
|
|
||||||
Args : Arg ArgSuite {$$ = $1 + $2; printf("Les arguments de la fonctions vont avoir une taille dans la pile de : %d\n",$$);};
|
|
||||||
Args : {$$ = 0;};
|
|
||||||
Arg : Type tID {int addr = push($2,1, type_courant); if (type_courant.pointeur_level > 0){$$ = taille_types[INT];} else{$$ = taille_types[type_courant.base];}};
|
|
||||||
Arg : Type tID tOCROCH tCCROCH {type_courant.isTab = 2; int addr = push($2,1, type_courant); $$ = taille_types[INT];};
|
|
||||||
ArgSuite : tCOMA Arg ArgSuite {$$ = $2 + $3;} ;
|
|
||||||
ArgSuite : {$$ = 0;};
|
|
||||||
|
|
||||||
|
|
||||||
Body : tOBRACKET {inc_prof();} Instructions tCBRACKET {print(); reset_prof();};
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/************** Main *****************/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Le main, renvoi un int, possède le mot clé main, des arguments et un body
|
||||||
|
// Dès que le main est reconnu (token main) on met en place le JMP
|
||||||
|
Main : tINT tMAIN {printf("Déclaration du main\n");
|
||||||
|
create_jump_to_main(get_current_index());
|
||||||
|
}
|
||||||
|
tOBRACE Args tCBRACE Body;
|
||||||
|
|
||||||
|
|
||||||
|
// Une fonction possède un Type , un identifiant
|
||||||
|
Fonction : Type tID {return_type_fonc = type_courant; // On récupère le ype de la fonction
|
||||||
|
printf("Déclaration de la fonction %s\n", $2);
|
||||||
|
}
|
||||||
|
tOBRACE {inc_prof(); // On incrémente la profondeur pour les arguments, ils font parti de la fonction
|
||||||
|
}
|
||||||
|
Args {decrement_prof(); // Quand les arguments sont passés, on peur décrémenter la profondeur (sans effacer les variables)
|
||||||
|
push_fonction($2,return_type_fonc,get_current_index(), $6); // On enregistre la fonction dans la table des fonctions
|
||||||
|
}
|
||||||
|
tCBRACE Body {add_operation(RET,0,0,0); // On ajoute le RET
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get, une fonction particulière -> renvoi l'adresse de la valeur getée
|
||||||
|
Get : tGET tOBRACE tCBRACE {int addr = push("0_TEMPORARY", 0, integer); // On déclare la var temporelle
|
||||||
|
add_operation(GET,addr,0,0); // On ajoute le GET
|
||||||
|
$$ = addr; // On renvoi l'adresse
|
||||||
|
};
|
||||||
|
|
||||||
|
// Print, une fonction particulière
|
||||||
|
Print : tPRINTF tOBRACE E tCBRACE {add_operation(PRI,$3,0,0); // On ajoute l'instruction PRI
|
||||||
|
pop(); // On supprime la variable temporaire
|
||||||
|
};
|
||||||
|
|
||||||
|
// Stop, une fonction particulière
|
||||||
|
Stop : tSTOP tOBRACE tNB tCBRACE {add_operation(STOP,$3,0,0); // On ajoute juste l'instruction stop
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return, etape clé d'une fonction
|
||||||
|
Return : tRETURN E tPV {add_operation(COP,0,$2,0); // On copie la valeur retournée à l'adresse 0 de la frame
|
||||||
|
pop(); // On pop la variable temporaire
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/************ Arguments **************/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Les arguments : Args, Arg, ArgSuite renvoient la taille dans la pile des arguments déjà reconnus
|
||||||
|
// Des argmuments correspondent à : un argument, puis la suite d'arguments
|
||||||
|
Args : Arg ArgSuite {$$ = $1 + $2; // La taille des arguments est la taille du premier argument plus celle des suivants
|
||||||
|
};
|
||||||
|
Args : {$$ = 0; // Il peut ne pas y avoir d'arguments, alors la taille est 0
|
||||||
|
};
|
||||||
|
// Un argument possède un type et un identifiant (nom)
|
||||||
|
Arg : Type tID { int addr = push($2,1, type_courant); // On stocke l'argument dans la pile des symboles
|
||||||
|
if (type_courant.pointeur_level > 0) {
|
||||||
|
$$ = taille_types[ADDR];
|
||||||
|
} else {
|
||||||
|
$$ = taille_types[type_courant.base];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Un argument peut aussi être un tableau (argument classique et crochets) il est considéré comme un pointeur
|
||||||
|
Arg : Type tID tOCROCH tCCROCH {type_courant.pointeur_level++; // Considéré comme un simple pointeur
|
||||||
|
int addr = push($2,1, type_courant);
|
||||||
|
$$ = taille_types[ADDR];
|
||||||
|
};
|
||||||
|
// La suite d'un argument, une virgule, un argument, et d'autres arguments
|
||||||
|
ArgSuite : tCOMA Arg ArgSuite {$$ = $2 + $3;
|
||||||
|
};
|
||||||
|
// Cela peut être aucun arguments
|
||||||
|
ArgSuite : {$$ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/*************** Body ****************/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Un body n'est rien d'autre qu'une suite d'instructions entre deux accolades
|
||||||
|
Body : tOBRACKET {inc_prof(); // Lors de l'ouverture de l'accolade la profondeur augmente
|
||||||
|
}
|
||||||
|
Instructions tCBRACKET {reset_prof(); // A la sortie d'un body, on détruit toutes les variables locales de ce body
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/*********** Instructions ************/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Des instructions sont une instruction suivie d'autres instructions, ou, rien
|
||||||
Instructions : Instruction Instructions ;
|
Instructions : Instruction Instructions ;
|
||||||
Instructions : ;
|
Instructions : ;
|
||||||
Instruction : Aff {};
|
|
||||||
Instruction : Decl {};
|
|
||||||
Instruction : Invocation tPV{pop();};
|
|
||||||
Instruction : If {};
|
|
||||||
Instruction : While {};
|
|
||||||
Instruction : Return {};
|
|
||||||
Instruction : Stop tPV {};
|
|
||||||
|
|
||||||
|
// Un instruction peut être : une affectation, une déclaration, une invocation, un if, un while, un return, une fonction particulière
|
||||||
Invocation : tID tOBRACE {struct fonction_t fonc = get_fonction($1);}
|
Instruction : Aff;
|
||||||
Params tCBRACE {struct fonction_t fonc = get_fonction($1); multiple_pop($4);
|
Instruction : Decl;
|
||||||
add_operation(CALL,fonc.first_instruction_line, get_last_addr(),0); if (fonc.return_type.pointeur_level > 0 || fonc.return_type.isTab){
|
Instruction : Invocation tPV {pop();};
|
||||||
$$ = push("0_TEMPORARY_RETURN", 0, integer);
|
Instruction : If;
|
||||||
}
|
Instruction : While;
|
||||||
else{
|
Instruction : Return;
|
||||||
$$ = push("0_TEMPORARY_RETURN", 0, fonc.return_type);
|
Instruction : Stop tPV;
|
||||||
}};
|
Instruction : Print tPV;
|
||||||
|
|
||||||
Invocation : tPRINTF tOBRACE E tCBRACE{add_operation(PRI,$3,0,0);};
|
|
||||||
|
|
||||||
Params : {$$ = 0; printf("Sans Params\n"); } ;
|
|
||||||
Params : Param SuiteParams {$$ = $2 + 1;};
|
|
||||||
Param : E {printf("Parametre : %d\n", $1);};
|
|
||||||
SuiteParams : tCOMA Param SuiteParams {$$ = $3 + 1;};
|
|
||||||
SuiteParams : {$$ = 0;};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//On considère que la première ligne du code en ASM est la ligne 0
|
|
||||||
If : tIF tOBRACE E tCBRACE {
|
|
||||||
add_operation(JMF,$3,0,0); $1 = get_current_index() - 1;}
|
|
||||||
Body {int current = get_current_index();
|
|
||||||
patch($1,current + 1);
|
|
||||||
add_operation(JMP,0,0,0);
|
|
||||||
instructions_ligne_to_patch[get_prof()][nbs_instructions_to_patch[get_prof()]] = current;
|
|
||||||
nbs_instructions_to_patch[get_prof()]++;
|
|
||||||
pop();}
|
|
||||||
Else {printf("If reconnu\n");};
|
|
||||||
|
|
||||||
|
|
||||||
Else : tELSE If { printf("Else if reconnu\n"); };
|
/*************************************/
|
||||||
Else : tELSE Body { printf("Else reconnu\n"); int current = get_current_index();
|
/*************************************/
|
||||||
for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++){
|
/************ Invocation *************/
|
||||||
patch(instructions_ligne_to_patch[get_prof()][i],current);
|
/*************************************/
|
||||||
}
|
/*************************************/
|
||||||
nbs_instructions_to_patch[get_prof()] = 0;
|
|
||||||
};
|
|
||||||
Else : {int current = get_current_index();
|
|
||||||
for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++){
|
|
||||||
patch(instructions_ligne_to_patch[get_prof()][i],current);
|
|
||||||
}
|
|
||||||
nbs_instructions_to_patch[get_prof()] = 0;};
|
|
||||||
While : tWHILE tOBRACE E tCBRACE {
|
|
||||||
add_operation(JMF,$3,0,0);
|
|
||||||
$1 = get_current_index() - 1;
|
|
||||||
pop();}
|
|
||||||
|
|
||||||
Body { printf("While reconnu\n");
|
Invocation : tID tOBRACE Params tCBRACE {struct fonction_t fonc = get_fonction($1); // On récupère la fonction
|
||||||
int current = get_current_index();
|
multiple_pop($3); // On pop les paramètres de la table des symboles
|
||||||
patch($1,current + 1);
|
add_operation(CALL,fonc.first_instruction_line, get_last_addr(),0); // On écrit le CALL
|
||||||
add_operation(JMP,$1,0,0);};
|
// On renvoi l'adresse de la valeur retour de la fonction
|
||||||
|
if (fonc.return_type.pointeur_level > 0 || fonc.return_type.isTab) {
|
||||||
|
$$ = push("0_TEMPORARY_RETURN", 0, pointer);
|
||||||
|
} else {
|
||||||
|
$$ = push("0_TEMPORARY_RETURN", 0, fonc.return_type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Aff : DebutAff tEQ E tPV {add_operation(COP, $1, $3,0); pop();} ;
|
|
||||||
Aff : DebutAffPointeur tEQ E tPV {add_operation(WR,$1,$3,0); pop(); pop();};
|
|
||||||
|
|
||||||
DebutAff : tID {struct symbole_t * symbole = get_variable($1); symbole->initialized = 1; $$=symbole->adresse; printf("%s prend une valeur\n", $1);};
|
|
||||||
|
|
||||||
DebutAffPointeur : tMUL SuiteAffPointeur {add_operation(READ, $2, $2, 0); $$=$2;};
|
|
||||||
DebutAffPointeur : SuiteAffPointeur {$$=$1;};
|
|
||||||
SuiteAffPointeur : tMUL tID {struct symbole_t * symbole = get_variable($2); int addr = push("0_TEMPORARY", 1, symbole->type); add_operation(COP, addr,symbole->adresse,0); $$=addr;};
|
|
||||||
SuiteAffPointeur : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); int addr = push("0_TEMPORARY", 1, symbole->type); if (symbole->type.isTab == 2){add_operation(COP, addr,symbole->adresse,0);} else{add_operation(AFCA, addr,symbole->adresse,0);} int addr2 = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr2, taille_types[symbole->type.base],0); add_operation(MUL,$3,addr2,$3); add_operation(ADD,$3,addr,$3); $$=$3; pop(); pop();};
|
|
||||||
|
|
||||||
|
|
||||||
E : tNB { int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,$1,0); $$ = addr;};
|
|
||||||
E : tNBEXP { printf("Nombre exp\n"); int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,$1,0); $$ = addr;};
|
/*************************************/
|
||||||
E : E tMUL E { printf("Mul\n"); add_operation(MUL,$1,$1,$3); $$ = $1; pop();};
|
/*************************************/
|
||||||
E : E tDIV E { printf("Div\n"); add_operation(DIV, $1,$1,$3); $$ = $1; pop();};
|
/************ Paramètres *************/
|
||||||
E : E tSUB E { printf("Sub\n"); add_operation(SOU,$1,$1,$3); $$ = $1; pop();};
|
/*************************************/
|
||||||
E : E tADD E { printf("Add\n"); add_operation(ADD,$1,$1,$3); $$ = $1; pop();};
|
/*************************************/
|
||||||
E : Invocation {$$ = $1;};
|
|
||||||
E : tOBRACE E tCBRACE { printf("Parentheses\n"); $$=$2;};
|
// Ici aussi, 0, 1 ou plusieurs paramètres avec une suite paramètre pour prendre en compte la virgule, on renvoi le nombre de paramètres
|
||||||
E : tSUB E { printf("Moins\n"); int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,0,0); add_operation(SOU, $2,$2,addr); $$ = $2; pop();};
|
Params : {$$ = 0;
|
||||||
E : E tEQCOND E { printf("==\n"); add_operation(EQU,$1,$1,$3); $$ = $1; pop();};
|
};
|
||||||
E : E tGT E { printf(">\n"); add_operation(SUP,$1,$1,$3); $$ = $1; pop();};
|
Params : Param SuiteParams {$$ = $2 + 1;
|
||||||
E : E tLT E { printf("<\n"); add_operation(INF,$1,$1,$3); $$ = $1; pop();};
|
};
|
||||||
E : tNOT E { printf("!\n"); };
|
Param : E
|
||||||
|
SuiteParams : tCOMA Param SuiteParams {$$ = $3 + 1;};
|
||||||
|
SuiteParams : {$$ = 0;};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/******** Sauts conditionnels ********/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Un if : le token, une expression entre parenthèse suivie d'un body et d'un else
|
||||||
|
If : tIF tOBRACE E tCBRACE {add_operation(JMF,$3,0,0); // On ajoute le JMF sans préciser la ligne du saut
|
||||||
|
$1 = get_current_index() - 1; // On stocke le numéro d'instruction à patcher
|
||||||
|
}
|
||||||
|
Body {int current = get_current_index(); // On récupère le numéro d'instrcution
|
||||||
|
patch($1,current + 1); // On patch le Jump en cas d'instruction fausse
|
||||||
|
add_operation(JMP,0,0,0); // JMP pour skip le else si on devait faire le body
|
||||||
|
instructions_ligne_to_patch[get_prof()][nbs_instructions_to_patch[get_prof()]] = current; // On spécifie que le JMP est a patcher
|
||||||
|
nbs_instructions_to_patch[get_prof()]++;
|
||||||
|
pop(); // On pop la condition du if
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
|
||||||
|
// Elsif
|
||||||
|
Else : tELSE If;
|
||||||
|
|
||||||
|
// Else
|
||||||
|
Else : tELSE Body {int current = get_current_index();
|
||||||
|
for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++) {
|
||||||
|
patch(instructions_ligne_to_patch[get_prof()][i],current); // On patch après le else
|
||||||
|
}
|
||||||
|
nbs_instructions_to_patch[get_prof()] = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// If sans else
|
||||||
|
Else : {int current = get_current_index();
|
||||||
|
for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++){
|
||||||
|
patch(instructions_ligne_to_patch[get_prof()][i],current); // On patch après le else
|
||||||
|
}
|
||||||
|
nbs_instructions_to_patch[get_prof()] = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/************** Boucles **************/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
While : tWHILE tOBRACE E tCBRACE {add_operation(JMF,$3,0,0); // Ecriture du JMF
|
||||||
|
$1 = get_current_index() - 1; // Enregistrement de la ligne a patch
|
||||||
|
pop(); // Pop de la condition
|
||||||
|
}
|
||||||
|
Body {int current = get_current_index(); // Patch du JMF apres le body
|
||||||
|
patch($1,current + 1);
|
||||||
|
add_operation(JMP,$1,0,0); // JMP au debut de la boucle
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/************ Affectations ***********/ // A RETRAVAILLER
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Affectation simple
|
||||||
|
Aff : tID tEQ E tPV {struct symbole_t * symbole = get_variable($1); // On récupère le symbole
|
||||||
|
symbole->initialized = 1; // Le symbole devient initialisé
|
||||||
|
add_operation(COP, symbole->adresse, $3,0); // On affecte la valeur
|
||||||
|
pop(); // On pop l'expression
|
||||||
|
};
|
||||||
|
|
||||||
|
// Debut d'une affectation avec déreférencement de pointeur //////// A RETRAVAILLERRRRRR
|
||||||
|
DebutAffPointeur : tMUL SuiteAffPointeur {add_operation(READ, $2, $2, 0);
|
||||||
|
$$=$2;
|
||||||
|
};
|
||||||
|
|
||||||
|
DebutAffPointeur : SuiteAffPointeur {$$=$1;
|
||||||
|
};
|
||||||
|
|
||||||
|
SuiteAffPointeur : tMUL tID {struct symbole_t * symbole = get_variable($2);
|
||||||
|
int addr = push("0_TEMPORARY", 1, symbole->type);
|
||||||
|
add_operation(COP, addr,symbole->adresse,0);
|
||||||
|
$$=addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
SuiteAffPointeur : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1);
|
||||||
|
int addr = push("0_TEMPORARY", 1, symbole->type);
|
||||||
|
if (symbole->type.isTab == 2) {
|
||||||
|
add_operation(COP, addr,symbole->adresse,0);
|
||||||
|
} else {
|
||||||
|
add_operation(AFCA, addr,symbole->adresse,0);
|
||||||
|
}
|
||||||
|
int addr2 = push("0_TEMPORARY", 1, integer);
|
||||||
|
add_operation(AFC, addr2, taille_types[symbole->type.base],0);
|
||||||
|
add_operation(MUL,$3,addr2,$3);
|
||||||
|
add_operation(ADD,$3,addr,$3);
|
||||||
|
$$=$3;
|
||||||
|
pop();
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Affectation sur un pointeur
|
||||||
|
Aff : DebutAffPointeur tEQ E tPV {add_operation(WR,$1,$3,0);
|
||||||
|
pop();
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
/***** Expressions Arithmetiques *****/
|
||||||
|
/*************************************/
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
// Pour une expression arithmétique, nous renvoyons toujours l'adresse du resultat
|
||||||
|
|
||||||
|
// Un simple nombre
|
||||||
|
E : tNB {int addr = push("0_TEMPORARY", 1, integer); // On reserve la place de la variable temporaire
|
||||||
|
add_operation(AFC, addr,$1,0); // On Affecte la valeur a cette adresse
|
||||||
|
$$ = addr; // On renvoi l'adresse
|
||||||
|
};
|
||||||
|
|
||||||
|
// Un nombre sous forme XeY, même traitement qu'un nombre classique
|
||||||
|
E : tNBEXP {int addr = push("0_TEMPORARY", 1, integer);
|
||||||
|
add_operation(AFC, addr,$1,0);
|
||||||
|
$$ = addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Une Multiplication
|
||||||
|
E : E tMUL E {add_operation(MUL,$1,$1,$3); // On Multiplie les valeurs et stockons le résultat dans la première variable temporaire
|
||||||
|
$$ = $1; // On renvoi l'adresse du resultat
|
||||||
|
pop(); // On libère la seconde variable temporaire
|
||||||
|
};
|
||||||
|
|
||||||
|
// Une Division (idem multiplication)
|
||||||
|
E : E tDIV E {add_operation(DIV, $1,$1,$3);
|
||||||
|
$$ = $1;
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Une Soustraction (idem multiplication)
|
||||||
|
E : E tSUB E {add_operation(SOU,$1,$1,$3);
|
||||||
|
$$ = $1;
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Une Addition (idem multiplication)
|
||||||
|
E : E tADD E {add_operation(ADD,$1,$1,$3);
|
||||||
|
$$ = $1;
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Une invocation
|
||||||
|
E : Invocation {$$ = $1; // Une invocation renvoi déjà l'adresse, cette règle n'est qu'un cast d'Invocation en E
|
||||||
|
};
|
||||||
|
|
||||||
|
// Consomation de parenthèses
|
||||||
|
E : tOBRACE E tCBRACE {$$ = $2; // Cela permet de garantir la prioricité des expressions entre parenthèse
|
||||||
|
};
|
||||||
|
|
||||||
|
// Négatif --> -E <=> 0-E
|
||||||
|
E : tSUB E {int addr = push("0_TEMPORARY", 1, integer); // On réserve la variable temporaire pour le 0
|
||||||
|
add_operation(AFC, addr,0,0); // On affecte le 0
|
||||||
|
add_operation(SOU, $2, addr, $2); // On applique le 0-E
|
||||||
|
$$ = $2; // On renvoi l'adresse
|
||||||
|
pop(); // On libère la mémoire temporaire utilisée par 0
|
||||||
|
};
|
||||||
|
|
||||||
|
E : E tEQCOND E {add_operation(EQU,$1,$1,$3);
|
||||||
|
$$ = $1;
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
E : E tGT E {add_operation(SUP,$1,$1,$3);
|
||||||
|
$$ = $1;
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
E : E tLT E {add_operation(INF,$1,$1,$3);
|
||||||
|
$$ = $1;
|
||||||
|
pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
E : tNOT E { printf("!\n"); };
|
||||||
|
|
||||||
E : E tAND E {add_operation(MUL,$1,$1,$3); $$ = $1; pop();};
|
E : E tAND E {add_operation(MUL,$1,$1,$3); $$ = $1; pop();};
|
||||||
E : E tOR E {add_operation(ADD,$1,$1,$3); $$ = $1; pop();} ;
|
E : E tOR E {add_operation(ADD,$1,$1,$3); $$ = $1; pop();} ;
|
||||||
E : tMUL E { add_operation(READ, $2, $2, 0); $$=$2;};
|
E : tMUL E { add_operation(READ, $2, $2, 0); $$=$2;};
|
||||||
|
|
25
Makefile
25
Makefile
|
@ -1,6 +1,11 @@
|
||||||
default :
|
default :
|
||||||
@echo "Spécifiez une cible"
|
@echo "Spécifiez une cible"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################
|
||||||
|
### NETTOYAGE ###
|
||||||
|
###########################
|
||||||
clean : clean_Symboles clean_Instructions clean_Lex_Yacc clean_Fonctions
|
clean : clean_Symboles clean_Instructions clean_Lex_Yacc clean_Fonctions
|
||||||
@rm -f rondoudou_gcc
|
@rm -f rondoudou_gcc
|
||||||
@rm -f output.txt
|
@rm -f output.txt
|
||||||
|
@ -20,6 +25,11 @@ clean_Fonctions:
|
||||||
clean_Lex_Yacc:
|
clean_Lex_Yacc:
|
||||||
@rm -f Lex_Yacc/as.output Lex_Yacc/as.tab.* Lex_Yacc/lex.yy.*
|
@rm -f Lex_Yacc/as.output Lex_Yacc/as.tab.* Lex_Yacc/lex.yy.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################
|
||||||
|
### COMPILATION ###
|
||||||
|
###########################
|
||||||
build : clean build_Symboles build_Instructions build_Lex_Yacc build_Fonctions
|
build : clean build_Symboles build_Instructions build_Lex_Yacc build_Fonctions
|
||||||
gcc Lex_Yacc/as.tab.o Lex_Yacc/lex.yy.o Tables/Instructions/tab_instruc.o Tables/Symboles/table_symboles.o Tables/Fonctions/tab_fonctions.o -ll -o rondoudou_gcc
|
gcc Lex_Yacc/as.tab.o Lex_Yacc/lex.yy.o Tables/Instructions/tab_instruc.o Tables/Symboles/table_symboles.o Tables/Fonctions/tab_fonctions.o -ll -o rondoudou_gcc
|
||||||
|
|
||||||
|
@ -38,6 +48,11 @@ build_Lex_Yacc: clean_Lex_Yacc
|
||||||
gcc -c Lex_Yacc/as.tab.c -o Lex_Yacc/as.tab.o
|
gcc -c Lex_Yacc/as.tab.c -o Lex_Yacc/as.tab.o
|
||||||
gcc -c Lex_Yacc/lex.yy.c -o Lex_Yacc/lex.yy.o
|
gcc -c Lex_Yacc/lex.yy.c -o Lex_Yacc/lex.yy.o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################
|
||||||
|
### TESTS ###
|
||||||
|
###########################
|
||||||
test_Symboles: build_Symboles
|
test_Symboles: build_Symboles
|
||||||
gcc -c Tables/Symboles/test.c -o Tables/Symboles/test.o
|
gcc -c Tables/Symboles/test.c -o Tables/Symboles/test.o
|
||||||
gcc Tables/Symboles/test.o Tables/Symboles/table_symboles.o -o Tables/Symboles/test
|
gcc Tables/Symboles/test.o Tables/Symboles/table_symboles.o -o Tables/Symboles/test
|
||||||
|
@ -48,9 +63,19 @@ test_Instructions: build_Instructions
|
||||||
gcc Tables/Instructions/test.o Tables/Instructions/tab_instruc.o -o Tables/Instructions/test
|
gcc Tables/Instructions/test.o Tables/Instructions/tab_instruc.o -o Tables/Instructions/test
|
||||||
Tables/Instructions/test
|
Tables/Instructions/test
|
||||||
|
|
||||||
|
test_Fonctions: build_Fonctions
|
||||||
|
gcc -c Tables/Fonctions/test.c -o Tables/Fonctions/test.o
|
||||||
|
gcc Tables/Fonctions/test.o Tables/Fonctions/tab_fonctions.o -o Tables/Fonctions/test
|
||||||
|
Tables/Fonctions/test
|
||||||
|
|
||||||
test: build
|
test: build
|
||||||
cat Fichiers_Tests/progC | ./rondoudou_gcc
|
cat Fichiers_Tests/progC | ./rondoudou_gcc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################
|
||||||
|
### EDITION ###
|
||||||
|
###########################
|
||||||
edit_Lex_Yacc:
|
edit_Lex_Yacc:
|
||||||
pluma Lex_Yacc/al.lex Lex_Yacc/as.y &
|
pluma Lex_Yacc/al.lex Lex_Yacc/as.y &
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
#include "tab_fonctions.h"
|
#include "tab_fonctions.h"
|
||||||
|
|
||||||
|
#define MAX_TAILLE_FONC 50
|
||||||
|
|
||||||
|
// Table des fonctions
|
||||||
struct fonction_t tab_fonctions[MAX_TAILLE_FONC];
|
struct fonction_t tab_fonctions[MAX_TAILLE_FONC];
|
||||||
|
// Index dispo dans la table
|
||||||
int indexTab = 0;
|
int indexTab = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Renvoi une fonction a partir de son nom
|
||||||
struct fonction_t get_fonction(char * name){
|
struct fonction_t get_fonction(char * name){
|
||||||
int not_found = 1;
|
int not_found = 1;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -18,6 +23,7 @@ struct fonction_t get_fonction(char * name){
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insere une fonction
|
||||||
void push_fonction(char * name, struct type_t type, int line, int taille_args){
|
void push_fonction(char * name, struct type_t type, int line, int taille_args){
|
||||||
if (indexTab < MAX_TAILLE_FONC){
|
if (indexTab < MAX_TAILLE_FONC){
|
||||||
struct fonction_t fonc;
|
struct fonction_t fonc;
|
||||||
|
@ -31,6 +37,7 @@ void push_fonction(char * name, struct type_t type, int line, int taille_args){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction d'affichage des fonctions connues
|
||||||
void print_fonctions(){
|
void print_fonctions(){
|
||||||
printf("Affichage table des fonctions\n");
|
printf("Affichage table des fonctions\n");
|
||||||
printf("\t Size : %d\n",indexTab);
|
printf("\t Size : %d\n",indexTab);
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define MAX_TAILLE_FONC 50
|
|
||||||
|
|
||||||
//Struct dans le tableau qui permet d'identifier une fonction
|
//Struct dans le tableau qui permet d'identifier une fonction
|
||||||
struct fonction_t {
|
struct fonction_t {
|
||||||
char * name;
|
char * name;
|
||||||
|
@ -17,10 +15,11 @@ struct fonction_t {
|
||||||
int taille_args;
|
int taille_args;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Renvoi les informations sur une fonction à partir de son nom
|
||||||
struct fonction_t get_fonction(char * name);
|
struct fonction_t get_fonction(char * name);
|
||||||
|
// Insere une fonction dans la table (déclare une fonction)
|
||||||
void push_fonction(char * name, struct type_t type, int line, int taille_args);
|
void push_fonction(char * name, struct type_t type, int line, int taille_args);
|
||||||
|
// Fonction d'affichage des fonctions connues
|
||||||
void print_fonctions();
|
void print_fonctions();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
#include "tab_instruc.h"
|
#include "tab_instruc.h"
|
||||||
|
#define MAXTAILLE 1024
|
||||||
|
|
||||||
|
// Structure représentant une opération
|
||||||
|
struct operation_t {
|
||||||
|
enum opcode_t opcode;
|
||||||
|
int arg1;
|
||||||
|
int arg2;
|
||||||
|
int arg3;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Index dans le tableau des instruction
|
||||||
int current_index = 1;
|
int current_index = 1;
|
||||||
|
// Tableau des instructions (programme en assembleur)
|
||||||
struct operation_t tab_op[MAXTAILLE];
|
struct operation_t tab_op[MAXTAILLE];
|
||||||
|
|
||||||
|
// Insertion d'une opération dans le tableau
|
||||||
void add_operation(enum opcode_t opcode, int arg1, int arg2, int arg3){
|
void add_operation(enum opcode_t opcode, int arg1, int arg2, int arg3){
|
||||||
if (current_index == MAXTAILLE){
|
if (current_index == MAXTAILLE){
|
||||||
printf("Taillemax tableau operations atteinte\n");
|
printf("Taillemax tableau operations atteinte\n");
|
||||||
|
@ -13,12 +26,13 @@ void add_operation(enum opcode_t opcode, int arg1, int arg2, int arg3){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Les fonctions étant compilées en premiers, la première instruction du programme doit être un JMP vers le main
|
||||||
void create_jump_to_main(int line){
|
void create_jump_to_main(int line){
|
||||||
struct operation_t new_op = {JMP,line, 0, 0};
|
struct operation_t new_op = {JMP,line, 0, 0};
|
||||||
tab_op[0] = new_op;
|
tab_op[0] = new_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction traduisant une opération en assembleur
|
||||||
char * get_asm_line_from_op(struct operation_t op){
|
char * get_asm_line_from_op(struct operation_t op){
|
||||||
char * buffer = malloc(sizeof(char)*200);
|
char * buffer = malloc(sizeof(char)*200);
|
||||||
switch (op.opcode){
|
switch (op.opcode){
|
||||||
|
@ -73,16 +87,17 @@ char * get_asm_line_from_op(struct operation_t op){
|
||||||
case (RET):
|
case (RET):
|
||||||
sprintf(buffer,"RET\n");
|
sprintf(buffer,"RET\n");
|
||||||
break;
|
break;
|
||||||
case (GET):
|
case (GET):
|
||||||
sprintf(buffer,"GET %d\n",op.arg1);
|
sprintf(buffer,"GET %d\n",op.arg1);
|
||||||
break;
|
break;
|
||||||
case (STOP):
|
case (STOP):
|
||||||
sprintf(buffer,"STOP %d\n", op.arg1);
|
sprintf(buffer,"STOP %d\n", op.arg1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Genere le code asm dans un fichier
|
||||||
void create_asm(){
|
void create_asm(){
|
||||||
FILE * output = fopen("output.txt","w");
|
FILE * output = fopen("output.txt","w");
|
||||||
for (int i = 0; i < current_index; i++){
|
for (int i = 0; i < current_index; i++){
|
||||||
|
@ -92,10 +107,11 @@ void create_asm(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Renvoi l'index courrant dans le tableau
|
||||||
int get_current_index(){return current_index;}
|
int get_current_index(){return current_index;}
|
||||||
|
|
||||||
|
|
||||||
|
// Permet de modifier un instruction à postériorie (pour les JMP)
|
||||||
void patch(int index, int arg){
|
void patch(int index, int arg){
|
||||||
if (tab_op[index].opcode == JMP){
|
if (tab_op[index].opcode == JMP){
|
||||||
tab_op[index].arg1 = arg;
|
tab_op[index].arg1 = arg;
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
#ifndef TAB_INST_H
|
#ifndef TAB_INST_H
|
||||||
#define TAB_INST_H
|
#define TAB_INST_H
|
||||||
|
|
||||||
#define MAXTAILLE 1024
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Liste de codes des instruction
|
||||||
enum opcode_t {ADD,MUL,SOU,DIV,COP,AFC,AFCA,JMP,JMF,INF,SUP,EQU,PRI,READ,WR,CALL,RET,GET,STOP};
|
enum opcode_t {ADD,MUL,SOU,DIV,COP,AFC,AFCA,JMP,JMF,INF,SUP,EQU,PRI,READ,WR,CALL,RET,GET,STOP};
|
||||||
|
|
||||||
struct operation_t {
|
|
||||||
enum opcode_t opcode;
|
|
||||||
int arg1;
|
|
||||||
int arg2;
|
|
||||||
int arg3;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Ajoute une opération dans la table (à la fin)
|
//Ajoute une opération dans la table (à la fin)
|
||||||
void add_operation(enum opcode_t opcode, int arg1, int arg2, int arg3);
|
void add_operation(enum opcode_t opcode, int arg1, int arg2, int arg3);
|
||||||
//Renvoi le prochain slot disponible
|
//Renvoi le prochain slot disponible
|
||||||
|
|
|
@ -1,55 +1,35 @@
|
||||||
/* TABLE DES SYMBOLE DU COMPILATEUR (PILE)
|
|
||||||
|
|
||||||
-----------------------------------------------------
|
|
||||||
| symbole | adresse | type | initialisé |
|
|
||||||
-----------------------------------------------------
|
|
||||||
| | | | |
|
|
||||||
| | | | |
|
|
||||||
| | | | |
|
|
||||||
| i | 0x777756b8 | int | false |
|
|
||||||
| size | 0x777756b8 | int | true |
|
|
||||||
-----------------------------------------------------
|
|
||||||
|
|
||||||
Types pour l'implémentation :
|
|
||||||
- enum type_t : [int]
|
|
||||||
- struct symbole : {
|
|
||||||
char nom[30];
|
|
||||||
uintptr_t adresse;
|
|
||||||
enum type_t type;
|
|
||||||
char initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
Opérations possible :
|
|
||||||
- init -> pile * -> void
|
|
||||||
- push -> symbole -> pile * -> void
|
|
||||||
- pop -> pile * -> symbole
|
|
||||||
- exist -> pile * -> symbole -> char
|
|
||||||
- initialized -> pile * -> symbole -> char */
|
|
||||||
|
|
||||||
#include "table_symboles.h"
|
#include "table_symboles.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#define MAXADDR 1024*5
|
|
||||||
|
|
||||||
|
// Première adresse disponible
|
||||||
int last_addr = 0;
|
int last_addr = 0;
|
||||||
int temp_addr = MAXADDR;
|
// Tableau indexé sur les types donnant leur tailles
|
||||||
int taille_types[] = {-1, 1};
|
int taille_types[] = {-1, 1, 1};
|
||||||
|
// Pronfondeur dans le code (pour la visibilité des variables)
|
||||||
int profondeur = 0;
|
int profondeur = 0;
|
||||||
int last_temp_var_size;
|
// Constante pour les entiers
|
||||||
const struct type_t integer = {INT, 0, 1};
|
const struct type_t integer = {INT, 0, 1, 0};
|
||||||
|
// Constante pour les pointeurs
|
||||||
|
const struct type_t pointer = {ADDR, 0, 1, 0};
|
||||||
|
|
||||||
|
// Structure chainant les symboles
|
||||||
struct element_t {
|
struct element_t {
|
||||||
struct symbole_t symbole;
|
struct symbole_t symbole;
|
||||||
struct element_t * suivant;
|
struct element_t * suivant;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Structure de la pile des symboles
|
||||||
struct pile_t {
|
struct pile_t {
|
||||||
int taille;
|
int taille;
|
||||||
struct element_t * first;
|
struct element_t * first;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Pile des symboles
|
||||||
struct pile_t * pile;
|
struct pile_t * pile;
|
||||||
|
|
||||||
|
// Fonction d'affichage pour un type
|
||||||
char * type_to_string(struct type_t type) {
|
char * type_to_string(struct type_t type) {
|
||||||
char * star = "*";
|
char * star = "*";
|
||||||
char * resultat = malloc(sizeof(char)*20);
|
char * resultat = malloc(sizeof(char)*20);
|
||||||
|
@ -64,6 +44,7 @@ char * type_to_string(struct type_t type) {
|
||||||
return resultat;
|
return resultat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction d'affichage pour un symbole
|
||||||
void print_symbole(struct symbole_t symbole) {
|
void print_symbole(struct symbole_t symbole) {
|
||||||
char * type = type_to_string(symbole.type);
|
char * type = type_to_string(symbole.type);
|
||||||
if (symbole.initialized) {
|
if (symbole.initialized) {
|
||||||
|
@ -74,14 +55,14 @@ void print_symbole(struct symbole_t symbole) {
|
||||||
free(type);
|
free(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialisation de la pile
|
||||||
void init (void) {
|
void init (void) {
|
||||||
pile = malloc(sizeof(struct pile_t));
|
pile = malloc(sizeof(struct pile_t));
|
||||||
pile->first = NULL;
|
pile->first = NULL;
|
||||||
pile->taille = 0;
|
pile->taille = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction d'ajout d'un symbole à la pile
|
||||||
|
|
||||||
int push(char * nom, int isInit, struct type_t type) {
|
int push(char * nom, int isInit, struct type_t type) {
|
||||||
struct element_t * aux = malloc(sizeof(struct element_t));
|
struct element_t * aux = malloc(sizeof(struct element_t));
|
||||||
struct symbole_t symbole = {"", last_addr, type, isInit,profondeur};
|
struct symbole_t symbole = {"", last_addr, type, isInit,profondeur};
|
||||||
|
@ -95,6 +76,7 @@ int push(char * nom, int isInit, struct type_t type) {
|
||||||
return addr_var;
|
return addr_var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction renvoyant et supprimant le premier symbole
|
||||||
struct symbole_t pop() {
|
struct symbole_t pop() {
|
||||||
struct symbole_t retour = {"", 0, UNKNOWN, 0, 0};
|
struct symbole_t retour = {"", 0, UNKNOWN, 0, 0};
|
||||||
struct element_t * aux;
|
struct element_t * aux;
|
||||||
|
@ -109,14 +91,14 @@ struct symbole_t pop() {
|
||||||
return retour;
|
return retour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction supprimant les n premiers symboles
|
||||||
|
|
||||||
void multiple_pop(int n){
|
void multiple_pop(int n){
|
||||||
for (int i =0; i<n; i++){
|
for (int i =0; i<n; i++){
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction d'accès a un symbole par son nom
|
||||||
struct symbole_t * get_variable(char * nom){
|
struct symbole_t * get_variable(char * nom){
|
||||||
struct symbole_t * retour = NULL;
|
struct symbole_t * retour = NULL;
|
||||||
struct element_t * aux = pile->first;
|
struct element_t * aux = pile->first;
|
||||||
|
@ -132,6 +114,7 @@ struct symbole_t * get_variable(char * nom){
|
||||||
return retour;
|
return retour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction d'affichage de la pile
|
||||||
void print() {
|
void print() {
|
||||||
printf("Affichage de la Table des Symboles\n\tSize : %d\n\tContenu : \n", pile->taille);
|
printf("Affichage de la Table des Symboles\n\tSize : %d\n\tContenu : \n", pile->taille);
|
||||||
struct element_t * aux = pile->first;
|
struct element_t * aux = pile->first;
|
||||||
|
@ -146,11 +129,17 @@ void print() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Getteur sur la première adresse dispo (utile pour le CALL)
|
||||||
int get_last_addr(){
|
int get_last_addr(){
|
||||||
return last_addr;
|
return last_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********************************/
|
||||||
|
/*** GESTION DE LA PROFONDEUR ***/
|
||||||
|
/********************************/
|
||||||
void inc_prof() {
|
void inc_prof() {
|
||||||
profondeur++;
|
profondeur++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,9 @@
|
||||||
/* TABLE DES SYMBOLE DU COMPILATEUR (PILE)
|
|
||||||
|
|
||||||
-----------------------------------------------------
|
|
||||||
| symbole | adresse | type | initialisé |
|
|
||||||
-----------------------------------------------------
|
|
||||||
| | | | |
|
|
||||||
| | | | |
|
|
||||||
| | | | |
|
|
||||||
| i | 0x777756b8 | int | false |
|
|
||||||
| size | 0x777756b8 | int | true |
|
|
||||||
-----------------------------------------------------
|
|
||||||
|
|
||||||
Types pour l'implémentation :
|
|
||||||
- enum type_t : [int]
|
|
||||||
- struct symbole : {
|
|
||||||
char nom[30];
|
|
||||||
uintptr_t adresse;
|
|
||||||
enum type_t type;
|
|
||||||
char initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
Opérations possible :
|
|
||||||
- init -> pile * -> void
|
|
||||||
- push -> symbole -> pile * -> void
|
|
||||||
- pop -> pile * -> symbole
|
|
||||||
- status -> nom -> pile -> char */
|
|
||||||
|
|
||||||
#ifndef TAB_SYMB_H
|
#ifndef TAB_SYMB_H
|
||||||
#define TAB_SYMB_H
|
#define TAB_SYMB_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************/
|
/**************************************/
|
||||||
/**************************************/
|
/**************************************/
|
||||||
/**** Gestion des types possibles ****/
|
/**** Gestion des types possibles ****/
|
||||||
|
@ -45,7 +11,7 @@ Opérations possible :
|
||||||
/**************************************/
|
/**************************************/
|
||||||
|
|
||||||
//Enumération des types de base reconnus
|
//Enumération des types de base reconnus
|
||||||
enum base_type_t {UNKNOWN, INT};
|
enum base_type_t {UNKNOWN, INT, ADDR};
|
||||||
//Table enregistrant la taille de ces types de bases (indexée sur les types)
|
//Table enregistrant la taille de ces types de bases (indexée sur les types)
|
||||||
extern int taille_types[];
|
extern int taille_types[];
|
||||||
//Structure gérant les types
|
//Structure gérant les types
|
||||||
|
@ -54,17 +20,18 @@ struct type_t {
|
||||||
enum base_type_t base;
|
enum base_type_t base;
|
||||||
//Si la variable est un pointeur, on enregitre son niveau (nombre de *)
|
//Si la variable est un pointeur, on enregitre son niveau (nombre de *)
|
||||||
int pointeur_level;
|
int pointeur_level;
|
||||||
//Si il s'agit d'un tableau, on enregistre sa taille (nombre de cases) (même si c'est une variable on met quand même un nb_blocs à)
|
//Si il s'agit d'un tableau, on enregistre sa taille (nombre de cases) (même si c'est une variable on met quand même un nb_blocs à 1)
|
||||||
int nb_blocs;
|
int nb_blocs;
|
||||||
//Si c'est un tableau addressale directement, cette valeur est à 1. Si c'est un pointeur vers un tableau, valeur à 2.
|
//Si c'est un tableau cette valeur est à 1, 0 sinon.
|
||||||
int isTab;
|
int isTab;
|
||||||
};
|
};
|
||||||
|
|
||||||
//REtourne la représentation d'un type en string
|
//Retourne la représentation d'un type en string
|
||||||
char * type_to_string(struct type_t type);
|
char * type_to_string(struct type_t type);
|
||||||
//Constante pour les entiers
|
//Constante pour les entiers
|
||||||
extern const struct type_t integer;
|
extern const struct type_t integer;
|
||||||
|
//Constante pour les pointeurs
|
||||||
|
extern const struct type_t pointer;
|
||||||
|
|
||||||
|
|
||||||
/**************************************/
|
/**************************************/
|
||||||
|
@ -100,7 +67,7 @@ struct symbole_t {
|
||||||
//Est il initialisé
|
//Est il initialisé
|
||||||
int initialized;
|
int initialized;
|
||||||
//Sa profondeur de création
|
//Sa profondeur de création
|
||||||
int profondeur;
|
int profondeur;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Fonction d'affichage d'un symbole
|
//Fonction d'affichage d'un symbole
|
||||||
|
@ -124,7 +91,7 @@ void init(void);
|
||||||
int push(char * nom, int isInit, struct type_t type);
|
int push(char * nom, int isInit, struct type_t type);
|
||||||
//Destruction et récupération du premier élément de la table
|
//Destruction et récupération du premier élément de la table
|
||||||
struct symbole_t pop();
|
struct symbole_t pop();
|
||||||
//Destruction des n premiers elee=ments de la table des symboles
|
//Destruction des n premiers elements de la table des symboles
|
||||||
void multiple_pop(int n);
|
void multiple_pop(int n);
|
||||||
//Retourne la dernière adresse disponible
|
//Retourne la dernière adresse disponible
|
||||||
int get_last_addr();
|
int get_last_addr();
|
||||||
|
|
Loading…
Reference in a new issue