Mais um atributo redundante removido: is_parameter de Symbol.
[toypasc.git] / llvm_codegen_visitor.c
blobe0193a59b3f97389063014b7d78ef9a280ffa9cc
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include "llvm_codegen_visitor.h"
6 static int stack_size = -1;
8 static void _print_boolean(struct AstNode *node);
9 static void _print_load(struct AstNode *node, Visitor *visitor);
10 static int _get_type_size(Type type);
11 static int _process_expression(struct AstNode *rnode, Visitor *visitor);
13 Visitor *
14 llvm_codegen_new()
16 Visitor *visitor = (Visitor *) malloc (sizeof(Visitor));
18 visitor->visit_program = &llvm_codegen_visit_program;
19 visitor->visit_programdecl = &llvm_codegen_visit_programdecl;
20 visitor->visit_vardecl_list = &llvm_codegen_visit_vardecl_list;
21 visitor->visit_vardecl = &llvm_codegen_visit_vardecl;
22 visitor->visit_identifier_list = &llvm_codegen_visit_identifier_list;
23 visitor->visit_procfunc_list = &llvm_codegen_visit_procfunc_list;
24 visitor->visit_procedure = &llvm_codegen_visit_procfunc;
25 visitor->visit_function = &llvm_codegen_visit_procfunc;
26 visitor->visit_param_list = &llvm_codegen_visit_param_list;
27 visitor->visit_parameter = &llvm_codegen_visit_parameter;
28 visitor->visit_statement_list = &llvm_codegen_visit_statement_list;
29 visitor->visit_printint_stmt = &llvm_codegen_visit_printint_stmt;
30 visitor->visit_printchar_stmt = &llvm_codegen_visit_printchar_stmt;
31 visitor->visit_printbool_stmt = &llvm_codegen_visit_printbool_stmt;
32 visitor->visit_printline_stmt = &llvm_codegen_visit_printline_stmt;
33 visitor->visit_assignment_stmt = &llvm_codegen_visit_assignment_stmt;
34 visitor->visit_if_stmt = &llvm_codegen_visit_if_stmt;
35 visitor->visit_while_stmt = &llvm_codegen_visit_while_stmt;
36 visitor->visit_for_stmt = &llvm_codegen_visit_for_stmt;
37 visitor->visit_rel_expr = &llvm_codegen_visit_binary_expr;
38 visitor->visit_add_expr = &llvm_codegen_visit_binary_expr;
39 visitor->visit_mul_expr = &llvm_codegen_visit_binary_expr;
40 visitor->visit_notfactor = &llvm_codegen_visit_notfactor;
41 visitor->visit_call = &llvm_codegen_visit_call;
42 visitor->visit_callparam_list = &llvm_codegen_visit_callparam_list;
43 visitor->visit_callparam = &llvm_codegen_visit_callparam;
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);
66 if (child != NULL) {
67 printf("; Definition of main function\n");
68 printf("define i32 @main () {\nentry:\n");
69 ast_node_accept(child, visitor);
70 printf(TAB"ret i32 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("; Declare the string constants as a global constants...\n");
81 printf("@bool_str = global [2 x i8*] [ "
82 "i8* getelementptr ([6 x i8]* @.false_str, i32 0, i32 0), "
83 "i8* getelementptr ([5 x i8]* @.true_str, i32 0, i32 0) ]\n");
84 printf("@.false_str = internal constant [6 x i8] c\"false\\00\"\n");
85 printf("@.true_str = internal constant [5 x i8] c\"true\\00\"\n");
86 printf("@.int_fmt = internal constant [3 x i8] c\"%%d\\00\"\n");
87 printf("@.bool_fmt = internal constant [3 x i8] c\"%%s\\00\"\n");
89 printf("\n; External declaration of functions\n");
90 printf("declare i32 @puts(i8 *)\n");
91 printf("declare i32 @putchar(i32)\n");
92 printf("declare i32 @printf(i8*, ...)\n\n");
95 void
96 llvm_codegen_visit_vardecl_list (struct _Visitor *visitor, struct AstNode *node)
98 ast_node_accept_children(node->children, visitor);
99 if (node->parent->kind == PROGRAM)
100 printf("\n");
103 void
104 llvm_codegen_visit_identifier_list (struct _Visitor *visitor, struct AstNode *node)
106 struct AstNode *child;
108 /* FIXME */ fprintf(stderr, "Never reaches here?\n");
109 for (child = node->children; child != NULL; child = child->sibling) {
110 ast_node_accept(child, visitor);
111 if (child->sibling != NULL)
112 printf(", ");
116 void
117 llvm_codegen_visit_procfunc_list (struct _Visitor *visitor, struct AstNode *node)
119 ast_node_accept_children(node->children, visitor);
122 void
123 llvm_codegen_visit_procfunc (struct _Visitor *visitor, struct AstNode *node)
125 struct AstNode *child;
127 printf("define ");
128 PRINT_TYPE(node->type);
129 printf(" ");
131 child = node->children; // Identifier
132 ast_node_accept(child, visitor);
134 printf(" ( ");
136 child = child->sibling;
137 if (child->kind == PARAM_LIST) {
138 ast_node_accept(child, visitor);
139 child = child->sibling;
142 printf(" ) {\n");
143 printf("entry:\n");
145 if (child->kind == VARDECL_LIST) {
146 ast_node_accept(child, visitor);
147 child = child->sibling;
150 ast_node_accept(child, visitor);
152 printf(TAB"ret ");
153 PRINT_TYPE(node->type);
154 if (node->kind == FUNCTION) {
155 printf(" ");
156 PRINT_VALUE(node->children, node->children->symbol->stack_index);
159 printf("\n}\n\n");
162 void
163 llvm_codegen_visit_param_list (struct _Visitor *visitor, struct AstNode *node)
165 struct AstNode *child;
167 for (child = node->children; child != NULL; child = child->sibling) {
168 ast_node_accept(child, visitor);
169 if (child->sibling != NULL)
170 printf(", ");
174 void
175 llvm_codegen_visit_statement_list (struct _Visitor *visitor, struct AstNode *node)
177 struct AstNode *child;
179 stack_size = -1;
181 for (child = node->children; child != NULL; child = child->sibling) {
182 ast_node_accept(child, visitor);
183 printf("\n");
187 void
188 llvm_codegen_visit_binary_expr (struct _Visitor *visitor, struct AstNode *node)
190 int lindex = -1;
191 int rindex = -1;
192 struct AstNode *lnode = node->children;
193 struct AstNode *op = lnode->sibling;
194 struct AstNode *rnode = op->sibling;
196 int __process_binexpr_node(struct AstNode *node) {
197 if (node->kind == IDENTIFIER) {
198 if (node->symbol->is_global) {
199 if (symbol_is_procfunc(node->symbol))
200 return node->symbol->stack_index;
202 _print_load(node, visitor);
203 return stack_size;
206 } else if (!IS_LITERAL(node->kind)) {
207 ast_node_accept(node, visitor);
208 return stack_size;
211 return -1;
214 void __print_operand(struct AstNode *node, int index) {
215 if (index > -1)
216 printf("%%%d", index);
217 else if (node->symbol != NULL && symbol_is_procfunc(node->symbol))
218 printf("0");
219 else
220 ast_node_accept(node, visitor);
223 /* Construcao mais simples */
224 if (IS_LITERAL(lnode->kind) && IS_LITERAL(rnode->kind)) {
225 ast_node_accept(op, visitor);
226 printf(" ");
227 PRINT_TYPE(lnode->type);
228 printf(" ");
229 ast_node_accept(lnode, visitor);
230 printf(", ");
231 ast_node_accept(rnode, visitor);
232 printf("\n");
234 /* Construcoes complexas */
235 } else {
236 lindex = __process_binexpr_node(lnode);
237 rindex = __process_binexpr_node(rnode);
239 ast_node_accept(op, visitor);
240 printf(" ");
241 PRINT_TYPE(lnode->type);
242 printf(" ");
244 __print_operand(lnode, lindex);
245 printf(", ");
246 __print_operand(rnode, rindex);
248 printf("\n");
251 stack_size++;
254 void
255 llvm_codegen_visit_callparam_list (struct _Visitor *visitor, struct AstNode *node)
257 ast_node_accept(node->children, visitor);
260 void
261 llvm_codegen_visit_callparam (struct _Visitor *visitor, struct AstNode *node)
263 ast_node_accept(node->children, visitor);
266 void
267 llvm_codegen_visit_identifier (struct _Visitor *visitor, struct AstNode *node)
269 Symbol *sym = node->symbol;
271 if (sym->is_global || node->parent->kind == CALL)
272 printf("@%s", sym->name);
274 else if (!sym->is_global && node->parent->kind == PARAMETER &&
275 sym->stack_index == -1)
276 printf("%%%s", sym->name);
278 else if (sym->stack_index > -1)
279 printf("%%%d", sym->stack_index);
281 else
282 printf("0");
285 void
286 llvm_codegen_visit_literal (struct _Visitor *visitor, struct AstNode *node)
288 printf("%d", node->value.integer);
291 void
292 llvm_codegen_visit_vardecl (struct _Visitor *visitor, struct AstNode *node)
294 struct AstNode *child;
296 child = node->children;
298 for (child = child->children; child != NULL; child = child->sibling) {
299 if (node->parent->parent->kind == PROGRAM) {
300 ast_node_accept(child, visitor);
301 printf(" = global i%d 0\n", _get_type_size(child->type));
302 } else {
303 child->symbol->stack_index = -1;
308 void
309 llvm_codegen_visit_parameter (struct _Visitor *visitor, struct AstNode *node)
311 PRINT_TYPE(node->type);
312 printf(" ");
313 ast_node_accept(node->children, visitor);
316 void
317 llvm_codegen_visit_printint_stmt (struct _Visitor *visitor, struct AstNode *node)
319 int index = -1;
320 struct AstNode *child = node->children;
322 index = _process_expression(child, visitor);
324 printf(TAB"call i32 (i8* noalias , ...)* bitcast (i32 (i8*, ...)* \n");
325 printf(TAB TAB"@printf to i32 (i8* noalias, ...)*)\n");
326 printf(TAB TAB"( i8* getelementptr ");
327 printf("([3 x i8]* @.int_fmt, i32 0, i32 0) noalias ,\n");
328 printf(TAB TAB"i32 ");
329 PRINT_VALUE(child, index);
331 printf(" )\n");
332 stack_size++;
335 void
336 llvm_codegen_visit_printchar_stmt (struct _Visitor *visitor, struct AstNode *node)
338 int index = -1;
339 struct AstNode *child = node->children;
341 index = _process_expression(child, visitor);
343 printf(TAB"call i32 @putchar ( i32 ");
344 PRINT_VALUE(child, index);
345 printf(" )\n");
346 stack_size++;
349 void
350 llvm_codegen_visit_printbool_stmt (struct _Visitor *visitor, struct AstNode *node)
352 int index = -1;
353 struct AstNode *child = node->children;
355 index = _process_expression(child, visitor);
357 if (index == -1) {
358 printf(TAB"load i8** getelementptr ([2 x i8*]* @bool_str, i32 0, i32 %d )"
359 ", align 4\n", ast_node_get_value_as_int(child));
360 } else {
361 printf(TAB"getelementptr [2 x i8*]* @bool_str, i32 0, i32 %%%d\n",
362 index);
363 stack_size++;
364 printf(TAB"load i8** %%%d, align 4\n", stack_size);
366 stack_size++;
368 printf(TAB"call i32 (i8* noalias , ...)* bitcast (i32 (i8*, ...)* \n");
369 printf(TAB TAB"@printf to i32 (i8* noalias , ...)*)\n");
370 printf(TAB TAB"( i8* getelementptr ");
371 printf("([3 x i8]* @.bool_fmt, i32 0, i32 0) noalias , \n");
372 printf(TAB TAB"i8* %%%d )\n", stack_size);
373 stack_size++;
376 void
377 llvm_codegen_visit_printline_stmt (struct _Visitor *visitor, struct AstNode *node)
379 printf(TAB"call i32 @putchar( i32 10 )\n");
380 stack_size++;
383 void
384 llvm_codegen_visit_assignment_stmt (struct _Visitor *visitor, struct AstNode *node)
386 int rindex = -1;
387 struct AstNode *lnode = node->children;
388 struct AstNode *rnode = lnode->sibling;
390 /* FIXME * */printf("; [Assignment][%s] %s(%d/%d) = %d\n", rnode->name,
391 lnode->symbol->name, lnode->symbol->stack_index,
392 stack_size, ast_node_get_value_as_int(rnode));
393 /**/
395 /* rnode */
396 rindex = _process_expression(rnode, visitor);
398 /* lnode */
399 if (lnode->symbol->is_global && !symbol_is_procfunc(lnode->symbol)) {
400 printf(TAB"store ");
401 PRINT_TYPE(lnode->type);
402 printf(" ");
403 PRINT_VALUE(rnode, rindex);
404 printf(", ");
405 PRINT_TYPE(lnode->type);
406 printf("* ");
407 ast_node_accept(lnode, visitor);
408 printf(", align 4\n");
410 } else if (rindex == -1) {
411 /*lnode->symbol->stack_index = -1;
412 lnode->symbol->value.integer = rnode->value.integer;
413 lnode->value.integer = rnode->value.integer;*/
414 printf(TAB"add ");
415 PRINT_TYPE(lnode->type);
416 printf(" ");
417 PRINT_VALUE(rnode, rindex);
418 printf(", 0\n");
419 stack_size++;
420 lnode->symbol->stack_index = stack_size;
422 } else
423 lnode->symbol->stack_index = rindex;
426 /* FIXME */ printf("; [Assignment][%s] %s(%d/%d) = %d\n", rnode->name,
427 lnode->symbol->name, lnode->symbol->stack_index,
428 stack_size, ast_node_get_value_as_int(rnode));
429 /**/
432 void
433 llvm_codegen_visit_if_stmt (struct _Visitor *visitor, struct AstNode *node)
435 int index = -1;
436 struct AstNode *expr = node->children;
437 struct AstNode *cmd1 = expr->sibling;
438 struct AstNode *cmd2 = cmd1->sibling;
440 printf("; if evaluation, line %d\n", node->linenum);
442 index = _process_expression(expr, visitor);
444 printf(TAB"br i1 ");
445 PRINT_VALUE(expr, index);
446 printf(", label %%cond_true_%x, label ", node);
448 if (cmd2 == NULL)
449 printf("%%cond_next_%x\n", node);
450 else
451 printf("%%cond_false_%x\n", node);
453 printf("\ncond_true_%x:\n", node);
454 ast_node_accept(cmd1, visitor);
455 printf(TAB"br label %%cond_next_%x\n", node);
457 if (cmd2 != NULL) {
458 printf("\ncond_false_%x:\n", node);
459 ast_node_accept(cmd2, visitor);
460 printf(TAB"br label %%cond_next_%x\n", node);
463 printf("\ncond_next_%x:\n", node);
466 void
467 llvm_codegen_visit_while_stmt (struct _Visitor *visitor, struct AstNode *node)
469 struct AstNode *child;
470 const char *var;
472 printf("while (");
473 child = node->children; // Expression
474 ast_node_accept(child, visitor);
475 printf(") {\n");
477 child = child->sibling; // Statements
478 ast_node_accept(child, visitor);
480 printf("}\n");
483 void
484 llvm_codegen_visit_for_stmt (struct _Visitor *visitor, struct AstNode *node)
486 int index = -1;
487 struct AstNode *asgn = node->children;
488 struct AstNode *expr = asgn->sibling;
489 struct AstNode *stmt = expr->sibling;
491 printf("; for evaluation, line %d\n", node->linenum);
493 //%tmp512 = ????
494 ast_node_accept(asgn, visitor);
497 %tmp714 = icmp sgt i32 %tmp512, 0 ; <i1> [#uses=1]
498 br i1 %tmp714, label %bb.preheader, label %bb9
500 index = _process_expression(expr, visitor);
502 printf(TAB"br i1 ");
503 PRINT_VALUE(expr, index);
504 printf(", label %%bb_%x.preheader, label %%bb_%x\n", node, node);
507 bb.preheader: ; preds = %entry
508 %b.promoted = load i32* @b, align 4 ; <i32> [#uses=1]
509 br label %bb
511 printf("\nbb_%x.preheader:\n", node);
515 bb: ; preds = %bb, %bb.preheader
516 %ITERADOR.010.0 = phi i32 [ 0, %bb.preheader ], [ %tmp3, %bb ] ; <i32> [#uses=2]
517 %tmp3 = add i32 %ITERADOR.010.0, 1 ; <i32> [#uses=2]
518 %tmp7 = icmp slt i32 %tmp3, %tmp512 ; <i1> [#uses=1]
519 br i1 %tmp7, label %bb, label %bb9.loopexit
523 bb9.loopexit: ; preds = %bb
524 %b.tmp.0 = add i32 %ITERADOR.010.0, %b.promoted ; <i32> [#uses=1]
525 %tmp1 = add i32 %b.tmp.0, 1 ; <i32> [#uses=1]
526 store i32 %tmp1, i32* @b, align 4
527 br label %bb9
531 bb9: ; preds = %bb9.loopexit, %entry
535 printf("\ncond_true_%x:\n", node);
536 ast_node_accept(stmt, visitor);
537 printf(TAB"br label %%cond_next_%x\n", node);
539 printf("\ncond_next_%x:\n", node);
542 void
543 llvm_codegen_visit_notfactor (struct _Visitor *visitor, struct AstNode *node)
545 ast_node_accept_children(node->children, visitor);
548 void
549 llvm_codegen_visit_call (struct _Visitor *visitor, struct AstNode *node)
552 int index = -1;
553 struct AstNode *temp, *child = node->children;
555 index = _process_expression(child, visitor);
557 temp= child->sibling;
558 if (temp != NULL) {
559 for (temp = temp->children; temp != NULL; temp = temp->sibling) {
560 PRINT_TYPE(child->type);
561 printf(" ");
562 ast_node_accept(child, visitor);
563 if (child->sibling != NULL)
564 printf(", ");
568 printf(TAB"call ");
569 PRINT_TYPE(child->symbol->type);
570 printf(" ");
571 ast_node_accept(child, visitor);
572 printf("( ");
574 printf(" )\n");
575 stack_size++;
577 struct AstNode *child = node->children;
579 printf(TAB"call ");
580 PRINT_TYPE(child->symbol->type);
581 printf(" ");
582 ast_node_accept(child, visitor);
583 printf("( ");
585 child = child->sibling;
586 if (child != NULL) {
587 for (child = child->children; child != NULL; child = child->sibling) {
588 PRINT_TYPE(child->type);
589 printf(" ");
590 ast_node_accept(child, visitor);
591 if (child->sibling != NULL)
592 printf(", ");
596 printf(" )\n");
597 stack_size++;
600 void
601 llvm_codegen_visit_simplenode (struct _Visitor *visitor, struct AstNode *node)
603 ast_node_accept_children(node->children, visitor);
606 void
607 llvm_codegen_visit_binary_op (struct _Visitor *visitor, struct AstNode *node)
609 /* FIXME *printf("; %%%d = \n", stack_size + 1);*/
610 switch (node->kind) {
611 case T_OR:
612 printf(TAB"or");
613 break;
614 case T_AND:
615 printf(TAB"and");
616 break;
617 case T_EQUAL:
618 printf(TAB"icmp eq");
619 break;
620 case T_NOTEQUAL:
621 printf(TAB"icmp ne");
622 break;
623 case T_LESSER:
624 printf(TAB"icmp slt");
625 break;
626 case T_GREATER:
627 printf(TAB"icmp sgt");
628 break;
629 case T_LESSEREQUAL:
630 printf(TAB"icmp sle");
631 break;
632 case T_GREATEREQUAL:
633 printf(TAB"icmp sge");
634 break;
635 case T_PLUS:
636 printf(TAB"add");
637 break;
638 case T_MINUS:
639 printf(TAB"sub");
640 break;
641 case T_STAR:
642 printf(TAB"mul");
643 break;
644 /*case T_SLASH:
645 printf(" %s ", node->name);*/
649 void
650 llvm_codegen_visit_not_op (struct _Visitor *visitor, struct AstNode *node)
652 printf(" !", node->name);
655 static void
656 _print_boolean(struct AstNode *node)
658 printf("%bool_str = getelementptr [");
659 if (node->value.boolean)
660 printf("5 x i8]* @.true");
661 else
662 printf("6 x i8]* @.false");
663 printf("_str, i32 0, i32 0\n");
666 static void
667 _print_load(struct AstNode *node, Visitor *visitor)
669 printf(TAB"load ");
670 PRINT_TYPE(node->type);
671 printf("* ");
672 ast_node_accept(node, visitor);
673 printf(", align 4\n");
674 stack_size++;
677 static int
678 _get_type_size(Type type)
680 switch (type) {
681 case INTEGER:
682 return 32;
683 case CHAR:
684 return 8;
685 case BOOLEAN:
686 return 1;
687 default:
688 return 0;
692 static int
693 _process_expression(struct AstNode *rnode, Visitor *visitor)
695 if (!IS_LITERAL(rnode->kind)) {
696 if (rnode->kind != IDENTIFIER) {
697 ast_node_accept(rnode, visitor);
698 return stack_size;
700 } else if (rnode->symbol->is_global) {
701 _print_load(rnode, visitor);
702 return stack_size;
704 } else
705 return rnode->symbol->stack_index;
709 return -1;