Quase gerando codigo C.
[toypasc.git] / ast.c
blob0c4e6d0c584a0cf31ab8126f4a504a11904500fd
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "ast.h"
5 #include "typecheck_visitor.h"
7 struct AstNode *
8 ast_node_new(const char* name, int kind, int type,
9 int linenum, Symbol *symbol)
11 int i;
12 struct AstNode *node;
14 node = (struct AstNode *) malloc (sizeof(struct AstNode));
16 if (name != NULL){
17 node->name = strdup(name);
18 } else
19 node->name = NULL;
21 node->kind = kind;
22 node->type = type;
23 node->linenum = linenum;
24 node->symbol = symbol;
25 node->visited = FALSE;
26 node->parent = NULL;
27 node->children = NULL;
28 node->sibling = NULL;
30 return node;
33 void
34 ast_node_destroy(struct AstNode *self)
36 if (self != NULL) {
37 ast_node_destroy(self->children);
38 ast_node_destroy(self->sibling);
39 free(self);
43 void
44 ast_node_unset_visited(struct AstNode *self)
46 if (self == NULL)
47 return;
49 ast_node_unset_visited(self->children);
50 ast_node_unset_visited(self->sibling);
51 self->visited = FALSE;
54 void
55 ast_node_add_child(struct AstNode *self, struct AstNode *child)
57 struct AstNode *temp;
59 if (child == NULL)
60 return;
62 if (self->children == NULL) {
63 child->parent = self;
64 self->children = child;
65 } else {
66 ast_node_add_sibling(self->children, child);
68 for (temp = child; temp != NULL; temp = temp->sibling)
69 temp->parent = self;
72 void
73 ast_node_add_sibling(struct AstNode *self, struct AstNode *sibling)
75 struct AstNode *temp;
77 if (sibling == NULL)
78 return;
80 if (self->sibling == NULL) {
81 self->sibling = sibling;
82 } else {
83 for (temp = self->sibling; temp->sibling != NULL; temp = temp->sibling)
85 temp->sibling = sibling;
89 void
90 ast_node_accept(struct AstNode *self, Visitor *visitor)
92 VisitFunc visit;
94 if (self == NULL || self->visited)
95 return;
97 self->visited = TRUE;
99 switch (self->kind) {
100 case PROGRAM:
101 ast_node_unset_visited(self);
102 visit = visitor->visit_program;
103 break;
104 case PROGRAM_DECL:
105 visit = visitor->visit_programdecl;
106 break;
107 case VARDECL_LIST:
108 visit = visitor->visit_vardecl_list;
109 break;
110 case VARDECL:
111 visit = visitor->visit_vardecl;
112 break;
113 case IDENT_LIST:
114 visit = visitor->visit_identifier_list;
115 break;
116 case PROCFUNC_LIST:
117 visit = visitor->visit_procfunc_list;
118 break;
119 case PROCEDURE:
120 visit = visitor->visit_procedure;
121 break;
122 case FUNCTION:
123 visit = visitor->visit_function;
124 break;
125 case PARAM_LIST:
126 visit = visitor->visit_param_list;
127 break;
128 case PARAMETER:
129 visit = visitor->visit_parameter;
130 break;
131 case STATEMENT_LIST:
132 visit = visitor->visit_statement_list;
133 break;
134 case PRINTINT_STMT:
135 visit = visitor->visit_printint_stmt;
136 break;
137 case PRINTCHAR_STMT:
138 visit = visitor->visit_printchar_stmt;
139 break;
140 case PRINTBOOL_STMT:
141 visit = visitor->visit_printbool_stmt;
142 break;
143 case PRINTLINE_STMT:
144 visit = visitor->visit_printline_stmt;
145 break;
146 case ASSIGNMENT_STMT:
147 visit = visitor->visit_assignment_stmt;
148 break;
149 case IF_STMT:
150 visit = visitor->visit_if_stmt;
151 break;
152 case WHILE_STMT:
153 visit = visitor->visit_while_stmt;
154 break;
155 case FOR_STMT:
156 visit = visitor->visit_for_stmt;
157 break;
158 case REL_EXPR:
159 visit = visitor->visit_rel_expr;
160 break;
161 case ADD_EXPR:
162 visit = visitor->visit_add_expr;
163 break;
164 case MUL_EXPR:
165 visit = visitor->visit_mul_expr;
166 break;
167 case NOTFACTOR:
168 visit = visitor->visit_notfactor;
169 break;
170 case CALL:
171 visit = visitor->visit_call;
172 break;
173 case CALLPARAM_LIST:
174 visit = visitor->visit_callparam_list;
175 break;
176 case IDENTIFIER:
177 visit = visitor->visit_identifier;
178 break;
179 case INT_LITERAL:
180 case BOOL_LITERAL:
181 case CHAR_LITERAL:
182 visit = visitor->visit_literal;
183 break;
184 case T_PLUS:
185 case T_MINUS:
186 case T_OR:
187 visit = visitor->visit_add_op;
188 break;
189 case T_STAR:
190 case T_SLASH:
191 case T_AND:
192 visit = visitor->visit_mul_op;
193 break;
194 case T_EQUAL:
195 case T_NOTEQUAL:
196 case T_LESSER:
197 case T_GREATER:
198 case T_LESSEREQUAL:
199 case T_GREATEREQUAL:
200 visit = visitor->visit_rel_op;
201 break;
202 case T_NOT:
203 visit = visitor->visit_not_op;
204 break;
205 default:
206 visit = NULL;
209 if (visit != NULL)
210 visit(visitor, self);
213 void
214 ast_node_accept_children(struct AstNode *self, Visitor *visitor)
216 struct AstNode *temp;
217 for (temp = self; temp != NULL; temp = temp->sibling)
218 ast_node_accept(temp, visitor);