Iniciado trabalho com llvm_codegen_visitor.
[toypasc.git] / llvm_codegen_visitor.c
blob551c30f31a144e2c9665b4333f6b2fe05774692d
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include "llvm_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 llvm_codegen_new()
17 Visitor *visitor = (Visitor *) malloc (sizeof(Visitor));
19 visitor->visit_program = &llvm_codegen_visit_program;
20 visitor->visit_programdecl = &llvm_codegen_visit_programdecl;
21 visitor->visit_vardecl_list = &llvm_codegen_visit_vardecl_list;
22 visitor->visit_vardecl = &llvm_codegen_visit_vardecl;
23 visitor->visit_identifier_list = &llvm_codegen_visit_identifier_list;
24 visitor->visit_procfunc_list = &llvm_codegen_visit_procfunc_list;
25 visitor->visit_procedure = &llvm_codegen_visit_procfunc;
26 visitor->visit_function = &llvm_codegen_visit_procfunc;
27 visitor->visit_param_list = &llvm_codegen_visit_param_list;
28 visitor->visit_parameter = &llvm_codegen_visit_parameter;
29 visitor->visit_statement_list = &llvm_codegen_visit_statement_list;
30 visitor->visit_printint_stmt = &llvm_codegen_visit_printint_stmt;
31 visitor->visit_printchar_stmt = &llvm_codegen_visit_printchar_stmt;
32 visitor->visit_printbool_stmt = &llvm_codegen_visit_printbool_stmt;
33 visitor->visit_printline_stmt = &llvm_codegen_visit_printline_stmt;
34 visitor->visit_assignment_stmt = &llvm_codegen_visit_assignment_stmt;
35 visitor->visit_if_stmt = &llvm_codegen_visit_if_stmt;
36 visitor->visit_while_stmt = &llvm_codegen_visit_while_stmt;
37 visitor->visit_for_stmt = &llvm_codegen_visit_for_stmt;
38 visitor->visit_rel_expr = &llvm_codegen_visit_binary_expr;
39 visitor->visit_add_expr = &llvm_codegen_visit_binary_expr;
40 visitor->visit_mul_expr = &llvm_codegen_visit_binary_expr;
41 visitor->visit_notfactor = &llvm_codegen_visit_notfactor;
42 visitor->visit_call = &llvm_codegen_visit_call;
43 visitor->visit_callparam_list = &llvm_codegen_visit_callparam_list;
44 visitor->visit_identifier = &llvm_codegen_visit_identifier;
45 visitor->visit_literal = &llvm_codegen_visit_literal;
46 visitor->visit_add_op = &llvm_codegen_visit_binary_op;
47 visitor->visit_mul_op = &llvm_codegen_visit_binary_op;
48 visitor->visit_rel_op = &llvm_codegen_visit_binary_op;
49 visitor->visit_not_op = &llvm_codegen_visit_not_op;
51 return visitor;
54 void
55 llvm_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 llvm_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 llvm_codegen_visit_vardecl_list (struct _Visitor *visitor, struct AstNode *node)
88 ast_node_accept_children(node->children, visitor);
89 printf("\n");
92 void
93 llvm_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 llvm_codegen_visit_procfunc_list (struct _Visitor *visitor, struct AstNode *node)
107 ast_node_accept_children(node->children, visitor);
110 void
111 llvm_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 llvm_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 llvm_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 llvm_codegen_visit_binary_expr (struct _Visitor *visitor, struct AstNode *node)
181 ast_node_accept_children(node->children, visitor);
184 void
185 llvm_codegen_visit_callparam_list (struct _Visitor *visitor, struct AstNode *node)
187 ast_node_accept(node->children, visitor);
190 void
191 llvm_codegen_visit_identifier (struct _Visitor *visitor, struct AstNode *node)
193 printf("%s", node->symbol->name);
196 void
197 llvm_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 llvm_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 llvm_codegen_visit_parameter (struct _Visitor *visitor, struct AstNode *node)
218 ast_node_accept(node->children, visitor);
221 void
222 llvm_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 llvm_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 llvm_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 llvm_codegen_visit_printline_stmt (struct _Visitor *visitor, struct AstNode *node)
248 printf("printf(\"\\n\");");
249 ast_node_accept(node->children, visitor);
252 void
253 llvm_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 llvm_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 llvm_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 llvm_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 llvm_codegen_visit_notfactor (struct _Visitor *visitor, struct AstNode *node)
338 ast_node_accept_children(node->children, visitor);
341 void
342 llvm_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 llvm_codegen_visit_simplenode (struct _Visitor *visitor, struct AstNode *node)
351 ast_node_accept_children(node->children, visitor);
354 void
355 llvm_codegen_visit_binary_op (struct _Visitor *visitor, struct AstNode *node)
357 _print_op_symbol(node);
360 void
361 llvm_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);