diff options
-rw-r--r-- | src/generator.c | 60 | ||||
-rw-r--r-- | src/generator.h | 8 | ||||
-rw-r--r-- | src/tpc.y | 225 |
3 files changed, 158 insertions, 135 deletions
diff --git a/src/generator.c b/src/generator.c index 004e559..e547a23 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -96,8 +96,19 @@ void gen_ifelse_end(int idx) { | |||
96 | 96 | ||
97 | // ----- OPERATORS ----- | 97 | // ----- OPERATORS ----- |
98 | 98 | ||
99 | void gen_assign(int ident, Scope scope) { | 99 | int gen_assign(const char ident[], Scope scope) { |
100 | // TODO: what's "$$" and how do we extract it? | 100 | const char instr_fmt[] = "pop QWORD [rbp - %d] ;%s\n"; |
101 | |||
102 | switch (scope) { | ||
103 | case GLOBAL: | ||
104 | printf(instr_fmt, glo_get_addr(ident), ident); | ||
105 | return glo_lookup(ident); | ||
106 | case LOCAL: | ||
107 | printf(instr_fmt, loc_get_addr(ident), ident); | ||
108 | return loc_lookup(ident); | ||
109 | default: | ||
110 | exit(1); | ||
111 | } | ||
101 | } | 112 | } |
102 | 113 | ||
103 | void gen_or(int left, int right, int idx) { | 114 | void gen_or(int left, int right, int idx) { |
@@ -206,3 +217,48 @@ void gen_divstar(char op, int left, int right) { | |||
206 | } | 217 | } |
207 | } | 218 | } |
208 | 219 | ||
220 | int gen_signed_expr(char op, int type) { | ||
221 | switch (op) { | ||
222 | case '+': | ||
223 | printf(";+F\n"); | ||
224 | break; | ||
225 | case '-': | ||
226 | printf(";-F\npop rdx\nxor rax,rax\nsub rax,rdx\npush rax\n"); | ||
227 | break; | ||
228 | default: | ||
229 | exit(1); | ||
230 | } | ||
231 | |||
232 | return type; | ||
233 | } | ||
234 | |||
235 | int gen_negate_expr(int type) { | ||
236 | printf(";!F\npop rax\nxor rax,1\npush rax\n"); | ||
237 | return type; | ||
238 | } | ||
239 | |||
240 | int gen_value(const char ident[], Scope scope) { | ||
241 | switch (scope) { | ||
242 | case GLOBAL: | ||
243 | printf("push QWORD [rbp - %d] ;%s\n", glo_get_addr(ident), ident); | ||
244 | return glo_lookup(ident); | ||
245 | case LOCAL: | ||
246 | printf("push QWORD [rbp - %d] ;%s\n", loc_get_addr(ident), ident); | ||
247 | return loc_lookup(ident); | ||
248 | default: | ||
249 | exit(1); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | int gen_num(int value, Scope scope) { | ||
254 | if (scope == LOCAL) printf("push %d\n", value); // TODO: remove if? | ||
255 | // stored for the semantic analysis. | ||
256 | |||
257 | return INT; | ||
258 | } | ||
259 | |||
260 | int gen_char(int value, Scope scope) { | ||
261 | if(scope == LOCAL) printf("push %d\n", value); // TODO: remove if? | ||
262 | return CHAR; | ||
263 | } | ||
264 | |||
diff --git a/src/generator.h b/src/generator.h index 17ea662..c907f66 100644 --- a/src/generator.h +++ b/src/generator.h | |||
@@ -23,7 +23,7 @@ void gen_if_start(int idx); | |||
23 | void gen_if_end(int idx); | 23 | void gen_if_end(int idx); |
24 | void gen_ifelse_end(int idx); | 24 | void gen_ifelse_end(int idx); |
25 | 25 | ||
26 | void gen_assign(int ident, Scope scope); | 26 | int gen_assign(const char ident[], Scope scope); |
27 | void gen_or(int left, int right, int idx); | 27 | void gen_or(int left, int right, int idx); |
28 | void gen_and(int left, int right, int idx); | 28 | void gen_and(int left, int right, int idx); |
29 | void gen_eq(const char op[], int left, int right, int idx); | 29 | void gen_eq(const char op[], int left, int right, int idx); |
@@ -31,4 +31,10 @@ void gen_order(const char op[], int left, int right, int idx); | |||
31 | void gen_addsub(char op, int left, int right); | 31 | void gen_addsub(char op, int left, int right); |
32 | void gen_divstar(char op, int left, int right); | 32 | void gen_divstar(char op, int left, int right); |
33 | 33 | ||
34 | int gen_signed_expr(char op, int type); | ||
35 | int gen_negate_expr(int type); | ||
36 | int gen_value(const char ident[], Scope scope); | ||
37 | int gen_num(int value, Scope scope); | ||
38 | int gen_char(int value, Scope scope); | ||
39 | |||
34 | #endif | 40 | #endif |
@@ -50,167 +50,128 @@ static int num_if = 0; | |||
50 | 50 | ||
51 | %% | 51 | %% |
52 | Prog: { gen_prologue(); } | 52 | Prog: { gen_prologue(); } |
53 | DeclConsts DeclVars DeclFoncts { gen_const_declaration(); } | 53 | DeclConsts DeclVars DeclFoncts { gen_const_declaration(); } |
54 | ; | 54 | ; |
55 | DeclConsts: | 55 | DeclConsts: |
56 | DeclConsts CONST ListConst ';' | 56 | DeclConsts CONST ListConst ';' |
57 | | | 57 | | |
58 | ; | 58 | ; |
59 | ListConst: | 59 | ListConst: |
60 | ListConst ',' IDENT '=' Litteral | 60 | ListConst ',' IDENT '=' Litteral |
61 | | IDENT '=' Litteral | 61 | | IDENT '=' Litteral |
62 | ; | 62 | ; |
63 | Litteral: | 63 | Litteral: |
64 | NombreSigne | 64 | NombreSigne |
65 | | CARACTERE | 65 | | CARACTERE |
66 | ; | 66 | ; |
67 | NombreSigne: | 67 | NombreSigne: |
68 | NUM | 68 | NUM |
69 | | ADDSUB NUM | 69 | | ADDSUB NUM |
70 | ; | 70 | ; |
71 | DeclVars: | 71 | DeclVars: |
72 | DeclVars TYPE Declarateurs ';' | 72 | DeclVars TYPE Declarateurs ';' |
73 | | | 73 | | |
74 | ; | 74 | ; |
75 | Declarateurs: | 75 | Declarateurs: |
76 | Declarateurs ',' Declarateur { gen_declaration($<ident>3, $<type>0, scope); } | 76 | Declarateurs ',' Declarateur { gen_declaration($<ident>3, $<type>0, scope); } |
77 | | Declarateur { gen_declaration($<ident>1, $<type>0, scope); } | 77 | | Declarateur { gen_declaration($<ident>1, $<type>0, scope); } |
78 | ; | 78 | ; |
79 | Declarateur: | 79 | Declarateur: |
80 | IDENT | 80 | IDENT |
81 | | IDENT '[' NUM ']' | 81 | | IDENT '[' NUM ']' |
82 | ; | 82 | ; |
83 | DeclFoncts: | 83 | DeclFoncts: |
84 | DeclFoncts DeclFonct | 84 | DeclFoncts DeclFonct |
85 | | DeclFonct | 85 | | DeclFonct |
86 | ; | 86 | ; |
87 | DeclFonct: | 87 | DeclFonct: |
88 | EnTeteFonct { scope = LOCAL; } | 88 | EnTeteFonct { scope = LOCAL; } |
89 | Corps { scope = GLOBAL; } | 89 | Corps { scope = GLOBAL; } |
90 | ; | 90 | ; |
91 | EnTeteFonct: | 91 | EnTeteFonct: |
92 | TYPE IDENT '(' Parametres ')' | 92 | TYPE IDENT '(' Parametres ')' |
93 | | VOID IDENT '(' Parametres ')' | 93 | | VOID IDENT '(' Parametres ')' |
94 | ; | 94 | ; |
95 | Parametres: | 95 | Parametres: |
96 | VOID | 96 | VOID |
97 | | ListTypVar | 97 | | ListTypVar |
98 | ; | 98 | ; |
99 | ListTypVar: | 99 | ListTypVar: |
100 | ListTypVar ',' TYPE IDENT { gen_declaration($<ident>4, $<type>3, scope); } | 100 | ListTypVar ',' TYPE IDENT { gen_declaration($<ident>4, $<type>3, scope); } |
101 | | TYPE IDENT { gen_declaration($<ident>2, $<type>1, scope); } | 101 | | TYPE IDENT { gen_declaration($<ident>2, $<type>1, scope); } |
102 | ; | 102 | ; |
103 | Corps: | 103 | Corps: |
104 | '{' DeclConsts DeclVars SuiteInstr '}' | 104 | '{' DeclConsts DeclVars SuiteInstr '}' |
105 | ; | 105 | ; |
106 | SuiteInstr: | 106 | SuiteInstr: |
107 | SuiteInstr Instr | 107 | SuiteInstr Instr |
108 | | | 108 | | |
109 | ; | 109 | ; |
110 | Instr: | 110 | Instr: |
111 | Exp ';' | 111 | Exp ';' |
112 | | ';' | 112 | | ';' |
113 | | RETURN Exp ';' | 113 | | RETURN Exp ';' |
114 | | RETURN ';' | 114 | | RETURN ';' |
115 | | READE '(' IDENT ')' ';' { gen_read($<ident>3, scope); } | 115 | | READE '(' IDENT ')' ';' { gen_read($<ident>3, scope); } |
116 | | READC '(' IDENT ')' ';' { gen_read($<ident>3, scope); } | 116 | | READC '(' IDENT ')' ';' { gen_read($<ident>3, scope); } |
117 | | PRINT '(' Exp ')' ';' { gen_print();} | 117 | | PRINT '(' Exp ')' ';' { gen_print();} |
118 | | IF '(' Exp IfHandling')' Instr { gen_if_label($<num>4); } | 118 | | IF '(' Exp IfHandling')' Instr { gen_if_label($<num>4); } |
119 | | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling | 119 | | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling |
120 | | WHILE '(' Exp ')' Instr | 120 | | WHILE '(' Exp ')' Instr |
121 | | '{' SuiteInstr '}' | 121 | | '{' SuiteInstr '}' |
122 | ; | 122 | ; |
123 | IfHandling: { gen_if_start($<num>$ = num_if++); }; | 123 | IfHandling: { gen_if_start($<num>$ = num_if++); }; |
124 | IfEndHandling: { gen_if_end($<num>-3); }; | 124 | IfEndHandling: { gen_if_end($<num>-3); }; |
125 | IfElseEndHandling: { gen_ifelse_end($<num>-5); }; | 125 | IfElseEndHandling: { gen_ifelse_end($<num>-5); }; |
126 | Exp: | 126 | Exp: |
127 | LValue '=' Exp { /* TODO: extract this into func */ | 127 | LValue '=' Exp { $$ = gen_assign($<ident>1, scope); } |
128 | if(scope == GLOBAL){ | 128 | | EB |
129 | $$ = glo_lookup($<ident>1); | 129 | ; |
130 | printf("pop QWORD [rbp - %d] ;%s\n",glo_get_addr($<ident>1),$<ident>1); | ||
131 | } | ||
132 | else { | ||
133 | $$ = loc_lookup($<ident>1); | ||
134 | printf("pop QWORD [rbp - %d] ;%s\n",loc_get_addr($<ident>1),$<ident>1); | ||
135 | } | ||
136 | } | ||
137 | | EB | ||
138 | ; | ||
139 | EB: | 130 | EB: |
140 | EB OR TB { gen_or($1, $3, num_label++); } | 131 | EB OR TB { gen_or($1, $3, num_label++); } |
141 | | TB | 132 | | TB |
142 | ; | 133 | ; |
143 | TB: | 134 | TB: |
144 | TB AND FB { gen_and($1, $3, num_label++); } | 135 | TB AND FB { gen_and($1, $3, num_label++); } |
145 | | FB | 136 | | FB |
146 | ; | 137 | ; |
147 | FB: | 138 | FB: |
148 | FB EQ M { gen_eq($2, $1, $3, num_label++); } | 139 | FB EQ M { gen_eq($2, $1, $3, num_label++); } |
149 | | M | 140 | | M |
150 | ; | 141 | ; |
151 | M: | 142 | M: |
152 | M ORDER E { gen_order($2, $1, $3, num_label++); } | 143 | M ORDER E { gen_order($2, $1, $3, num_label++); } |
153 | | E | 144 | | E |