aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpacien2018-06-05 22:41:15 +0200
committerpacien2018-06-05 22:41:15 +0200
commit0f4b1600983f8afda41a02fec07424338785d81d (patch)
treecd1a3b2f599f7242c9fe76f9d66ca95ba58e34c0
parent864653f00dff0a8a1f37d8e9a732c1da8309a930 (diff)
downloadtpc-compiler-0f4b1600983f8afda41a02fec07424338785d81d.tar.gz
Prevent assigning to const
-rw-r--r--src/generator.c20
-rw-r--r--src/generator.h9
-rw-r--r--src/symbol_table.c20
-rw-r--r--src/symbol_table.h8
-rw-r--r--src/tpc.y4
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 -----
162void gen_reade(const char name[]) { 162void 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
177void gen_readc(const char name[]) { 182void 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) {
233int gen_assign(const char ident[], Scope scope) { 243int 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
13typedef enum scope {
14 GLOBAL,
15 LOCAL
16} Scope;
17
18extern int nb_globals; 13extern int nb_globals;
19extern int lineno; 14extern int lineno;
20FILE *output; 15FILE *output;
@@ -32,8 +27,8 @@ Type gen_function_call(const char name[], int nb_param);
32void gen_declaration(const char name[], int type, Scope scope); 27void gen_declaration(const char name[], int type, Scope scope);
33void gen_check(const char name[], Scope scope); 28void gen_check(const char name[], Scope scope);
34 29
35void gen_reade(const char name[]); 30void gen_reade(const char name[], Scope scope);
36void gen_readc(const char name[]); 31void gen_readc(const char name[], Scope scope);
37 32
38void gen_print(int type); 33void 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 */
233bool 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
18typedef enum scope {
19 GLOBAL,
20 LOCAL
21} Scope;
22
18typedef enum type { 23typedef enum type {
19 INT, 24 INT,
20 CHAR, 25 CHAR,
@@ -54,12 +59,15 @@ void glo_addConst(const char name[]);
54int glo_lookup(const char name[]); 59int glo_lookup(const char name[]);
55int glo_get_addr(const char name[]); 60int glo_get_addr(const char name[]);
56void glo_display_table(); 61void glo_display_table();
62
57void loc_addVar(const char name[], int type); 63void loc_addVar(const char name[], int type);
58void loc_addConst(const char name[]); 64void loc_addConst(const char name[]);
59int loc_lookup(const char name[]); 65int loc_lookup(const char name[]);
60int loc_get_addr(const char name[]); 66int loc_get_addr(const char name[]);
61void loc_display_table(); 67void loc_display_table();
62void loc_clean_table(); 68void loc_clean_table();
69
63void check_expected_type(int type_to_check, int type_expected); 70void check_expected_type(int type_to_check, int type_expected);
71bool is_read_only(const char name[], Scope scope);
64 72
65#endif 73#endif
diff --git a/src/tpc.y b/src/tpc.y
index d8fd1f1..64652d9 100644
--- a/src/tpc.y
+++ b/src/tpc.y
@@ -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