Adicionado suporte a opcoes da linha de comando com getopt.
[toypasc.git] / c_codegen_visitor.c
blob2b342a2cda32396a477f9f25efbaeeba3b3b8974
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_procedure;
26 visitor->visit_function = &c_codegen_visit_function;
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_identifier = &c_codegen_visit_identifier;
45 visitor->visit_literal = &c_codegen_visit_literal;
46 visitor->visit_add_op = &c_codegen_visit_binary_op;
47 visitor->visit_mul_op = &c_codegen_visit_binary_op;
48 visitor->visit_rel_op = &c_codegen_visit_binary_op;
49 visitor->visit_not_op = &c_codegen_visit_not_op;
51 return visitor;
54 void
55 c_codegen_visit_program(struct _Visitor *visitor, struct AstNode *node)
57 struct AstNode *child;
59 printf("/* Generated with toypasc */\n");
60 for (child = node->children;
61 child != NULL && child->kind != STATEMENT_LIST;
62 child = child->sibling) {
63 ast_node_accept(child, visitor);
64 printf("\n");
67 if (child != NULL) {
68 printf("int\nmain(int argc, char **argv)\n{\n");
69 ast_node_accept(child, visitor);
70 printf("\n"TAB"return 0;\n}\n\n");
74 void
75 c_codegen_visit_programdecl(struct _Visitor *visitor, struct AstNode *node)
77 printf("/* program ");
78 ast_node_accept(node->children, visitor);
79 printf("; */\n\n");
80 printf("#include <stdio.h>\n");
81 printf("#ifndef FALSE\n#define FALSE\t0\n#endif\n");
82 printf("#ifndef TRUE\n#define TRUE\t1\n#endif\n");
85 void
86 c_codegen_visit_vardecl_list (struct _Visitor *visitor, struct AstNode *node)
88 ast_node_accept_children(node->children, visitor);
89 printf("\n");
92 void
93 c_codegen_visit_identifier_list (struct _Visitor *visitor, struct AstNode *node)
95 struct AstNode *child;
97 for (child = node->children; child != NULL; child = child->sibling) {
98 ast_node_accept(child, visitor);
99 if (child->sibling != NULL)
100 printf(", ");
104 void
105 c_codegen_visit_procfunc_list (struct _Visitor *visitor, struct AstNode *node)
107 ast_node_accept_children(node->children, visitor);
110 void
111 c_codegen_visit_procedure (struct _Visitor *visitor, struct AstNode *node)
113 printf("void\n%s ()\n{\n", node->children->symbol->name);
114 printf(TAB"/* declaracoes */\n\n");
116 ast_node_accept(node->children, visitor);
118 printf("}\n\n");
121 void
122 c_codegen_visit_function (struct _Visitor *visitor, struct AstNode *node)
124 const char *type;
125 struct AstNode *child;
127 type = _get_type_string(node->type);
128 pf_name = _create_temporary();
130 printf("%s\n", type);
132 child = node->children; // Identifier
133 ast_node_accept(child, visitor);
135 printf(" (");
137 child = child->sibling;
138 if (child->kind == PARAM_LIST) {
139 ast_node_accept(child, visitor);
140 child = child->sibling;
143 printf(")\n{\n");
145 printf(TAB"%s %s;\n", type, pf_name);
147 if (child->kind == VARDECL_LIST) {
148 ast_node_accept(child, visitor);
149 child = child->sibling;
152 printf("\n");
154 ast_node_accept(child, visitor);
156 printf("\n"TAB"return %s;\n}\n\n", pf_name);
157 free(pf_name);
160 void
161 c_codegen_visit_param_list (struct _Visitor *visitor, struct AstNode *node)
163 struct AstNode *child;
165 for (child = node->children; child != NULL; child = child->sibling) {
166 printf("%s ", _get_type_string(child->type));
167 ast_node_accept(child, visitor);
168 if (child->sibling != NULL)
169 printf(", ");
173 void
174 c_codegen_visit_statement_list (struct _Visitor *visitor, struct AstNode *node)
176 struct AstNode *child;
178 for (child = node->children; child != NULL; child = child->sibling) {
179 _tab(child);
180 ast_node_accept(child, visitor);
181 printf("\n");
185 void
186 c_codegen_visit_binary_expr (struct _Visitor *visitor, struct AstNode *node)
188 ast_node_accept_children(node->children, visitor);
191 void
192 c_codegen_visit_callparam_list (struct _Visitor *visitor, struct AstNode *node)
194 ast_node_accept(node->children, visitor);
197 void
198 c_codegen_visit_identifier (struct _Visitor *visitor, struct AstNode *node)
200 printf("%s", node->symbol->name);
203 void
204 c_codegen_visit_literal (struct _Visitor *visitor, struct AstNode *node)
206 if (node->type == BOOLEAN) {
207 printf("%s", node->value.boolean ? "TRUE" : "FALSE");
208 } else
209 value_print(&node->value, node->type);
212 void
213 c_codegen_visit_vardecl (struct _Visitor *visitor, struct AstNode *node)
215 const char *type = _get_type_string(node->type);
217 printf(TAB"%s ", type);
218 ast_node_accept(node->children, visitor);
219 printf(";\n");
222 void
223 c_codegen_visit_parameter (struct _Visitor *visitor, struct AstNode *node)
225 ast_node_accept(node->children, visitor);
228 void
229 c_codegen_visit_printint_stmt (struct _Visitor *visitor, struct AstNode *node)
231 printf("printf(\"%%d\", ");
232 ast_node_accept(node->children, visitor);
233 printf(");");
236 void
237 c_codegen_visit_printchar_stmt (struct _Visitor *visitor, struct AstNode *node)
239 printf("printf(\"%%c\", ");
240 ast_node_accept(node->children, visitor);
241 printf(");");
244 void
245 c_codegen_visit_printbool_stmt (struct _Visitor *visitor, struct AstNode *node)
247 printf("printf(\"%%s\", ");
248 ast_node_accept(node->children, visitor);
249 printf(");");
252 void
253 c_codegen_visit_printline_stmt (struct _Visitor *visitor, struct AstNode *node)
255 printf("printf(\"\\n\");");
256 ast_node_accept(node->children, visitor);
259 void
260 c_codegen_visit_assignment_stmt (struct _Visitor *visitor, struct AstNode *node)
262 ast_node_accept(node->children, visitor);
263 printf(" = ");
264 ast_node_accept(node->children->sibling, visitor);
265 printf(";");
268 void
269 c_codegen_visit_if_stmt (struct _Visitor *visitor, struct AstNode *node)
271 struct AstNode *child;
272 const char *var;
274 printf("if (");
275 child = node->children; // Expression
276 ast_node_accept(child, visitor);
277 printf(") {\n");
279 child = child->sibling; // If Statements
280 ast_node_accept(child, visitor);
282 printf("\n");
283 _tab(node);
284 printf("}");
286 child = child->sibling; // Else Statements
288 if (child != NULL) {
289 printf(" else {\n");
290 ast_node_accept(child, visitor);
291 printf("\n");
292 _tab(node);
293 printf("}");
295 printf("\n");
298 void
299 c_codegen_visit_while_stmt (struct _Visitor *visitor, struct AstNode *node)
301 struct AstNode *child;
302 const char *var;
304 printf("while (");
305 child = node->children; // Expression
306 ast_node_accept(child, visitor);
307 printf(") {\n");
309 child = child->sibling; // Statements
310 ast_node_accept(child, visitor);
312 _tab(node);
313 printf("}\n");
316 void
317 c_codegen_visit_for_stmt (struct _Visitor *visitor, struct AstNode *node)
319 struct AstNode *child;
320 const char *var;
322 printf("for (");
323 child = node->children; // Assignment
324 ast_node_accept(child, visitor);
326 var = child->children->symbol->name;
327 printf(" %s < ", var);
329 child = child->sibling; // Stop condition
330 ast_node_accept(child, visitor);
332 printf("; %s++) {\n", var);
334 child = child->sibling; // Statements
335 ast_node_accept_children(child, visitor);
337 _tab(node);
338 printf("}\n");
341 void
342 c_codegen_visit_notfactor (struct _Visitor *visitor, struct AstNode *node)
344 ast_node_accept_children(node->children, visitor);
347 void
348 c_codegen_visit_call (struct _Visitor *visitor, struct AstNode *node)
350 printf("%s ();\n", node->symbol->name);
351 ast_node_accept(node->children, visitor);
354 void
355 c_codegen_visit_simplenode (struct _Visitor *visitor, struct AstNode *node)
357 ast_node_accept_children(node->children, visitor);
360 void
361 c_codegen_visit_binary_op (struct _Visitor *visitor, struct AstNode *node)
363 _print_op_symbol(node);
366 void
367 c_codegen_visit_not_op (struct _Visitor *visitor, struct AstNode *node)
369 printf(" !", node->name);
372 static void
373 _tab(struct AstNode *node) {
374 struct AstNode *parent;
375 for (parent = node->parent; parent->parent != NULL; parent = parent->parent)
376 printf(TAB);
379 static char
380 *_get_type_string(Type type)
382 switch (type) {
383 case INTEGER:
384 case BOOLEAN:
385 return "int";
386 break;
387 case CHAR:
388 return "char";
390 return "void";
393 static char
394 *_create_temporary()
396 char *temp;
398 if (asprintf (&temp, "tmp%.5d", tmp_var) < 0)
399 return NULL;
401 tmp_var++;
402 return temp;
405 static void
406 _print_op_symbol(struct AstNode *node)
408 switch (node->kind) {
409 case T_OR:
410 printf(" || ");
411 break;
412 case T_AND:
413 printf(" && ");
414 break;
415 case T_EQUAL:
416 printf(" == ");
417 break;
418 case T_NOTEQUAL:
419 printf(" != ");
420 break;
421 case T_LESSER:
422 printf(" < ");
423 break;
424 case T_GREATER:
425 printf(" > ");
426 break;
427 case T_LESSEREQUAL:
428 printf(" <= ");
429 break;
430 case T_GREATEREQUAL:
431 printf(" >= ");
432 break;
433 case T_PLUS:
434 case T_MINUS:
435 case T_STAR:
436 case T_SLASH:
437 printf(" %s ", node->name);