diff options
-rw-r--r-- | res/test_global.tpc | 15 | ||||
-rw-r--r-- | src/generator.c | 24 | ||||
-rw-r--r-- | src/generator.h | 3 | ||||
-rw-r--r-- | src/symbol_table.c | 91 | ||||
-rw-r--r-- | src/symbol_table.h | 16 | ||||
-rw-r--r-- | src/tpc.y | 27 |
6 files changed, 136 insertions, 40 deletions
diff --git a/res/test_global.tpc b/res/test_global.tpc index 789f290..731fffb 100644 --- a/res/test_global.tpc +++ b/res/test_global.tpc | |||
@@ -4,9 +4,16 @@ | |||
4 | entier r1,b,s,c,r2 ; | 4 | entier r1,b,s,c,r2 ; |
5 | caractere letter, digit, punct; | 5 | caractere letter, digit, punct; |
6 | 6 | ||
7 | void calcul(void) { | ||
8 | entier i; | ||
9 | i = 3; | ||
10 | r1=12; | ||
11 | r2=13; | ||
12 | b = r1 + r2 + i; | ||
13 | print(b); | ||
14 | } | ||
15 | |||
16 | |||
7 | entier main(void) { | 17 | entier main(void) { |
8 | r1=12; | 18 | calcul(); |
9 | r2=13; | ||
10 | b = r1 + r2; | ||
11 | print(b); | ||
12 | } | 19 | } |
diff --git a/src/generator.c b/src/generator.c index c038b7f..d44bbd1 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -18,7 +18,7 @@ void gen_prologue_continue(int *bss_done){ | |||
18 | if (*bss_done == 0){ | 18 | if (*bss_done == 0){ |
19 | fprintf(output, "globals: resq %d\n", nb_globals); | 19 | fprintf(output, "globals: resq %d\n", nb_globals); |
20 | fprintf(output, "section .text\n\nglobal _start\n"); | 20 | fprintf(output, "section .text\n\nglobal _start\n"); |
21 | fprintf(output, "print: ;print needs an argument in rax\n"); | 21 | fprintf(output, "\nprint: ;print needs an argument in rax\n"); |
22 | fprintf(output, "push rbp\n"); | 22 | fprintf(output, "push rbp\n"); |
23 | fprintf(output, "mov rbp, rsp\n"); | 23 | fprintf(output, "mov rbp, rsp\n"); |
24 | fprintf(output, "push rsi\n"); | 24 | fprintf(output, "push rsi\n"); |
@@ -29,19 +29,35 @@ void gen_prologue_continue(int *bss_done){ | |||
29 | fprintf(output, "pop rsi\n"); | 29 | fprintf(output, "pop rsi\n"); |
30 | fprintf(output, "pop rbp\n"); | 30 | fprintf(output, "pop rbp\n"); |
31 | fprintf(output, "ret\n"); | 31 | fprintf(output, "ret\n"); |
32 | fprintf(output, "\n_start:\n"); | ||
33 | fprintf(output, "push rbp\nmov rbp, rsp\n\n"); | ||
34 | *bss_done = 1; | 32 | *bss_done = 1; |
35 | } | 33 | } |
36 | } | 34 | } |
37 | void gen_const_declaration() { | 35 | void gen_const_declaration() { |
38 | fprintf(output, "mov rax,60 \n"); | 36 | fprintf(output, "\n_start:\n"); |
37 | fprintf(output, "push rbp\nmov rbp, rsp\n\n"); | ||
38 | fprintf(output, "call main\n"); | ||
39 | fprintf(output, "\nmov rax,60 \n"); | ||
39 | fprintf(output, "mov rdi,0 \n"); | 40 | fprintf(output, "mov rdi,0 \n"); |
40 | fprintf(output, "syscall \n\n"); | 41 | fprintf(output, "syscall \n\n"); |
41 | fprintf(output, ";global table\n"); | 42 | fprintf(output, ";global table\n"); |
42 | glo_display_table(); | 43 | glo_display_table(); |
43 | fprintf(output, ";local table\n"); | 44 | fprintf(output, ";local table\n"); |
44 | loc_display_table(); | 45 | loc_display_table(); |
46 | fprintf(output, ";function table\n"); | ||
47 | fun_display_table(); | ||
48 | } | ||
49 | |||
50 | void gen_function_declaration(const char name[], int return_type, int nb_param){ | ||
51 | fun_add(name,return_type,nb_param); | ||
52 | fprintf(output, "\n%s:\npush rbp\nmov rbp,rsp\n",name); | ||
53 | } | ||
54 | |||
55 | void gen_function_end_declaration(){ | ||
56 | fprintf(output, "mov rsp, rbp\npop rbp\nret\n"); | ||
57 | } | ||
58 | int gen_function_call(const char name[], int nb_param){ | ||
59 | fprintf(output,"call %s\n",name); | ||
60 | return fun_lookup(name,nb_param); | ||
45 | } | 61 | } |
46 | 62 | ||
47 | void gen_declaration(const char name[], int type, Scope scope) { | 63 | void gen_declaration(const char name[], int type, Scope scope) { |
diff --git a/src/generator.h b/src/generator.h index 1a4c96a..b486172 100644 --- a/src/generator.h +++ b/src/generator.h | |||
@@ -19,6 +19,9 @@ FILE *output; | |||
19 | void gen_prologue(); | 19 | void gen_prologue(); |
20 | void gen_prologue_continue(int *bss_done); | 20 | void gen_prologue_continue(int *bss_done); |
21 | void gen_const_declaration(); | 21 | void gen_const_declaration(); |
22 | void gen_function_declaration(const char name[], int return_type, int nb_param); | ||
23 | void gen_function_end_declaration(); | ||
24 | int gen_function_call(const char name[], int nb_param); | ||
22 | void gen_declaration(const char name[], int type, Scope scope); | 25 | void gen_declaration(const char name[], int type, Scope scope); |
23 | 26 | ||
24 | void gen_read(const char name[], Scope scope); | 27 | void gen_read(const char name[], Scope scope); |
diff --git a/src/symbol_table.c b/src/symbol_table.c index 6dc3e64..d03f858 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c | |||
@@ -10,6 +10,61 @@ extern int lineno; /* from lexical analyser */ | |||
10 | 10 | ||
11 | SymbolTable glo_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; | 11 | SymbolTable glo_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; |
12 | SymbolTable loc_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; | 12 | SymbolTable loc_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; |
13 | FunctionTable fun_table = {{{{0}, 0}}, MAXFUNCTIONS, 0}; | ||
14 | |||
15 | void fun_add(const char name[], int rt_type, int nb_par) { | ||
16 | int count; | ||
17 | for (count = 0; count < fun_table.size; count++) { | ||
18 | if (!strcmp(fun_table.entries[count].name, name)) { | ||
19 | fprintf(stderr, | ||
20 | "semantic error, redefinition of function %s near line %d\n", | ||
21 | name, lineno); | ||
22 | return; | ||
23 | } | ||
24 | } | ||
25 | if (++fun_table.size > fun_table.maxsize) { | ||
26 | fprintf(stderr, "too many functions near line %d\n", lineno); | ||
27 | exit(1); | ||
28 | } | ||
29 | strcpy(fun_table.entries[fun_table.size - 1].name, name); | ||
30 | fun_table.entries[fun_table.size - 1].return_type = rt_type; | ||
31 | fun_table.entries[fun_table.size - 1].nb_parameters = nb_par; | ||
32 | } | ||
33 | |||
34 | void fun_display_table() { | ||
35 | int count; | ||
36 | for (count = 0; count < fun_table.size; count++) { | ||
37 | if (fun_table.entries[count].return_type == INT) | ||
38 | fprintf(output, | ||
39 | ";%s, type de retour : entier, nombre de parametres : %d \n", | ||
40 | fun_table.entries[count].name, | ||
41 | fun_table.entries[count].nb_parameters); | ||
42 | else if (fun_table.entries[count].return_type == CHAR) | ||
43 | fprintf(output, | ||
44 | ";%s, type de retour : caractere, nombre de parametres : %d \n", | ||
45 | fun_table.entries[count].name, | ||
46 | fun_table.entries[count].nb_parameters); | ||
47 | else | ||
48 | fprintf(output, | ||
49 | ";%s, type de retour : void, nombre de parametres : %d \n", | ||
50 | fun_table.entries[count].name, | ||
51 | fun_table.entries[count].nb_parameters); | ||
52 | } | ||
53 | fprintf(output, "\n"); | ||
54 | } | ||
55 | |||
56 | int fun_lookup(const char name[], int nb_param) { | ||
57 | int count; | ||
58 | |||
59 | for (count = 0; count < fun_table.size; count++) { | ||
60 | if (!strcmp(fun_table.entries[count].name, name) && (fun_table.entries[count].nb_parameters == nb_param)) { | ||
61 | return fun_table.entries[count].return_type; | ||
62 | } | ||
63 | } | ||
64 | fprintf(stderr, "No definition of the function %s (or wrong number of parameters) near line %d\n", name, | ||
65 | lineno); | ||
66 | return -1; | ||
67 | } | ||
13 | 68 | ||
14 | void glo_addVar(const char name[], int type) { | 69 | void glo_addVar(const char name[], int type) { |
15 | int count; | 70 | int count; |
@@ -28,7 +83,7 @@ void glo_addVar(const char name[], int type) { | |||
28 | strcpy(glo_symbol_table.entries[glo_symbol_table.size - 1].name, name); | 83 | strcpy(glo_symbol_table.entries[glo_symbol_table.size - 1].name, name); |
29 | glo_symbol_table.entries[glo_symbol_table.size - 1].type = type; | 84 | glo_symbol_table.entries[glo_symbol_table.size - 1].type = type; |
30 | glo_symbol_table.entries[glo_symbol_table.size - 1].addr = | 85 | glo_symbol_table.entries[glo_symbol_table.size - 1].addr = |
31 | (glo_symbol_table.size - 1) * 8; | 86 | (glo_symbol_table.size - 1) * 8; |
32 | } | 87 | } |
33 | 88 | ||
34 | // Verifies that the variable exists and returns the type | 89 | // Verifies that the variable exists and returns the type |
@@ -52,8 +107,6 @@ int glo_get_addr(const char name[]) { | |||
52 | return glo_symbol_table.entries[count].addr; | 107 | return glo_symbol_table.entries[count].addr; |
53 | } | 108 | } |
54 | } | 109 | } |
55 | fprintf(stderr, "No definition of the variable %s near line %d\n", name, | ||
56 | lineno); | ||
57 | return -1; | 110 | return -1; |
58 | } | 111 | } |
59 | 112 | ||
@@ -62,12 +115,12 @@ void glo_display_table() { | |||
62 | for (count = 0; count < glo_symbol_table.size; count++) { | 115 | for (count = 0; count < glo_symbol_table.size; count++) { |
63 | if (glo_symbol_table.entries[count].type == INT) | 116 | if (glo_symbol_table.entries[count].type == INT) |
64 | fprintf(output, ";entier: %s, pos: %d \n", | 117 | fprintf(output, ";entier: %s, pos: %d \n", |
65 | glo_symbol_table.entries[count].name, | 118 | glo_symbol_table.entries[count].name, |
66 | glo_symbol_table.entries[count].addr); | 119 | glo_symbol_table.entries[count].addr); |
67 | else | 120 | else |
68 | fprintf(output, ";caractere: %s, pos: %d \n", | 121 | fprintf(output, ";caractere: %s, pos: %d \n", |
69 | glo_symbol_table.entries[count].name, | 122 | glo_symbol_table.entries[count].name, |
70 | glo_symbol_table.entries[count].addr); | 123 | glo_symbol_table.entries[count].addr); |
71 | } | 124 | } |
72 | fprintf(output, "\n"); | 125 | fprintf(output, "\n"); |
73 | } | 126 | } |
@@ -89,7 +142,7 @@ void loc_addVar(const char name[], int type) { | |||
89 | strcpy(loc_symbol_table.entries[loc_symbol_table.size - 1].name, name); | 142 | strcpy(loc_symbol_table.entries[loc_symbol_table.size - 1].name, name); |
90 | loc_symbol_table.entries[loc_symbol_table.size - 1].type = type; | 143 | loc_symbol_table.entries[loc_symbol_table.size - 1].type = type; |
91 | loc_symbol_table.entries[loc_symbol_table.size - 1].addr = | 144 | loc_symbol_table.entries[loc_symbol_table.size - 1].addr = |
92 | (loc_symbol_table.size - 1) * 8; | 145 | (loc_symbol_table.size - 1) * 8 + 8; |
93 | } | 146 | } |
94 | 147 | ||
95 | int loc_lookup(const char name[]) { | 148 | int loc_lookup(const char name[]) { |
@@ -100,7 +153,7 @@ int loc_lookup(const char name[]) { | |||
100 | return loc_symbol_table.entries[count].type; | 153 | return loc_symbol_table.entries[count].type; |
101 | } | 154 | } |
102 | } | 155 | } |
103 | //Check in global table | 156 | // Check in global table |
104 | for (count = 0; count < glo_symbol_table.size; count++) { | 157 | for (count = 0; count < glo_symbol_table.size; count++) { |
105 | if (!strcmp(glo_symbol_table.entries[count].name, name)) { | 158 | if (!strcmp(glo_symbol_table.entries[count].name, name)) { |
106 | return glo_symbol_table.entries[count].type; | 159 | return glo_symbol_table.entries[count].type; |
@@ -128,12 +181,12 @@ void loc_display_table() { | |||
128 | for (count = 0; count < loc_symbol_table.size; count++) { | 181 | for (count = 0; count < loc_symbol_table.size; count++) { |
129 | if (loc_symbol_table.entries[count].type == INT) | 182 | if (loc_symbol_table.entries[count].type == INT) |
130 | fprintf(output, ";entier: %s, pos: %d \n", | 183 | fprintf(output, ";entier: %s, pos: %d \n", |
131 | loc_symbol_table.entries[count].name, | 184 | loc_symbol_table.entries[count].name, |
132 | loc_symbol_table.entries[count].addr); | 185 | loc_symbol_table.entries[count].addr); |
133 | else | 186 | else |
134 | fprintf(output, ";caractere: %s, pos: %d \n", | 187 | fprintf(output, ";caractere: %s, pos: %d \n", |
135 | loc_symbol_table.entries[count].name, |