Avancées sur les fonctions

This commit is contained in:
Elies Tali 2021-04-27 17:02:30 +02:00
parent e7fd215110
commit fffd6020f5
11 changed files with 148 additions and 53 deletions

View file

@ -30,6 +30,10 @@ 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
Copie la valeur addr à l'adresse @X en considérant que ce qui est copié est une adresse (et donc il faut ajouter BP)
## JMP lig
Saute vers la ligne lig dans le code sans condition
@ -52,9 +56,13 @@ Met à l'adresse @X 1 si val en @A égale à celle en @B et 0 sinon
## READ @X @Y
Va mettre à l'adresse @X ce qui est à l'addresse contenue à l'adresse @Y (on considère que ce qui est dans @Y est un adresse et on va voir à cette adresse)
Va mettre à l'adresse @X ce qui est à l'addresse contenue à l'adresse @Y (on considère que ce qui est dans @Y est un adresse et on va voir à cette adresse). Attention, considérer des addresses globales (pas relatives).
## WR @X @Y
Va mettre le contenue dans @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)
Va mettre le contenue dans @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
Appelle la fonction dont la première ligne est lig est dont la taille des arguments est en @Y (afin de pouvoir bouger ebp).

View file

@ -1,9 +1,10 @@
int fonction(int * p){
int b = *p + 2;
}
int main(){
int b[3];
int * c = &b[2];
int * f = &b[1];
if(1){
int v;
}
int y;
int a = 255;
fonction(&a);
}

View file

@ -3,15 +3,16 @@
char id[30];
}
%{
#include "../Tables/Fonctions/tab_fonctions.h"
#include "../Tables/Symboles/table_symboles.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../Tables/Instructions/tab_instruc.h"
#include "../Tables/Fonctions/tab_fonctions.h"
#define TAILLE 1024
struct type_t type_courant;
struct type_t return_type_fonc;
int instructions_ligne_to_patch[10][20];
int nbs_instructions_to_patch[10];
@ -42,7 +43,7 @@ int nbs_instructions_to_patch[10];
%left tADD tSUB
%left tMUL tDIV
%type<nombre> E DebutAff SuiteAffPointeur DebutAffPointeur EBis ETer
%type<nombre> E DebutAff SuiteAffPointeur DebutAffPointeur EBis Invocation Args ArgSuite Arg SuiteParams Params
@ -52,20 +53,24 @@ int nbs_instructions_to_patch[10];
%%
Main : tINT tMAIN tOBRACE Params tCBRACE Body { print(); create_asm();} ;
Params : { printf("Sans Params\n"); } ;
Params : Param SuiteParams ;
Param : Type tID { printf("Parametre : %s\n", $2); };
SuiteParams : tCOMA Param SuiteParams ;
SuiteParams : ;
Args : Arg ArgSuite;
Args : ;
Arg : Type tID {int addr = push($2,1, type_courant);};
ArgSuite : tCOMA Arg ArgSuite {} ;
ArgSuite : ;
C : Fonction Fonctions;
Fonctions : Fonction Fonctions;
Fonctions : ;
Main : tINT {printf("Déclaration du main\n");} tMAIN tOBRACE Args tCBRACE Body { print(); create_asm();} ;
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();} ;
Fonction : Main {print_fonctions();};
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 {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();} ;
@ -75,10 +80,24 @@ Instructions : Instruction Instructions ;
Instructions : ;
Instruction : Aff {};
Instruction : Decl {};
//Instruction : Invocation tPV{};
Instruction : Invocation tPV{};
Instruction : If {};
Instruction : While {};
Invocation : tID tOBRACE Params tCBRACE {multiple_pop($3); struct fonction_t fonc = get_fonction($1); add_operation(CALL,fonc.first_instruction_line, fonc.taille_args,0);};
//Pour les tableaux quand on les passe en arguments, il faudra faire gaffe à bien les passer comme un pointeur vers un tableau et pas juste un tableau car sinon in ne pourra pas accéder au tableau de base depuis la fonction appellée. Il faut pour cela peut être rajouter un nouveau champ (isArg) dans la table des symboles (ou autre idée?)
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;}
@ -131,7 +150,7 @@ 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 { printf("Invoc\n"); int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,$1,0); $$ = addr;};
E : Invocation { printf("Invoc\n"); int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,$1,0); $$ = addr;};
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();};
@ -141,21 +160,32 @@ 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;};
E : tADDR EBis {add_operation(COPA,$2, $2,0); $$=$2;};
E : tADDR ETer {add_operation(COPA,$2, $2,0); $$=$2;};
E : tID { printf("Id\n"); struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); if (symbole->type.isTab){add_operation(AFCA, addr,symbole->adresse,0); } else{add_operation(COP, addr,symbole->adresse,0);} $$=addr;};
E : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); if(type.pointeur_level > 0) {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); add_operation(READ,$3,$3,0); $$=$3; pop(); pop();};
E : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); if(type.pointeur_level > 0) {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); add_operation(READ,$3,$3,0); $$=$3; pop(); pop();};
E : tADDR EBis {add_operation(COPA,$2, $2,0); $$=$2;};
EBis : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); if(type.pointeur_level > 0) {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();};
ETer : tID { printf("Id\n"); struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); add_operation(AFCA, addr,symbole->adresse,0); $$=addr;};
EBis : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1);
struct type_t type = symbole->type; type.nb_blocs = 1;
int addr = push("0_TEMPORARY", 1, type);
if(type.pointeur_level > 0) {
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();};
EBis : tID { printf("Id\n"); struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); add_operation(AFCA, addr,symbole->adresse,0); $$=addr;};
//Créer un champ isConst dans la table des symboles
Type : tINT {type_courant.base = INT; type_courant.pointeur_level = 0; type_courant.isTab = 0; type_courant.nb_blocs = 1; printf("Type int\n");} ;
Type : Type tMUL {type_courant.pointeur_level++; printf("Type int *\n");};
//SuiteType : tMUL SuiteType {type_courant.pointeur_level++; printf(" * en plus\n");} ;
//SuiteType : ;
Decl : Type SuiteDecl FinDecl ;
Decl : tCONST Type SuiteDeclConst FinDeclConst;
@ -169,10 +199,6 @@ FinDecl : tCOMA SuiteDecl FinDecl ;
SuiteDeclConst : tID tEQ E {pop(); int addr = push($1,1, type_courant);};
FinDeclConst : tPV;
FinDeclConst : tCOMA SuiteDeclConst FinDeclConst;
Fonction : Type tID {push_fonction($2,type_courant,get_current_index());} tOBRACE {} Args {} tCBRACE Body { printf("Déclaration de la fonction %s\n", $1); } ;)
%%
void main(void) {
init();

View file

@ -1,7 +1,7 @@
default :
@echo "Spécifiez une cible"
clean : clean_Symboles clean_Instructions clean_Lex_Yacc
clean : clean_Symboles clean_Instructions clean_Lex_Yacc clean_Fonctions
@rm -f rondoudou_gcc
@rm -f output.txt
@ -13,11 +13,15 @@ clean_Instructions:
@rm -f Tables/Instructions/*.o
@rm -f Tables/Instructions/test
clean_Fonctions:
@rm -f Tables/Fonctions/*.o
@rm -f Tables/Fonctions/test
clean_Lex_Yacc:
@rm -f Lex_Yacc/as.output Lex_Yacc/as.tab.* Lex_Yacc/lex.yy.*
build : clean build_Symboles build_Instructions build_Lex_Yacc
gcc Lex_Yacc/as.tab.o Lex_Yacc/lex.yy.o Tables/Instructions/tab_instruc.o Tables/Symboles/table_symboles.o -ll -o rondoudou_gcc
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
build_Symboles: clean_Symboles
gcc -c Tables/Symboles/table_symboles.c -o Tables/Symboles/table_symboles.o
@ -25,6 +29,9 @@ build_Symboles: clean_Symboles
build_Instructions: clean_Instructions
gcc -c Tables/Instructions/tab_instruc.c -o Tables/Instructions/tab_instruc.o
build_Fonctions : clean_Fonctions
gcc -c Tables/Fonctions/tab_fonctions.c -o Tables/Fonctions/tab_fonctions.o
build_Lex_Yacc: clean_Lex_Yacc
bison -d -t -b Lex_Yacc/as Lex_Yacc/as.y
flex -o Lex_Yacc/lex.yy.c Lex_Yacc/al.lex
@ -56,4 +63,7 @@ edit_Instructions:
edit_Progs:
pluma Fichiers_Tests/progC &
edit: edit_Lex_Yacc edit_Symboles edit_Instructions edit_Progs
edit_Fonctions :
pluma Tables/Fonctions/tab_fonctions.c Tables/Fonctions/tab_fonctions.h
edit: edit_Lex_Yacc edit_Symboles edit_Instructions edit_Progs edit_Fonctions

View file

@ -1,13 +1,15 @@
#include "tab_fonctions.h"
struct fonction_t tab_fonctions[MAX_TAILLE_FONC];
int index = 0;
int indexTab = 0;
struct fonction_t get_fonction(char * name){
int not_found = 1;
int i = 0;
struct fonction_t res = NULL;
while (not_found && (i <= index)){
if (!strcmp(name,tab_fonctions[i].name){
struct fonction_t res;
while (not_found && (i <= indexTab)){
if (!strcmp(name,tab_fonctions[i].name)){
res = tab_fonctions[i];
not_found = 0;
}
@ -16,14 +18,25 @@ struct fonction_t get_fonction(char * name){
return res;
}
void push_fonction(char * name, struct type_t type, int line){
if (index < MAX_TAILLE_FONC){
void push_fonction(char * name, struct type_t type, int line, int taille_args){
if (indexTab < MAX_TAILLE_FONC){
struct fonction_t fonc;
fonc.name = malloc(sizeof(char)*50);
strcpy(fonc.name,name);
fonc.type = type;
fonc.return_type = type;
fonc.first_instruction_line = line;
tab_fonctions[i] = fonc;
index++;
fonc.taille_args = taille_args;
tab_fonctions[indexTab] = fonc;
indexTab++;
}
}
void print_fonctions(){
printf("Affichage table des fonctions\n");
printf("\t Size : %d\n",indexTab);
printf("\t Contenu : \n");
for (int i =0; i<indexTab; i++){
printf("\t\t{Fonction : %s returns %s and starts at line %d and its args have a size of %d}\n",tab_fonctions[i].name, type_to_string(tab_fonctions[i].return_type), tab_fonctions[i].first_instruction_line, tab_fonctions[i].taille_args);
}
}

View file

@ -1,5 +1,11 @@
#include "tab_symboles.h"
#ifndef TAB_FONC_H
#define TAB_FONC_H
#include "../Symboles/table_symboles.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_TAILLE_FONC 50
@ -8,9 +14,14 @@ struct fonction_t {
char * name;
struct type_t return_type;
int first_instruction_line;
int taille_args;
};
struct fonction_t get_fonction(char * name);
void push_fonction(char * name, struct type_t type, int line);
void push_fonction(char * name, struct type_t type, int line, int taille_args);
void print_fonctions();
#endif

Binary file not shown.

View file

@ -66,6 +66,9 @@ char * get_asm_line_from_op(struct operation_t op){
case (WR):
sprintf(buffer,"WR %d %d\n",op.arg1, op.arg2);
break;
case (CALL):
sprintf(buffer,"CALL %d %d\n",op.arg1, op.arg2);
break;
}
return buffer;
}

View file

@ -1,10 +1,13 @@
#ifndef TAB_INST_H
#define TAB_INST_H
#define MAXTAILLE 1024
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
enum opcode_t {ADD,MUL,SOU,DIV,COP,AFC,AFCA,COPA,JMP,JMF,INF,SUP,EQU,PRI,READ,WR};
enum opcode_t {ADD,MUL,SOU,DIV,COP,AFC,AFCA,COPA,JMP,JMF,INF,SUP,EQU,PRI,READ,WR,CALL};
struct operation_t {
enum opcode_t opcode;
@ -21,3 +24,5 @@ int get_current_index();
void patch(int index, int arg);
//Ecrit la table des intructions dans un fichier ASM
void create_asm();
#endif

View file

@ -109,6 +109,14 @@ struct symbole_t pop() {
return retour;
}
void multiple_pop(int n){
for (int i =0; i<n; i++){
pop();
}
}
struct symbole_t * get_variable(char * nom){
struct symbole_t * retour = NULL;
struct element_t * aux = pile->first;

View file

@ -25,6 +25,9 @@ Opérations possible :
- pop -> pile * -> symbole
- status -> nom -> pile -> char */
#ifndef TAB_SYMB_H
#define TAB_SYMB_H
#include <stdint.h>
@ -57,6 +60,9 @@ struct type_t {
int isTab;
};
//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;
@ -119,6 +125,8 @@ 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
void multiple_pop(int n);
//Retourne la dernière adresse disponible
int get_last_addr();
//Renvoi un pointeur vers le symbole correspondant au nom de variable
@ -126,3 +134,5 @@ struct symbole_t * get_variable(char * nom);
//Affiche la table des symboles
void print();
#endif