4 #include "llvm_codegen_visitor.h"
7 static int tmp_var
= 0;
9 static void _tab(struct AstNode
*node
);
10 static int _get_type_size(Type type
);
11 static char *_create_temporary();
12 static void _print_op_symbol(struct AstNode
*node
);
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
;
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
);
67 printf("; Definition of main function\n");
68 printf("define i32 @main () {\n");
69 ast_node_accept(child
, visitor
);
70 printf(TAB
"ret i32 0\n}\n\n");
75 llvm_codegen_visit_programdecl(struct _Visitor
*visitor
, struct AstNode
*node
)
78 ast_node_accept(node
->children
, visitor
);
80 printf("; Declare the string constants as a global constants...\n");
81 printf("@.true_str = internal constant [5 x i8] c\"true\\00\"\n");
82 printf("@.false_str = internal constant [6 x i8] c\"false\\00\"\n");
83 printf("@.int_fmt = internal constant [3 x i8] c\"%%d\\00\"\n");
85 printf("\n; External declaration of functions\n");
86 printf("declare i32 @puts(i8 *)\n");
87 printf("declare i32 @putchar(i32)\n");
88 printf("declare i32 @printf(i8*, ...)\n\n");
92 llvm_codegen_visit_vardecl_list (struct _Visitor
*visitor
, struct AstNode
*node
)
94 ast_node_accept_children(node
->children
, visitor
);
99 llvm_codegen_visit_identifier_list (struct _Visitor
*visitor
, struct AstNode
*node
)
101 struct AstNode
*child
;
103 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
104 ast_node_accept(child
, visitor
);
105 if (child
->sibling
!= NULL
)
111 llvm_codegen_visit_procfunc_list (struct _Visitor
*visitor
, struct AstNode
*node
)
113 ast_node_accept_children(node
->children
, visitor
);
117 llvm_codegen_visit_procfunc (struct _Visitor
*visitor
, struct AstNode
*node
)
119 struct AstNode
*child
;
121 pf_name
= _create_temporary();
124 PRINT_TYPE(node
->type
);
127 child
= node
->children
; // Identifier
128 ast_node_accept(child
, visitor
);
132 child
= child
->sibling
;
133 if (child
->kind
== PARAM_LIST
) {
134 ast_node_accept(child
, visitor
);
135 child
= child
->sibling
;
141 if (node
->kind
== FUNCTION
) {
143 PRINT_TYPE(node
->type
);
144 printf(" %%%s\n", pf_name
);
147 if (child
->kind
== VARDECL_LIST
) {
148 ast_node_accept(child
, visitor
);
149 child
= child
->sibling
;
154 ast_node_accept(child
, visitor
);
157 PRINT_TYPE(node
->type
);
159 if (node
->kind
== FUNCTION
)
160 printf(" %s", pf_name
);
168 llvm_codegen_visit_param_list (struct _Visitor
*visitor
, struct AstNode
*node
)
170 struct AstNode
*child
;
172 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
173 //printf("%s ", _get_type_string(child->type));
174 ast_node_accept(child
, visitor
);
175 if (child
->sibling
!= NULL
)
181 llvm_codegen_visit_statement_list (struct _Visitor
*visitor
, struct AstNode
*node
)
183 struct AstNode
*child
;
185 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
187 ast_node_accept(child
, visitor
);
193 llvm_codegen_visit_binary_expr (struct _Visitor
*visitor
, struct AstNode
*node
)
195 struct AstNode
*left
= node
->children
;
196 struct AstNode
*op
= left
->sibling
;
197 struct AstNode
*right
= op
->sibling
;
199 fprintf(stderr
, "[%s]\n", node
->name
);
200 fprintf(stderr
, "left : %s\n", left
->name
);
201 fprintf(stderr
, "op : %s\n", op
->name
);
202 fprintf(stderr
, "right: %s\n\n", right
->name
);
204 if (IS_LITERAL(left
->kind
) && IS_LITERAL(right
->kind
)) {
205 _print_op_symbol(op
);
207 ast_node_accept(left
, visitor
);
209 ast_node_accept(right
, visitor
);
212 // %tmp = mul i32 %x, %y
213 // %tmp2 = add i32 %tmp, %z
214 //ast_node_accept_children(node->children, visitor);
218 llvm_codegen_visit_callparam_list (struct _Visitor
*visitor
, struct AstNode
*node
)
220 ast_node_accept(node
->children
, visitor
);
224 llvm_codegen_visit_identifier (struct _Visitor
*visitor
, struct AstNode
*node
)
226 printf("%s%s", node
->symbol
->is_global
? "@" : TAB
"%",
231 llvm_codegen_visit_literal (struct _Visitor
*visitor
, struct AstNode
*node
)
233 if (node
->type
== BOOLEAN
) {
234 printf("%bool_str = getelementptr [");
235 if (node
->value
.boolean
)
236 printf("5 x i8]* @.true");
238 printf("6 x i8]* @.false");
239 printf("_str, i32 0, i32 0\n");
242 printf("%d", node
->value
.integer
);
246 llvm_codegen_visit_vardecl (struct _Visitor
*visitor
, struct AstNode
*node
)
248 struct AstNode
*child
;
249 const char *type
;// = _get_type_string(node->type);
251 child
= node
->children
;
252 child
->visited
= TRUE
;
254 for (child
= child
->children
; child
!= NULL
; child
= child
->sibling
) {
255 ast_node_accept(child
, visitor
);
256 if (node
->parent
->parent
->kind
== PROGRAM
)
257 printf(" = global i%d 0\n", _get_type_size(child
->type
));
259 printf(" = add i%d 0, 0\n", _get_type_size(child
->type
));
264 llvm_codegen_visit_parameter (struct _Visitor
*visitor
, struct AstNode
*node
)
266 PRINT_TYPE(node
->type
);
268 ast_node_accept(node
->children
, visitor
);
272 llvm_codegen_visit_printint_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
274 printf("call i32 (i8* noalias , ...)* bitcast (i32 (i8*, ...)* ");
275 printf("@printf to i32 (i8* noalias , ...)*)( i8* getelementptr ");
276 printf("([3 x i8]* @.int_fmt, i32 0, i32 0) noalias , i32 ");
277 ast_node_accept(node
->children
, visitor
);
282 llvm_codegen_visit_printchar_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
284 printf("call i32 @putchar( i32 ");
285 ast_node_accept(node
->children
, visitor
);
290 llvm_codegen_visit_printbool_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
292 ast_node_accept(node
->children
, visitor
);
293 printf(TAB
"call i32 @puts( i8 * %bool_str )\n");
297 llvm_codegen_visit_printline_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
299 printf("call i32 @putchar( i32 10 )\n");
303 llvm_codegen_visit_assignment_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
306 int tsize
= _get_type_size(node
->children
->type
);
307 printf("; [Template] store i32 50, i32* @x, align 4\n");
309 lsym
= node
->children
->symbol
;
311 fprintf(stderr
, "%s - ", node
->children
->symbol
->name
);
312 fprintf(stderr
, "is_global? %d\n", node
->children
->symbol
->is_global
);
314 //printf(TAB"store i%d ", tsize);
315 //ast_node_accept(node->children->sibling, visitor);
316 //printf(", i%d* ", tsize);
317 ast_node_accept(node
->children
, visitor
);
322 llvm_codegen_visit_if_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
324 struct AstNode
*child
;
328 child
= node
->children
; // Expression
329 ast_node_accept(child
, visitor
);
332 child
= child
->sibling
; // If Statements
333 ast_node_accept(child
, visitor
);
339 child
= child
->sibling
; // Else Statements
343 ast_node_accept(child
, visitor
);
352 llvm_codegen_visit_while_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
354 struct AstNode
*child
;
358 child
= node
->children
; // Expression
359 ast_node_accept(child
, visitor
);
362 child
= child
->sibling
; // Statements
363 ast_node_accept(child
, visitor
);
370 llvm_codegen_visit_for_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
372 struct AstNode
*child
;
376 child
= node
->children
; // Assignment
377 ast_node_accept(child
, visitor
);
379 var
= child
->children
->symbol
->name
;
380 printf(" %s < ", var
);
382 child
= child
->sibling
; // Stop condition
383 ast_node_accept(child
, visitor
);
385 printf("; %s++) {\n", var
);
387 child
= child
->sibling
; // Statements
388 ast_node_accept_children(child
, visitor
);
396 llvm_codegen_visit_notfactor (struct _Visitor
*visitor
, struct AstNode
*node
)
398 ast_node_accept_children(node
->children
, visitor
);
402 llvm_codegen_visit_call (struct _Visitor
*visitor
, struct AstNode
*node
)
404 struct AstNode
*child
= node
->children
;
407 PRINT_TYPE(child
->symbol
->type
);
409 ast_node_accept(child
, visitor
);
411 for (child
= child
->sibling
->children
; child
!= NULL
;
412 child
= child
->sibling
) {
413 PRINT_TYPE(child
->type
);
415 ast_node_accept(child
, visitor
);
416 if (child
->sibling
!= NULL
)
423 llvm_codegen_visit_simplenode (struct _Visitor
*visitor
, struct AstNode
*node
)
425 ast_node_accept_children(node
->children
, visitor
);
429 llvm_codegen_visit_binary_op (struct _Visitor
*visitor
, struct AstNode
*node
)
431 _print_op_symbol(node
);
435 llvm_codegen_visit_not_op (struct _Visitor
*visitor
, struct AstNode
*node
)
437 printf(" !", node
->name
);
441 _tab(struct AstNode
*node
) {
442 struct AstNode
*parent
;
443 for (parent
= node
->parent
; parent
->parent
!= NULL
; parent
= parent
->parent
)
448 _get_type_size(Type type
)
467 if (asprintf (&temp
, "tmp%d", tmp_var
) < 0)
475 _print_op_symbol(struct AstNode
*node
)
477 switch (node
->kind
) {
512 printf(" %s ", node->name);*/