diff options
author | pacien | 2018-06-05 22:41:15 +0200 |
---|---|---|
committer | pacien | 2018-06-05 22:41:15 +0200 |
commit | 0f4b1600983f8afda41a02fec07424338785d81d (patch) | |
tree | cd1a3b2f599f7242c9fe76f9d66ca95ba58e34c0 | |
parent | 864653f00dff0a8a1f37d8e9a732c1da8309a930 (diff) | |
download | tpc-compiler-0f4b1600983f8afda41a02fec07424338785d81d.tar.gz |
Prevent assigning to const
-rw-r--r-- | src/generator.c | 20 | ||||
-rw-r--r-- | src/generator.h | 9 | ||||
-rw-r--r-- | src/symbol_table.c | 20 | ||||
-rw-r--r-- | src/symbol_table.h | 8 | ||||
-rw-r--r-- | src/tpc.y | 4 |
5 files changed, 50 insertions, 11 deletions
diff --git a/src/generator.c b/src/generator.c index 3ecfe0d..f32f468 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -159,7 +159,12 @@ void gen_check(const char name[], Scope scope) { | |||
159 | } | 159 | } |
160 | 160 | ||
161 | // ----- READ AND PRINT FUNCTIONS ----- | 161 | // ----- READ AND PRINT FUNCTIONS ----- |
162 | void gen_reade(const char name[]) { | 162 | void gen_reade(const char name[], Scope scope) { |
163 | if (is_read_only(name, scope)) { | ||
164 | fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, scope); | ||
165 | exit(1); | ||
166 | } | ||
167 | |||
163 | if (loc_lookup(name) != INT) { | 168 | if (loc_lookup(name) != INT) { |
164 | fprintf(stderr, "Need to be a INT in the reade() function\n"); | 169 | fprintf(stderr, "Need to be a INT in the reade() function\n"); |
165 | return; | 170 | return; |
@@ -174,7 +179,12 @@ void gen_reade(const char name[]) { | |||
174 | fprintf(output, "mov rax,globals\nadd rax,%d\ncall reade\n", g_addr); | 179 | fprintf(output, "mov rax,globals\nadd rax,%d\ncall reade\n", g_addr); |
175 | } | 180 | } |
176 | 181 | ||
177 | void gen_readc(const char name[]) { | 182 | void gen_readc(const char name[], Scope scope) { |
183 | if (is_read_only(name, scope)) { | ||
184 | fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, scope); | ||
185 | exit(1); | ||
186 | } | ||
187 | |||
178 | if (loc_lookup(name) != CHAR) { | 188 | if (loc_lookup(name) != CHAR) { |
179 | fprintf(stderr, "Need to be a CHAR in the readc() function\n"); | 189 | fprintf(stderr, "Need to be a CHAR in the readc() function\n"); |
180 | return; | 190 | return; |
@@ -233,6 +243,12 @@ void gen_ifelse_end(int idx) { | |||
233 | int gen_assign(const char ident[], Scope scope) { | 243 | int gen_assign(const char ident[], Scope scope) { |
234 | int l_addr = loc_get_addr(ident); | 244 | int l_addr = loc_get_addr(ident); |
235 | int g_addr = glo_get_addr(ident); | 245 | int g_addr = glo_get_addr(ident); |
246 | |||
247 | if (is_read_only(ident, scope)) { | ||
248 | fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, scope); | ||
249 | exit(1); | ||
250 | } | ||
251 | |||
236 | switch (scope) { | 252 | switch (scope) { |
237 | case GLOBAL: | 253 | case GLOBAL: |
238 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, | 254 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, |
diff --git a/src/generator.h b/src/generator.h index 6c132fd..d2ad5c2 100644 --- a/src/generator.h +++ b/src/generator.h | |||
@@ -10,11 +10,6 @@ | |||
10 | #include <stdbool.h> | 10 | #include <stdbool.h> |
11 | #include "symbol_table.h" | 11 | #include "symbol_table.h" |
12 | 12 | ||
13 | typedef enum scope { | ||
14 | GLOBAL, | ||
15 | LOCAL | ||
16 | } Scope; | ||
17 | |||
18 | extern int nb_globals; | 13 | extern int nb_globals; |
19 | extern int lineno; | 14 | extern int lineno; |
20 | FILE *output; | 15 | FILE *output; |
@@ -32,8 +27,8 @@ Type gen_function_call(const char name[], int nb_param); | |||
32 | void gen_declaration(const char name[], int type, Scope scope); | 27 | void gen_declaration(const char name[], int type, Scope scope); |
33 | void gen_check(const char name[], Scope scope); | 28 | void gen_check(const char name[], Scope scope); |
34 | 29 | ||
35 | void gen_reade(const char name[]); | 30 | void gen_reade(const char name[], Scope scope); |
36 | void gen_readc(const char name[]); | 31 | void gen_readc(const char name[], Scope scope); |
37 | 32 | ||
38 | void gen_print(int type); | 33 | void gen_print(int type); |
39 | 34 | ||
diff --git a/src/symbol_table.c b/src/symbol_table.c index 08124ac..68e24f0 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c | |||
@@ -228,3 +228,23 @@ void check_expected_type(int type_to_check, int type_expected) { | |||
228 | string_of_type(type_expected), string_of_type(type_to_check), | 228 | string_of_type(type_expected), string_of_type(type_to_check), |
229 | lineno); | 229 | lineno); |
230 | } | 230 | } |
231 | |||
232 | /* returns false if symbol can't be found too */ | ||
233 | bool is_read_only(const char name[], Scope scope) { | ||
234 | int count; | ||
235 | |||
236 | switch (scope) { | ||
237 | case LOCAL: | ||
238 | for (count = 0; count < loc_symbol_table.size; count++) | ||
239 | if (!strcmp(loc_symbol_table.entries[count].name, name)) | ||
240 | return loc_symbol_table.entries[count].read_only; | ||
241 | |||
242 | case GLOBAL: | ||
243 | for (count = 0; count < glo_symbol_table.size; count++) | ||
244 | if (!strcmp(glo_symbol_table.entries[count].name, name)) | ||
245 | return glo_symbol_table.entries[count].read_only; | ||
246 | |||
247 | default: | ||
248 | return false; | ||
249 | } | ||
250 | } | ||
diff --git a/src/symbol_table.h b/src/symbol_table.h index b2c8879..23cd618 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h | |||
@@ -15,6 +15,11 @@ | |||
15 | #define MAXSYMBOLS 256 | 15 | #define MAXSYMBOLS 256 |
16 | #define MAXFUNCTIONS 256 | 16 | #define MAXFUNCTIONS 256 |
17 | 17 | ||
18 | typedef enum scope { | ||
19 | GLOBAL, | ||
20 | LOCAL | ||
21 | } Scope; | ||
22 | |||
18 | typedef enum type { | 23 | typedef enum type { |
19 | INT, | 24 | INT, |
20 | CHAR, | 25 | CHAR, |
@@ -54,12 +59,15 @@ void glo_addConst(const char name[]); | |||
54 | int glo_lookup(const char name[]); | 59 | int glo_lookup(const char name[]); |
55 | int glo_get_addr(const char name[]); | 60 | int glo_get_addr(const char name[]); |
56 | void glo_display_table(); | 61 | void glo_display_table(); |
62 | |||
57 | void loc_addVar(const char name[], int type); | 63 | void loc_addVar(const char name[], int type); |
58 | void loc_addConst(const char name[]); | 64 | void loc_addConst(const char name[]); |
59 | int loc_lookup(const char name[]); | 65 | int loc_lookup(const char name[]); |
60 | int loc_get_addr(const char name[]); | 66 | int loc_get_addr(const char name[]); |
61 | void loc_display_table(); | 67 | void loc_display_table(); |
62 | void loc_clean_table(); | 68 | void loc_clean_table(); |
69 | |||
63 | void check_expected_type(int type_to_check, int type_expected); | 70 | void check_expected_type(int type_to_check, int type_expected); |
71 | bool is_read_only(const char name[], Scope scope); | ||
64 | 72 | ||
65 | #endif | 73 | #endif |
@@ -121,8 +121,8 @@ Instr: | |||
121 | | ';' | 121 | | ';' |
122 | | RETURN Exp ';' { gen_function_return(return_type, $<type>2); } | 122 | | RETURN Exp ';' { gen_function_return(return_type, $<type>2); } |
123 | | RETURN ';' { gen_function_return(return_type, VOID_T);} | 123 | | RETURN ';' { gen_function_return(return_type, VOID_T);} |
124 | | READE '(' IDENT ')' ';' { gen_reade($<ident>3); } | 124 | | READE '(' IDENT ')' ';' { gen_reade($<ident>3, scope); } |
125 | | READC '(' IDENT ')' ';' { gen_readc($<ident>3); } | 125 | | READC '(' IDENT ')' ';' { gen_readc($<ident>3, scope); } |
126 | | PRINT '(' Exp ')' ';' { gen_print($<type>3);} | 126 | | PRINT '(' Exp ')' ';' { gen_print($<type>3);} |
127 | | IF '(' Exp IfHandling')' Instr { gen_if_label($<num>4); } | 127 | | IF '(' Exp IfHandling')' Instr { gen_if_label($<num>4); } |
128 | | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling | 128 | | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling |