Mais um atributo redundante removido: is_parameter de Symbol.
[toypasc.git] / ast.c
blob3b666175099f71667a055c8553650e390b99584e
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->child_counter = 0;
25 node->symbol = symbol;
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 Value
44 ast_node_get_value(struct AstNode *self)
46 if (self->kind == IDENTIFIER)
47 return self->symbol->value;
49 return self->value;
52 int
53 ast_node_get_value_as_int(struct AstNode *self)
55 if (self->kind == IDENTIFIER)
56 return self->symbol->value.integer;
58 return self->value.integer;
61 int
62 ast_node_get_child_counter(struct AstNode *self)
64 return self->child_counter++;
67 bool
68 ast_node_check_errors(struct AstNode *self)
70 struct AstNode *child;
72 if (self == NULL || self->type == ERROR)
73 return TRUE;
75 for (child = self->children; child != NULL; child = child->sibling) {
76 if (ast_node_check_errors(child) == TRUE)
77 return TRUE;
80 return FALSE;
83 void
84 ast_node_add_child(struct AstNode *self, struct AstNode *child)
86 struct AstNode *temp;
88 if (child == NULL)
89 return;
91 if (self->children == NULL) {
92 child->parent = self;
93 self->children = child;
94 } else {
95 ast_node_add_sibling(self->children, child);
97 for (temp = child; temp != NULL; temp = temp->sibling)
98 temp->parent = self;
101 void
102 ast_node_add_sibling(struct AstNode *self, struct AstNode *sibling)
104 struct AstNode *temp;
106 if (sibling == NULL)
107 return;
109 if (self->sibling == NULL) {
110 self->sibling = sibling;
111 } else {
112 for (temp = self->sibling; temp->sibling != NULL; temp = temp->sibling)
114 temp->sibling = sibling;
118 void
119 ast_node_accept(struct AstNode *self, Visitor *visitor)
121 VisitFunc visit;
123 if (self == NULL)
124 return;
126 self->child_counter = 1;
128 switch (self->kind) {
129 case PROGRAM:
130 visit = visitor->visit_program;
131 break;
132 case PROGRAM_DECL:
133 visit = visitor->visit_programdecl;
134 break;
135 case VARDECL_LIST:
136 visit = visitor->visit_vardecl_list;
137 break;
138 case VARDECL:
139 visit = visitor->visit_vardecl;
140 break;
141 case IDENT_LIST:
142 visit = visitor->visit_identifier_list;
143 break;
144 case PROCFUNC_LIST:
145 visit = visitor->visit_procfunc_list;
146 break;
147 case PROCEDURE:
148 visit = visitor->visit_procedure;
149 break;
150 case FUNCTION:
151 visit = visitor->visit_function;
152 break;
153 case PARAM_LIST:
154 visit = visitor->visit_param_list;
155 break;
156 case PARAMETER:
157 visit = visitor->visit_parameter;
158 break;
159 case STATEMENT_LIST:
160 visit = visitor->visit_statement_list;
161 break;
162 case PRINTINT_STMT:
163 visit = visitor->visit_printint_stmt;
164 break;
165 case PRINTCHAR_STMT:
166 visit = visitor->visit_printchar_stmt;
167 break;
168 case PRINTBOOL_STMT:
169 visit = visitor->visit_printbool_stmt;
170 break;
171 case PRINTLINE_STMT:
172 visit = visitor->visit_printline_stmt;
173 break;
174 case ASSIGNMENT_STMT:
175 visit = visitor->visit_assignment_stmt;
176 break;
177 case IF_STMT:
178 visit = visitor->visit_if_stmt;
179 break;
180 case WHILE_STMT:
181 visit = visitor->visit_while_stmt;
182 break;
183 case FOR_STMT:
184 visit = visitor->visit_for_stmt;
185 break;
186 case REL_EXPR:
187 visit = visitor->visit_rel_expr;
188 break;
189 case ADD_EXPR:
190 visit = visitor->visit_add_expr;
191 break;
192 case MUL_EXPR:
193 visit = visitor->visit_mul_expr;
194 break;
195 case NOTFACTOR:
196 visit = visitor->visit_notfactor;
197 break;
198 case CALL:
199 visit = visitor->visit_call;
200 break;
201 case CALLPARAM_LIST:
202 visit = visitor->visit_callparam_list;
203 break;
204 case CALLPARAM:
205 visit = visitor->visit_callparam;
206 break;
207 case IDENTIFIER:
208 visit = visitor->visit_identifier;
209 break;
210 case INT_LITERAL:
211 case BOOL_LITERAL:
212 case CHAR_LITERAL:
213 visit = visitor->visit_literal;
214 break;
215 case T_PLUS:
216 case T_MINUS:
217 case T_OR:
218 visit = visitor->visit_add_op;
219 break;
220 case T_STAR:
221 case T_SLASH:
222 case T_AND:
223 visit = visitor->visit_mul_op;
224 break;
225 case T_EQUAL:
226 case T_NOTEQUAL:
227 case T_LESSER:
228 case T_GREATER:
229 case T_LESSEREQUAL:
230 case T_GREATEREQUAL:
231 visit = visitor->visit_rel_op;
232 break;
233 case T_NOT:
234 visit = visitor->visit_not_op;
235 break;
236 default:
237 visit = NULL;
240 if (visit != NULL)
241 visit(visitor, self);
244 void
245 ast_node_accept_children(struct AstNode *self, Visitor *visitor)
247 struct AstNode *temp;
248 for (temp = self; temp != NULL; temp = temp->sibling)
249 ast_node_accept(temp, visitor);