4 #include "c_codegen_visitor.h"
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
);
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
;
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
);
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");
75 c_codegen_visit_programdecl(struct _Visitor
*visitor
, struct AstNode
*node
)
77 printf("/* program ");
78 ast_node_accept(node
->children
, visitor
);
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");
86 c_codegen_visit_vardecl_list (struct _Visitor
*visitor
, struct AstNode
*node
)
88 ast_node_accept_children(node
->children
, visitor
);
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
)
105 c_codegen_visit_procfunc_list (struct _Visitor
*visitor
, struct AstNode
*node
)
107 ast_node_accept_children(node
->children
, visitor
);
111 c_codegen_visit_procfunc (struct _Visitor
*visitor
, struct AstNode
*node
)
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
);
126 child
= child
->sibling
;
127 if (child
->kind
== PARAM_LIST
) {
128 ast_node_accept(child
, visitor
);
129 child
= child
->sibling
;
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
;
144 ast_node_accept(child
, visitor
);
146 if (node
->kind
== FUNCTION
)
147 printf("\n"TAB
"return %s;\n", pf_name
);
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
)
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
) {
173 ast_node_accept(child
, visitor
);
179 c_codegen_visit_binary_expr (struct _Visitor
*visitor
, struct AstNode
*node
)
181 ast_node_accept_children(node
->children
, visitor
);
185 c_codegen_visit_callparam_list (struct _Visitor
*visitor
, struct AstNode
*node
)
187 ast_node_accept(node
->children
, visitor
);
191 c_codegen_visit_identifier (struct _Visitor
*visitor
, struct AstNode
*node
)
193 printf("%s", node
->symbol
->name
);
197 c_codegen_visit_literal (struct _Visitor
*visitor
, struct AstNode
*node
)
199 if (node
->type
== BOOLEAN
) {
200 printf("%s", node
->value
.boolean
? "TRUE" : "FALSE");
202 value_print(stdout
, &node
->value
, node
->type
);
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
);
216 c_codegen_visit_parameter (struct _Visitor
*visitor
, struct AstNode
*node
)
218 ast_node_accept(node
->children
, visitor
);
222 c_codegen_visit_printint_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
224 printf("printf(\"%%d\", ");
225 ast_node_accept(node
->children
, visitor
);
230 c_codegen_visit_printchar_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
232 printf("printf(\"%%c\", ");
233 ast_node_accept(node
->children
, visitor
);
238 c_codegen_visit_printbool_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
240 printf("printf(\"%%s\", ");
241 ast_node_accept(node
->children
, visitor
);
246 c_codegen_visit_printline_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
248 printf("printf(\"\\n\");");
252 c_codegen_visit_assignment_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
254 ast_node_accept(node
->children
, visitor
);
256 ast_node_accept(node
->children
->sibling
, visitor
);
261 c_codegen_visit_if_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
263 struct AstNode
*child
;
267 child
= node
->children
; // Expression
268 ast_node_accept(child
, visitor
);
271 child
= child
->sibling
; // If Statements
272 ast_node_accept(child
, visitor
);
278 child
= child
->sibling
; // Else Statements
282 ast_node_accept(child
, visitor
);
291 c_codegen_visit_while_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
293 struct AstNode
*child
;
297 child
= node
->children
; // Expression
298 ast_node_accept(child
, visitor
);
301 child
= child
->sibling
; // Statements
302 ast_node_accept(child
, visitor
);
309 c_codegen_visit_for_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
311 struct AstNode
*child
;
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
);
335 c_codegen_visit_notfactor (struct _Visitor
*visitor
, struct AstNode
*node
)
337 ast_node_accept_children(node
->children
, visitor
);
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
);
348 c_codegen_visit_simplenode (struct _Visitor
*visitor
, struct AstNode
*node
)
350 ast_node_accept_children(node
->children
, visitor
);
354 c_codegen_visit_binary_op (struct _Visitor
*visitor
, struct AstNode
*node
)
356 _print_op_symbol(node
);
360 c_codegen_visit_not_op (struct _Visitor
*visitor
, struct AstNode
*node
)
362 printf(" !", node
->name
);
366 _tab(struct AstNode
*node
) {
367 struct AstNode
*parent
;
368 for (parent
= node
->parent
; parent
->parent
!= NULL
; parent
= parent
->parent
)
373 *_get_type_string(Type type
)
392 if (asprintf (&temp
, "tmp%.5d", tmp_var
) < 0)
400 _print_op_symbol(struct AstNode
*node
)
402 switch (node
->kind
) {
431 printf(" %s ", node
->name
);