Mais um atributo redundante removido: is_parameter de Symbol.
[toypasc.git] / c_codegen_visitor.c
blobc914a928317f7522c2f20cee1c495e66f128b3ca
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include "c_codegen_visitor.h"
6 static char *pf_name;
7 static int tmp_var = 0;
9 static void _tab(struct AstNode *node);
10 static char *_get_type_string(Type type);
11 static char *_create_temporary();
12 static void _print_op_symbol(struct AstNode *node);
14 Visitor *
15 c_codegen_new()
17 Visitor *visitor = (Visitor *) malloc (sizeof(Visitor));
19 visitor->visit_program = &c_codegen_visit_program;
20 visitor->visit_programdecl = &c_codegen_visit_programdecl;
21 visitor->visit_vardecl_list = &c_codegen_visit_vardecl_list;
22 visitor->visit_vardecl = &c_codegen_visit_vardecl;
23 visitor->visit_identifier_list = &c_codegen_visit_identifier_list;
24 visitor->visit_procfunc_list = &c_codegen_visit_procfunc_list;
25 visitor->visit_procedure = &c_codegen_visit_procfunc;
26 visitor->visit_function = &c_codegen_visit_procfunc;
27 visitor->visit_param_list = &c_codegen_visit_param_list;
28 visitor->visit_parameter = &c_codegen_visit_parameter;
29 visitor->visit_statement_list = &c_codegen_visit_statement_list;
30 visitor->visit_printint_stmt = &c_codegen_visit_printint_stmt;
31 visitor->visit_printchar_stmt = &c_codegen_visit_printchar_stmt;
32 visitor->visit_printbool_stmt = &c_codegen_visit_printbool_stmt;
33 visitor->visit_printline_stmt = &c_codegen_visit_printline_stmt;
34 visitor->visit_assignment_stmt = &c_codegen_visit_assignment_stmt;
35 visitor->visit_if_stmt = &c_codegen_visit_if_stmt;
36 visitor->visit_while_stmt = &c_codegen_visit_while_stmt;
37 visitor->visit_for_stmt = &c_codegen_visit_for_stmt;
38 visitor->visit_rel_expr = &c_codegen_visit_binary_expr;
39 visitor->visit_add_expr = &c_codegen_visit_binary_expr;
40 visitor->visit_mul_expr = &c_codegen_visit_binary_expr;
41 visitor->visit_notfactor = &c_codegen_visit_notfactor;
42 visitor->visit_call = &c_codegen_visit_call;
43 visitor->visit_callparam_list = &c_codegen_visit_callparam_list;
44 visitor->visit_callparam = NULL;
45 visitor->visit_identifier = &c_codegen_visit_identifier;
46 visitor->visit_literal = &c_codegen_visit_literal;
47 visitor->visit_add_op = &c_codegen_visit_binary_op;
48 visitor->visit_mul_op = &c_codegen_visit_binary_op;
49 visitor->visit_rel_op = &c_codegen_visit_binary_op;
50 visitor->visit_not_op = &c_codegen_visit_not_op;
52 return visitor;
55 void
56 c_codegen_visit_program(struct _Visitor *visitor, struct AstNode *node)
58 struct AstNode *child;
60 printf("/* Generated with toypasc */\n");
61 for (child = node->children;
62 child != NULL && child->kind != STATEMENT_LIST;
63 child = child->sibling) {
64 ast_node_accept(child, visitor);
65 printf("\n");
68 if (child != NULL) {
69 printf("int\nmain(int argc, char **argv)\n{\n");
70 ast_node_accept(child, visitor);
71 printf("\n"TAB"return 0;\n}\n\n");
75 void
76 c_codegen_visit_programdecl(struct _Visitor *visitor, struct AstNode *node)
78 printf("/* program ");
79 ast_node_accept(node->children, visitor);
80 printf("; */\n\n");
81 printf("#include <stdio.h>\n\n");
82 printf("#ifndef FALSE\n#define FALSE\t0\n#endif\n\n");
83 printf("#ifndef TRUE\n#define TRUE\t1\n#endif\n");
86 void
87 c_codegen_visit_vardecl_list (struct _Visitor *visitor, struct AstNode *node)
89 ast_node_accept_children(node->children, visitor);
90 printf("\n");
93 void
94 c_codegen_visit_identifier_list (struct _Visitor *visitor, struct AstNode *node)
96 struct AstNode *child;
98 for (child = node->children; child != NULL; child = child->sibling) {
99 ast_node_accept(child, visitor);
100 if (child->sibling != NULL)
101 printf(", ");
105 void
106 c_codegen_visit_procfunc_list (struct _Visitor *visitor, struct AstNode *node)
108 ast_node_accept_children(node->children, visitor);
111 void
112 c_codegen_visit_procfunc (struct _Visitor *visitor, struct AstNode *node)
114 const char *type;
115 struct AstNode *child;
117 type = _get_type_string(node->type);
118 pf_name = _create_temporary();
120 printf("%s\n", type);
122 child = node->children; // Identifier
123 ast_node_accept(child, visitor);
125 printf(" (");
127 child = child->sibling;
128 if (child->kind == PARAM_LIST) {
129 ast_node_accept(child, visitor);
130 child = child->sibling;
133 printf(")\n{\n");
135 if (node->kind == FUNCTION)
136 printf(TAB"%s %s;\n", type, pf_name);
138 if (child->kind == VARDECL_LIST) {
139 ast_node_accept(child, visitor);
140 child = child->sibling;
143 printf("\n");
145 ast_node_accept(child, visitor);
147 if (node->kind == FUNCTION)
148 printf("\n"TAB"return %s;\n", pf_name);
149 printf("}\n\n");
151 free(pf_name);
154 void
155 c_codegen_visit_param_list (struct _Visitor *visitor, struct AstNode *node)
157 struct AstNode *child;
159 for (child = node->children; child != NULL; child = child->sibling) {
160 printf("%s ", _get_type_string(child->type));
161 ast_node_accept(child, visitor);
162 if (child->sibling != NULL)
163 printf(", ");
167 void
168 c_codegen_visit_statement_list (struct _Visitor *visitor, struct AstNode *node)
170 struct AstNode *child;
172 for (child = node->children; child != NULL; child = child->sibling) {
173 _tab(child);
174 ast_node_accept(child, visitor);
175 printf("\n");
179 void
180 c_codegen_visit_binary_expr (struct _Visitor *visitor, struct AstNode *node)
182 ast_node_accept_children(node->children, visitor);
185 void
186 c_codegen_visit_callparam_list (struct _Visitor *visitor, struct AstNode *node)
188 ast_node_accept(node->children, visitor);
191 void
192 c_codegen_visit_identifier (struct _Visitor *visitor, struct AstNode *node)
194 printf("%s", node->symbol->name);
197 void
198 c_codegen_visit_literal (struct _Visitor *visitor, struct AstNode *node)
200 if (node->type == BOOLEAN) {
201 printf("%s", node->value.boolean ? "TRUE" : "FALSE");
202 } else
203 value_print(stdout, &node->value, node->type);
206 void
207 c_codegen_visit_vardecl (struct _Visitor *visitor, struct AstNode *node)
209 const char *type = _get_type_string(node->type);
211 printf(TAB"%s ", type);
212 ast_node_accept(node->children, visitor);
213 printf(";\n");
216 void
217 c_codegen_visit_parameter (struct _Visitor *visitor, struct AstNode *node)
219 ast_node_accept(node->children, visitor);
222 void
223 c_codegen_visit_printint_stmt (struct _Visitor *visitor, struct AstNode *node)
225 printf("printf(\"%%d\", ");
226 ast_node_accept(node->children, visitor);
227 printf(");");
230 void
231 c_codegen_visit_printchar_stmt (struct _Visitor *visitor, struct AstNode *node)
233 printf("printf(\"%%c\", ");
234 ast_node_accept(node->children, visitor);
235 printf(");");
238 void
239 c_codegen_visit_printbool_stmt (struct _Visitor *visitor, struct AstNode *node)
241 printf("printf(\"%%s\", ");
242 ast_node_accept(node->children, visitor);
243 printf(");");
246 void
247 c_codegen_visit_printline_stmt (struct _Visitor *visitor, struct AstNode *node)
249 printf("printf(\"\\n\");");
252 void
253 c_codegen_visit_assignment_stmt (struct _Visitor *visitor, struct AstNode *node)
255 ast_node_accept(node->children, visitor);
256 printf(" = ");
257 ast_node_accept(node->children->sibling, visitor);
258 printf(";");
261 void
262 c_codegen_visit_if_stmt (struct _Visitor *visitor, struct AstNode *node)
264 struct AstNode *child;
265 const char *var;
267 printf("if (");
268 child = node->children; // Expression
269 ast_node_accept(child, visitor);
270 printf(") {\n");
272 child = child->sibling; // If Statements
273 ast_node_accept(child, visitor);
275 printf("\n");
276 _tab(node);
277 printf("}");
279 child = child->sibling; // Else Statements
281 if (child != NULL) {
282 printf(" else {\n");
283 ast_node_accept(child, visitor);
284 printf("\n");
285 _tab(node);
286 printf("}");
288 printf("\n");
291 void
292 c_codegen_visit_while_stmt (struct _Visitor *visitor, struct AstNode *node)
294 struct AstNode *child;
295 const char *var;
297 printf("while (");
298 child = node->children; // Expression
299 ast_node_accept(child, visitor);
300 printf(") {\n");
302 child = child->sibling; // Statements
303 ast_node_accept(child, visitor);
305 _tab(node);
306 printf("}\n");
309 void
310 c_codegen_visit_for_stmt (struct _Visitor *visitor, struct AstNode *node)
312 struct AstNode *child;
313 const char *var;
315 printf("for (");
316 child = node->children; // Assignment
317 ast_node_accept(child, visitor);
319 var = child->children->symbol->name;
320 printf(" %s < ", var);
322 child = child->sibling; // Stop condition
323 ast_node_accept(child, visitor);
325 printf("; %s++) {\n", var);
327 child = child->sibling; // Statements
328 ast_node_accept_children(child, visitor);
330 printf("\n");
331 _tab(node);
332 printf("}\n");
335 void
336 c_codegen_visit_notfactor (struct _Visitor *visitor, struct AstNode *node)
338 ast_node_accept_children(node->children, visitor);
341 void
342 c_codegen_visit_call (struct _Visitor *visitor, struct AstNode *node)
344 printf("%s ();\n", node->symbol->name);
345 ast_node_accept(node->children, visitor);
348 void
349 c_codegen_visit_simplenode (struct _Visitor *visitor, struct AstNode *node)
351 ast_node_accept_children(node->children, visitor);
354 void
355 c_codegen_visit_binary_op (struct _Visitor *visitor, struct AstNode *node)
357 _print_op_symbol(node);
360 void
361 c_codegen_visit_not_op (struct _Visitor *visitor, struct AstNode *node)
363 printf(" !", node->name);
366 static void
367 _tab(struct AstNode *node) {
368 struct AstNode *parent;
369 for (parent = node->parent; parent->parent != NULL; parent = parent->parent)
370 printf(TAB);
373 static char
374 *_get_type_string(Type type)
376 switch (type) {
377 case INTEGER:
378 case BOOLEAN:
379 return "int";
380 break;
381 case CHAR:
382 return "char";
383 default:
384 return "void";
388 static char
389 *_create_temporary()
391 char *temp;
393 if (asprintf (&temp, "tmp%.5d", tmp_var) < 0)
394 return NULL;
396 tmp_var++;
397 return temp;
400 static void
401 _print_op_symbol(struct AstNode *node)
403 switch (node->kind) {
404 case T_OR:
405 printf(" || ");
406 break;
407 case T_AND:
408 printf(" && ");
409 break;
410 case T_EQUAL:
411 printf(" == ");
412 break;
413 case T_NOTEQUAL:
414 printf(" != ");
415 break;
416 case T_LESSER:
417 printf(" < ");
418 break;
419 case T_GREATER:
420 printf(" > ");
421 break;
422 case T_LESSEREQUAL:
423 printf(" <= ");
424 break;
425 case T_GREATEREQUAL:
426 printf(" >= ");
427 break;
428 case T_PLUS:
429 case T_MINUS:
430 case T_STAR:
431 case T_SLASH:
432 printf(" %s ", node->name);