Expressoes andando. Vou dormir.
[toypasc.git] / c_codegen_visitor.c
blob1d673c6221223a67e6b1d2591c216a5539d2d4e7
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_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\n");
81 printf("#ifndef FALSE\n#define FALSE\t0\n#endif\n\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_procfunc (struct _Visitor *visitor, struct AstNode *node)
113 const char *type;
114 struct AstNode *child;
116 type = _get_type_string(node->type);
117 pf_name = _create_temporary();
119 printf("%s\n", type);
121 child = node->children; // Identifier
122 ast_node_accept(child, visitor);
124 printf(" (");
126 child = child->sibling;
127 if (child->kind == PARAM_LIST) {
128 ast_node_accept(child, visitor);
129 child = child->sibling;
132 printf(")\n{\n");
134 if (node->kind == FUNCTION)
135 printf(TAB"%s %s;\n", type, pf_name);
137 if (child->kind == VARDECL_LIST) {
138 ast_node_accept(child, visitor);
139 child = child->sibling;
142 printf("\n");
144 ast_node_accept(child, visitor);
146 if (node->kind == FUNCTION)
147 printf("\n"TAB"return %s;\n", pf_name);
148 printf("}\n\n");
150 free(pf_name);
153 void
154 c_codegen_visit_param_list (struct _Visitor *visitor, struct AstNode *node)
156 struct AstNode *child;
158 for (child = node->children; child != NULL; child = child->sibling) {
159 printf("%s ", _get_type_string(child->type));
160 ast_node_accept(child, visitor);
161 if (child->sibling != NULL)
162 printf(", ");
166 void
167 c_codegen_visit_statement_list (struct _Visitor *visitor, struct AstNode *node)
169 struct AstNode *child;
171 for (child = node->children; child != NULL; child = child->sibling) {
172 _tab(child);
173 ast_node_accept(child, visitor);
174 printf("\n");
178 void
179 c_codegen_visit_binary_expr (struct _Visitor *visitor, struct AstNode *node)
181 ast_node_accept_children(node->children, visitor);
184 void
185 c_codegen_visit_callparam_list (struct _Visitor *visitor, struct AstNode *node)
187 ast_node_accept(node->children, visitor);
190 void
191 c_codegen_visit_identifier (struct _Visitor *visitor, struct AstNode *node)
193 printf("%s", node->symbol->name);
196 void
197 c_codegen_visit_literal (struct _Visitor *visitor, struct AstNode *node)
199 if (node->type == BOOLEAN) {
200 printf("%s", node->value.boolean ? "TRUE" : "FALSE");
201 } else
202 value_print(stdout, &node->value, node->type);
205 void
206 c_codegen_visit_vardecl (struct _Visitor *visitor, struct AstNode *node)
208 const char *type = _get_type_string(node->type);
210 printf(TAB"%s ", type);
211 ast_node_accept(node->children, visitor);
212 printf(";\n");
215 void
216 c_codegen_visit_parameter (struct _Visitor *visitor, struct AstNode *node)
218 ast_node_accept(node->children, visitor);
221 void
222 c_codegen_visit_printint_stmt (struct _Visitor *visitor, struct AstNode *node)
224 printf("printf(\"%%d\", ");
225 ast_node_accept(node->children, visitor);
226 printf(");");
229 void
230 c_codegen_visit_printchar_stmt (struct _Visitor *visitor, struct AstNode *node)
232 printf("printf(\"%%c\", ");
233 ast_node_accept(node->children, visitor);
234 printf(");");
237 void
238 c_codegen_visit_printbool_stmt (struct _Visitor *visitor, struct AstNode *node)
240 printf("printf(\"%%s\", ");
241 ast_node_accept(node->children, visitor);
242 printf(");");
245 void
246 c_codegen_visit_printline_stmt (struct _Visitor *visitor, struct AstNode *node)
248 printf("printf(\"\\n\");");
251 void
252 c_codegen_visit_assignment_stmt (struct _Visitor *visitor, struct AstNode *node)
254 ast_node_accept(node->children, visitor);
255 printf(" = ");
256 ast_node_accept(node->children->sibling, visitor);
257 printf(";");
260 void
261 c_codegen_visit_if_stmt (struct _Visitor *visitor, struct AstNode *node)
263 struct AstNode *child;
264 const char *var;
266 printf("if (");
267 child = node->children; // Expression
268 ast_node_accept(child, visitor);
269 printf(") {\n");
271 child = child->sibling; // If Statements
272 ast_node_accept(child, visitor);
274 printf("\n");
275 _tab(node);
276 printf("}");
278 child = child->sibling; // Else Statements
280 if (child != NULL) {
281 printf(" else {\n");
282 ast_node_accept(child, visitor);
283 printf("\n");
284 _tab(node);
285 printf("}");
287 printf("\n");
290 void
291 c_codegen_visit_while_stmt (struct _Visitor *visitor, struct AstNode *node)
293 struct AstNode *child;
294 const char *var;
296 printf("while (");
297 child = node->children; // Expression
298 ast_node_accept(child, visitor);
299 printf(") {\n");
301 child = child->sibling; // Statements
302 ast_node_accept(child, visitor);
304 _tab(node);
305 printf("}\n");
308 void
309 c_codegen_visit_for_stmt (struct _Visitor *visitor, struct AstNode *node)
311 struct AstNode *child;
312 const char *var;
314 printf("for (");
315 child = node->children; // Assignment
316 ast_node_accept(child, visitor);
318 var = child->children->symbol->name;
319 printf(" %s < ", var);
321 child = child->sibling; // Stop condition
322 ast_node_accept(child, visitor);
324 printf("; %s++) {\n", var);
326 child = child->sibling; // Statements
327 ast_node_accept_children(child, visitor);
329 printf("\n");
330 _tab(node);
331 printf("}\n");
334 void
335 c_codegen_visit_notfactor (struct _Visitor *visitor, struct AstNode *node)
337 ast_node_accept_children(node->children, visitor);
340 void
341 c_codegen_visit_call (struct _Visitor *visitor, struct AstNode *node)
343 printf("%s ();\n", node->symbol->name);
344 ast_node_accept(node->children, visitor);
347 void
348 c_codegen_visit_simplenode (struct _Visitor *visitor, struct AstNode *node)
350 ast_node_accept_children(node->children, visitor);
353 void
354 c_codegen_visit_binary_op (struct _Visitor *visitor, struct AstNode *node)
356 _print_op_symbol(node);
359 void
360 c_codegen_visit_not_op (struct _Visitor *visitor, struct AstNode *node)
362 printf(" !", node->name);
365 static void
366 _tab(struct AstNode *node) {
367 struct AstNode *parent;
368 for (parent = node->parent; parent->parent != NULL; parent = parent->parent)
369 printf(TAB);
372 static char
373 *_get_type_string(Type type)
375 switch (type) {
376 case INTEGER:
377 case BOOLEAN:
378 return "int";
379 break;
380 case CHAR:
381 return "char";
382 default:
383 return "void";
387 static char
388 *_create_temporary()
390 char *temp;
392 if (asprintf (&temp, "tmp%.5d", tmp_var) < 0)
393 return NULL;
395 tmp_var++;
396 return temp;
399 static void
400 _print_op_symbol(struct AstNode *node)
402 switch (node->kind) {
403 case T_OR:
404 printf(" || ");
405 break;
406 case T_AND:
407 printf(" && ");
408 break;
409 case T_EQUAL:
410 printf(" == ");
411 break;
412 case T_NOTEQUAL:
413 printf(" != ");
414 break;
415 case T_LESSER:
416 printf(" < ");
417 break;
418 case T_GREATER:
419 printf(" > ");
420 break;
421 case T_LESSEREQUAL:
422 printf(" <= ");
423 break;
424 case T_GREATEREQUAL:
425 printf(" >= ");
426 break;
427 case T_PLUS:
428 case T_MINUS:
429 case T_STAR:
430 case T_SLASH:
431 printf(" %s ", node->name);