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.tab.*  | ||||
| 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) | ||||
| 
 | ||||
| ## 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 | ||||
| 
 | ||||
|  | @ -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). | ||||
| 
 | ||||
| ##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 | ||||
| 
 | ||||
| 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" | ||||
| int yywrap(void){return 1;} | ||||
| void | ||||
|  | @ -11,44 +11,57 @@ yyerror (char const *s) | |||
| 
 | ||||
| %% | ||||
| 
 | ||||
| "main"      { return tMAIN ;}  | ||||
| "{"         { return tOBRACKET;} | ||||
| "}"         { return tCBRACKET; } | ||||
| "("			{ return tOBRACE; } | ||||
| ")"			{ return tCBRACE; } | ||||
| "const"     { return tCONST; } | ||||
| "int"       { return tINT; } | ||||
| "printf"    { return tPRINTF; } //Degeu mais à degager | ||||
| "if"        { return tIF; } | ||||
| "while"     { return tWHILE; } | ||||
| "return"    {return tRETURN; } | ||||
| "<"         { return tLT; } | ||||
| ">"         { return tGT; } | ||||
| "=="        { return tEQCOND; } | ||||
| "&&"        { return tAND; } | ||||
| "||"        { return tOR; } | ||||
| "else"      { return tELSE;} | ||||
| "&"         { return tADDR;} | ||||
| "["         { return tOCROCH;} | ||||
| "]" 		{ return tCCROCH;} | ||||
| "get"       { return tGET;} | ||||
| "stop"      { return tSTOP;} | ||||
| 
 | ||||
| "main"      { return tMAIN;     }    // Token de la fonction main | ||||
| 
 | ||||
| "{"         { return tOBRACKET; }    // Token accolade ouvrante | ||||
| "}"         { return tCBRACKET; }    // Token accolade fermante | ||||
| "("		    	{ return tOBRACE;   }    // Token parenthèse ouvrante | ||||
| ")"	    		{ return tCBRACE;   }    // Token parenthèse fermante | ||||
| 
 | ||||
| "const"     { return tCONST;    }    // Token constante | ||||
| "int"       { return tINT;      }    // Token type int | ||||
| 
 | ||||
| "if"        { return tIF;       }    // Token if | ||||
| "else"      { return tELSE;     }    // Token else | ||||
| "while"     { return tWHILE;    }    // Token while | ||||
| 
 | ||||
| "return"    {return tRETURN;    }    // Token return | ||||
| 
 | ||||
| "<"         { return tLT;       }    // Token plus petit que | ||||
| ">"         { return tGT;       }    // Token plus grand que | ||||
| "=="        { return tEQCOND;   }    // Token égal comparaison | ||||
| 
 | ||||
| "&&"        { 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; } | ||||
| [0-9]+e[0-9]+	{ yylval.nombre = -1; return tNBEXP; } //Renvoyer le token tNB et pas tNBEXP | ||||
| "+"			{ return tADD; } | ||||
| "-"			{ 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; } | ||||
| " "			    {} //Ne pas les retourner à Yacc (espace) | ||||
| "   "       {} //Ne pas les retourner à Yacc (tabulation) | ||||
| "\n"        {} //Ne pas les retourner à Yacc (retour chariot) | ||||
| 
 | ||||
| %% | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										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 return_type_fonc; | ||||
| 
 | ||||
| 
 | ||||
| // Tableau pour le management des patchs des JMP | ||||
| int instructions_ligne_to_patch[10][20]; | ||||
| int nbs_instructions_to_patch[10]; | ||||
| 
 | ||||
| %} | ||||
| 
 | ||||
| // Récupération des tokens | ||||
| %token tMAIN | ||||
| %token tOBRACKET tCBRACKET | ||||
| %token<nombre> tOBRACE tCBRACE | ||||
|  | @ -45,134 +46,411 @@ int nbs_instructions_to_patch[10]; | |||
| %left tADD tSUB | ||||
| %left tMUL tDIV | ||||
| 
 | ||||
| %type<nombre> E DebutAff 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 *******************/ | ||||
| %type<nombre> E SuiteAffPointeur DebutAffPointeur EBis Invocation Args ArgSuite Arg SuiteParams Params Get | ||||
| 
 | ||||
| %% | ||||
| 
 | ||||
| /*************************************/ | ||||
| /*************************************/ | ||||
| /*********** 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 : ; | ||||
| 
 | ||||
| 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 : Aff {}; | ||||
| Instruction : Decl {}; | ||||
| Instruction : Invocation tPV{pop();}; | ||||
| Instruction : If {}; | ||||
| Instruction : While {}; | ||||
| Instruction : Return {}; | ||||
| Instruction : Stop tPV {}; | ||||
| 
 | ||||
| 
 | ||||
| Invocation : tID tOBRACE {struct fonction_t fonc = get_fonction($1);} | ||||
| Params tCBRACE {struct fonction_t fonc = get_fonction($1); multiple_pop($4); | ||||
| add_operation(CALL,fonc.first_instruction_line, get_last_addr(),0); if (fonc.return_type.pointeur_level > 0 || fonc.return_type.isTab){ | ||||
|  $$ = push("0_TEMPORARY_RETURN", 0, integer);  | ||||
| } | ||||
| else{ | ||||
| $$ = push("0_TEMPORARY_RETURN", 0, fonc.return_type);  | ||||
| }}; | ||||
| 
 | ||||
| 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;}; | ||||
| // Un instruction peut être : une affectation, une déclaration, une invocation, un if, un while, un return, une fonction particulière | ||||
| Instruction : Aff; | ||||
| Instruction : Decl; | ||||
| Instruction : Invocation tPV      {pop();}; | ||||
| Instruction : If; | ||||
| Instruction : While; | ||||
| Instruction : Return; | ||||
| Instruction : Stop tPV; | ||||
| Instruction : Print tPV; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //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++){ | ||||
| 	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();} | ||||
| /*************************************/ | ||||
| /*************************************/ | ||||
| /************ Invocation *************/ | ||||
| /*************************************/ | ||||
| /*************************************/ | ||||
| 
 | ||||
| Body { printf("While reconnu\n"); | ||||
| int current = get_current_index(); | ||||
| patch($1,current + 1); | ||||
| add_operation(JMP,$1,0,0);}; | ||||
| Invocation : tID tOBRACE Params tCBRACE  {struct fonction_t fonc = get_fonction($1);                              // On récupère la fonction | ||||
|                                           multiple_pop($3);                                                       // On pop les paramètres de la table des symboles | ||||
|                                           add_operation(CALL,fonc.first_instruction_line, get_last_addr(),0);     // On écrit le CALL | ||||
| 																					// 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();}; | ||||
| 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;}; | ||||
| 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();}; | ||||
| 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();}; | ||||
| E : E tLT E { printf("<\n"); add_operation(INF,$1,$1,$3); $$ = $1; pop();}; | ||||
| E : tNOT E { printf("!\n"); }; | ||||
| 
 | ||||
| /*************************************/ | ||||
| /*************************************/ | ||||
| /************ Paramètres *************/ | ||||
| /*************************************/ | ||||
| /*************************************/ | ||||
| 
 | ||||
| // 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 | ||||
| Params :                                 {$$ = 0; | ||||
|                                          }; | ||||
| Params : Param SuiteParams               {$$ = $2 + 1; | ||||
|                                          }; | ||||
| 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 tOR E {add_operation(ADD,$1,$1,$3); $$ = $1; pop();} ; | ||||
| E : tMUL E { add_operation(READ, $2, $2, 0); $$=$2;}; | ||||
|  |  | |||
							
								
								
									
										25
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								Makefile
									
									
									
									
									
								
							|  | @ -1,6 +1,11 @@ | |||
| default :  | ||||
| 	@echo "Spécifiez une cible" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ###########################
 | ||||
| ###      NETTOYAGE      ###
 | ||||
| ###########################
 | ||||
| clean : clean_Symboles clean_Instructions clean_Lex_Yacc clean_Fonctions | ||||
| 	@rm -f rondoudou_gcc | ||||
| 	@rm -f output.txt | ||||
|  | @ -20,6 +25,11 @@ clean_Fonctions: | |||
| clean_Lex_Yacc: | ||||
| 	@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 | ||||
| 	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/lex.yy.c -o Lex_Yacc/lex.yy.o | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ###########################
 | ||||
| ###        TESTS        ###
 | ||||
| ###########################
 | ||||
| test_Symboles: build_Symboles | ||||
| 	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 | ||||
|  | @ -48,9 +63,19 @@ test_Instructions: build_Instructions | |||
| 	gcc Tables/Instructions/test.o Tables/Instructions/tab_instruc.o -o 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 | ||||
| 	cat Fichiers_Tests/progC | ./rondoudou_gcc  | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ###########################
 | ||||
| ###       EDITION       ###
 | ||||
| ###########################
 | ||||
| edit_Lex_Yacc:  | ||||
| 	pluma Lex_Yacc/al.lex Lex_Yacc/as.y & | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,9 +1,14 @@ | |||
| #include "tab_fonctions.h" | ||||
| 
 | ||||
| #define MAX_TAILLE_FONC 50 | ||||
| 
 | ||||
| // Table des fonctions
 | ||||
| struct fonction_t tab_fonctions[MAX_TAILLE_FONC]; | ||||
| // Index dispo dans la table
 | ||||
| int indexTab = 0; | ||||
| 
 | ||||
| 
 | ||||
| // Renvoi une fonction a partir de son nom
 | ||||
| struct fonction_t get_fonction(char * name){ | ||||
| 	int not_found = 1; | ||||
| 	int i = 0; | ||||
|  | @ -18,6 +23,7 @@ struct fonction_t get_fonction(char * name){ | |||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| // Insere une fonction
 | ||||
| void push_fonction(char * name, struct type_t type, int line, int taille_args){ | ||||
| 	 if (indexTab < MAX_TAILLE_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(){ | ||||
| 	printf("Affichage table des fonctions\n"); | ||||
| 	printf("\t Size : %d\n",indexTab); | ||||
|  |  | |||
|  | @ -7,8 +7,6 @@ | |||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| #define MAX_TAILLE_FONC 50 | ||||
| 
 | ||||
| //Struct dans le tableau qui permet d'identifier une fonction
 | ||||
| struct fonction_t { | ||||
| 	char * name; | ||||
|  | @ -17,10 +15,11 @@ struct fonction_t { | |||
| 	int taille_args; | ||||
| }; | ||||
| 
 | ||||
| // Renvoi les informations sur une fonction à partir de son nom
 | ||||
| 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); | ||||
| 
 | ||||
| // Fonction d'affichage des fonctions connues
 | ||||
| void print_fonctions(); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,7 +1,20 @@ | |||
| #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; | ||||
| // Tableau des instructions (programme en assembleur)
 | ||||
| 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){ | ||||
| 	if (current_index == MAXTAILLE){ | ||||
| 		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){ | ||||
|     struct operation_t new_op = {JMP,line, 0, 0}; | ||||
|     tab_op[0] = new_op; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Fonction traduisant une opération en assembleur
 | ||||
| char * get_asm_line_from_op(struct operation_t op){ | ||||
| 	char * buffer = malloc(sizeof(char)*200); | ||||
| 	switch (op.opcode){ | ||||
|  | @ -73,16 +87,17 @@ char * get_asm_line_from_op(struct operation_t op){ | |||
| 		case (RET): | ||||
| 			sprintf(buffer,"RET\n"); | ||||
| 			break; | ||||
|         case (GET): | ||||
|             sprintf(buffer,"GET %d\n",op.arg1); | ||||
|             break; | ||||
|         case (STOP): | ||||
|             sprintf(buffer,"STOP %d\n", op.arg1); | ||||
|             break; | ||||
|     case (GET): | ||||
|       sprintf(buffer,"GET %d\n",op.arg1); | ||||
|       break; | ||||
|     case (STOP): | ||||
|       sprintf(buffer,"STOP %d\n", op.arg1); | ||||
|       break; | ||||
| 	} | ||||
| 	return buffer; | ||||
| } | ||||
| 
 | ||||
| // Genere le code asm dans un fichier
 | ||||
| void create_asm(){ | ||||
| 	FILE * output = fopen("output.txt","w"); | ||||
| 	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;} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Permet de modifier un instruction à postériorie (pour les JMP)
 | ||||
| void patch(int index, int arg){ | ||||
| 	if (tab_op[index].opcode == JMP){ | ||||
| 		tab_op[index].arg1 = arg; | ||||
|  |  | |||
|  | @ -1,21 +1,15 @@ | |||
| #ifndef TAB_INST_H | ||||
| #define TAB_INST_H | ||||
| 
 | ||||
| #define MAXTAILLE 1024 | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| #include <string.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}; | ||||
| 
 | ||||
| struct operation_t { | ||||
| 	enum opcode_t opcode; | ||||
| 	int arg1; | ||||
| 	int arg2; | ||||
| 	int arg3; | ||||
| }; | ||||
| 
 | ||||
| //Ajoute une opération dans la table (à la fin)
 | ||||
| void add_operation(enum opcode_t opcode, int arg1, int arg2, int arg3); | ||||
| //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 <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| #define MAXADDR 1024*5 | ||||
| 
 | ||||
| // Première adresse disponible
 | ||||
| int last_addr = 0; | ||||
| int temp_addr = MAXADDR; | ||||
| int taille_types[] = {-1, 1}; | ||||
| // Tableau indexé sur les types donnant leur tailles 
 | ||||
| int taille_types[] = {-1, 1, 1}; | ||||
| // Pronfondeur dans le code (pour la visibilité des variables)
 | ||||
| int profondeur = 0; | ||||
| int last_temp_var_size; | ||||
| const struct type_t integer = {INT, 0, 1}; | ||||
| // Constante pour les entiers
 | ||||
| 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 symbole_t symbole; | ||||
| 	struct element_t * suivant; | ||||
| }; | ||||
| 
 | ||||
| // Structure de la pile des symboles
 | ||||
| struct pile_t { | ||||
| 	int taille; | ||||
| 	struct element_t * first; | ||||
| }; | ||||
| 
 | ||||
| // Pile des symboles
 | ||||
| struct pile_t * pile; | ||||
| 
 | ||||
| // Fonction d'affichage pour un type
 | ||||
| char * type_to_string(struct type_t type) { | ||||
|     char * star = "*"; | ||||
|     char * resultat = malloc(sizeof(char)*20); | ||||
|  | @ -64,6 +44,7 @@ char * type_to_string(struct type_t type) { | |||
|     return resultat; | ||||
| } | ||||
| 
 | ||||
| // Fonction d'affichage pour un symbole
 | ||||
| void print_symbole(struct symbole_t symbole) { | ||||
|     char * type = type_to_string(symbole.type); | ||||
|     if (symbole.initialized) { | ||||
|  | @ -74,14 +55,14 @@ void print_symbole(struct symbole_t symbole) { | |||
|     free(type); | ||||
| } | ||||
| 
 | ||||
| // Initialisation de la pile
 | ||||
| void init (void) { | ||||
|     pile = malloc(sizeof(struct pile_t)); | ||||
|   pile = malloc(sizeof(struct pile_t)); | ||||
| 	pile->first = NULL; | ||||
| 	pile->taille = 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Fonction d'ajout d'un symbole à la pile
 | ||||
| int push(char * nom, int isInit, struct type_t type) { | ||||
| 	struct element_t * aux = malloc(sizeof(struct element_t)); | ||||
| 	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; | ||||
| } | ||||
| 
 | ||||
| // Fonction renvoyant et supprimant le premier symbole
 | ||||
| struct symbole_t pop() { | ||||
| 	struct symbole_t retour = {"", 0, UNKNOWN, 0, 0}; | ||||
| 	struct element_t * aux; | ||||
|  | @ -109,14 +91,14 @@ struct symbole_t pop() { | |||
| 	return retour; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Fonction supprimant les n premiers symboles
 | ||||
| void multiple_pop(int n){ | ||||
| 	for (int i =0; i<n; i++){ | ||||
| 		pop(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Fonction d'accès a un symbole par son nom
 | ||||
| struct symbole_t * get_variable(char * nom){ | ||||
| 	struct symbole_t * retour = NULL; | ||||
| 	struct element_t * aux = pile->first; | ||||
|  | @ -132,6 +114,7 @@ struct symbole_t * get_variable(char * nom){ | |||
| 	return retour; | ||||
| } | ||||
| 
 | ||||
| // Fonction d'affichage de la pile
 | ||||
| void print() { | ||||
| 	printf("Affichage de la Table des Symboles\n\tSize : %d\n\tContenu : \n", pile->taille); | ||||
| 	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(){ | ||||
| 	return last_addr; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /********************************/ | ||||
| /*** GESTION DE LA PROFONDEUR ***/ | ||||
| /********************************/ | ||||
| void inc_prof() { | ||||
|     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 | ||||
| #define TAB_SYMB_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /**************************************/ | ||||
| /**************************************/ | ||||
| /**** Gestion des types possibles  ****/ | ||||
|  | @ -45,7 +11,7 @@ Opérations possible : | |||
| /**************************************/ | ||||
| 
 | ||||
| //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)
 | ||||
| extern int taille_types[]; | ||||
| //Structure gérant les types 
 | ||||
|  | @ -54,17 +20,18 @@ struct type_t { | |||
|     enum base_type_t base; | ||||
|     //Si la variable est un pointeur, on enregitre son niveau (nombre de *)
 | ||||
|     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 à) 
 | ||||
| 	int nb_blocs; | ||||
| 	//Si c'est un tableau addressale directement, cette valeur est à 1. Si c'est un pointeur vers un tableau, valeur à 2.
 | ||||
| 	int isTab; | ||||
|     //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; | ||||
| 	  //Si c'est un tableau cette valeur est à 1, 0 sinon.
 | ||||
| 	  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); | ||||
| //Constante pour les entiers
 | ||||
| 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é
 | ||||
| 	int initialized; | ||||
|     //Sa profondeur de création
 | ||||
|     int profondeur; | ||||
|   int profondeur; | ||||
| }; | ||||
| 
 | ||||
| //Fonction d'affichage d'un symbole
 | ||||
|  | @ -124,7 +91,7 @@ void init(void); | |||
| int push(char * nom, int isInit, struct type_t type); | ||||
| //Destruction et récupération du premier élément de la table
 | ||||
| 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); | ||||
| //Retourne la dernière adresse disponible
 | ||||
| int get_last_addr(); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue