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_callparam
= NULL
;
45 visitor
->visit_identifier
= &c_codegen_visit_identifier
;
46 visitor
->visit_literal
= &c_codegen_visit_literal
;
47 visitor
->visit_add_op
= &c_codegen_visit_binary_op
;
48 visitor
->visit_mul_op
= &c_codegen_visit_binary_op
;
49 visitor
->visit_rel_op
= &c_codegen_visit_binary_op
;
50 visitor
->visit_not_op
= &c_codegen_visit_not_op
;
56 c_codegen_visit_program(struct _Visitor
*visitor
, struct AstNode
*node
)
58 struct AstNode
*child
;
60 printf("/* Generated with toypasc */\n");
61 for (child
= node
->children
;
62 child
!= NULL
&& child
->kind
!= STATEMENT_LIST
;
63 child
= child
->sibling
) {
64 ast_node_accept(child
, visitor
);
69 printf("int\nmain(int argc, char **argv)\n{\n");
70 ast_node_accept(child
, visitor
);
71 printf("\n"TAB
"return 0;\n}\n\n");
76 c_codegen_visit_programdecl(struct _Visitor
*visitor
, struct AstNode
*node
)
78 printf("/* program ");
79 ast_node_accept(node
->children
, visitor
);
81 printf("#include <stdio.h>\n\n");
82 printf("#ifndef FALSE\n#define FALSE\t0\n#endif\n\n");
83 printf("#ifndef TRUE\n#define TRUE\t1\n#endif\n");
87 c_codegen_visit_vardecl_list (struct _Visitor
*visitor
, struct AstNode
*node
)
89 ast_node_accept_children(node
->children
, visitor
);
94 c_codegen_visit_identifier_list (struct _Visitor
*visitor
, struct AstNode
*node
)
96 struct AstNode
*child
;
98 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
99 ast_node_accept(child
, visitor
);
100 if (child
->sibling
!= NULL
)
106 c_codegen_visit_procfunc_list (struct _Visitor
*visitor
, struct AstNode
*node
)
108 ast_node_accept_children(node
->children
, visitor
);
112 c_codegen_visit_procfunc (struct _Visitor
*visitor
, struct AstNode
*node
)
115 struct AstNode
*child
;
117 type
= _get_type_string(node
->type
);
118 pf_name
= _create_temporary();
120 printf("%s\n", type
);
122 child
= node
->children
; // Identifier
123 ast_node_accept(child
, visitor
);
127 child
= child
->sibling
;
128 if (child
->kind
== PARAM_LIST
) {
129 ast_node_accept(child
, visitor
);
130 child
= child
->sibling
;
135 if (node
->kind
== FUNCTION
)
136 printf(TAB
"%s %s;\n", type
, pf_name
);
138 if (child
->kind
== VARDECL_LIST
) {
139 ast_node_accept(child
, visitor
);
140 child
= child
->sibling
;
145 ast_node_accept(child
, visitor
);
147 if (node
->kind
== FUNCTION
)
148 printf("\n"TAB
"return %s;\n", pf_name
);
155 c_codegen_visit_param_list (struct _Visitor
*visitor
, struct AstNode
*node
)
157 struct AstNode
*child
;
159 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
160 printf("%s ", _get_type_string(child
->type
));
161 ast_node_accept(child
, visitor
);
162 if (child
->sibling
!= NULL
)
168 c_codegen_visit_statement_list (struct _Visitor
*visitor
, struct AstNode
*node
)
170 struct AstNode
*child
;
172 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
174 ast_node_accept(child
, visitor
);
180 c_codegen_visit_binary_expr (struct _Visitor
*visitor
, struct AstNode
*node
)
182 ast_node_accept_children(node
->children
, visitor
);
186 c_codegen_visit_callparam_list (struct _Visitor
*visitor
, struct AstNode
*node
)
188 ast_node_accept(node
->children
, visitor
);
192 c_codegen_visit_identifier (struct _Visitor
*visitor
, struct AstNode
*node
)
194 printf("%s", node
->symbol
->name
);
198 c_codegen_visit_literal (struct _Visitor
*visitor
, struct AstNode
*node
)
200 if (node
->type
== BOOLEAN
) {
201 printf("%s", node
->value
.boolean
? "TRUE" : "FALSE");
203 value_print(stdout
, &node
->value
, node
->type
);
207 c_codegen_visit_vardecl (struct _Visitor
*visitor
, struct AstNode
*node
)
209 const char *type
= _get_type_string(node
->type
);
211 printf(TAB
"%s ", type
);
212 ast_node_accept(node
->children
, visitor
);
217 c_codegen_visit_parameter (struct _Visitor
*visitor
, struct AstNode
*node
)
219 ast_node_accept(node
->children
, visitor
);
223 c_codegen_visit_printint_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
225 printf("printf(\"%%d\", ");
226 ast_node_accept(node
->children
, visitor
);
231 c_codegen_visit_printchar_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
233 printf("printf(\"%%c\", ");
234 ast_node_accept(node
->children
, visitor
);
239 c_codegen_visit_printbool_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
241 printf("printf(\"%%s\", ");
242 ast_node_accept(node
->children
, visitor
);
247 c_codegen_visit_printline_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
249 printf("printf(\"\\n\");");
253 c_codegen_visit_assignment_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
255 ast_node_accept(node
->children
, visitor
);
257 ast_node_accept(node
->children
->sibling
, visitor
);
262 c_codegen_visit_if_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
264 struct AstNode
*child
;
268 child
= node
->children
; // Expression
269 ast_node_accept(child
, visitor
);
272 child
= child
->sibling
; // If Statements
273 ast_node_accept(child
, visitor
);
279 child
= child
->sibling
; // Else Statements
283 ast_node_accept(child
, visitor
);
292 c_codegen_visit_while_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
294 struct AstNode
*child
;
298 child
= node
->children
; // Expression
299 ast_node_accept(child
, visitor
);
302 child
= child
->sibling
; // Statements
303 ast_node_accept(child
, visitor
);
310 c_codegen_visit_for_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
312 struct AstNode
*child
;
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
);
336 c_codegen_visit_notfactor (struct _Visitor
*visitor
, struct AstNode
*node
)
338 ast_node_accept_children(node
->children
, visitor
);
342 c_codegen_visit_call (struct _Visitor
*visitor
, struct AstNode
*node
)
344 printf("%s ();\n", node
->symbol
->name
);
345 ast_node_accept(node
->children
, visitor
);
349 c_codegen_visit_simplenode (struct _Visitor
*visitor
, struct AstNode
*node
)
351 ast_node_accept_children(node
->children
, visitor
);
355 c_codegen_visit_binary_op (struct _Visitor
*visitor
, struct AstNode
*node
)
357 _print_op_symbol(node
);
361 c_codegen_visit_not_op (struct _Visitor
*visitor
, struct AstNode
*node
)
363 printf(" !", node
->name
);
367 _tab(struct AstNode
*node
) {
368 struct AstNode
*parent
;
369 for (parent
= node
->parent
; parent
->parent
!= NULL
; parent
= parent
->parent
)
374 *_get_type_string(Type type
)
393 if (asprintf (&temp
, "tmp%.5d", tmp_var
) < 0)
401 _print_op_symbol(struct AstNode
*node
)
403 switch (node
->kind
) {
432 printf(" %s ", node
->name
);