Adicionando codegen_visitor.h e c
[toypasc.git] / ast.c
blobef6b3c5d118d3cda8db6f565a6fb47d8a2a359e3
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 struct AstNode *temp;
93 bool opened_group = FALSE;
95 switch (self->kind) {
96 case PROGRAM:
97 ast_node_unset_visited(self);
98 visitor->visit_program(self);
99 opened_group = TRUE;
100 break;
101 case PROGDECL:
102 visitor->visit_programdecl(self);
103 break;
104 case VARDECL_LIST:
105 visitor->visit_vardecl_list(self);
106 opened_group = TRUE;
107 break;
108 case VARDECL:
109 visitor->visit_vardecl(self);
110 break;
111 case IDENT_LIST:
112 visitor->visit_identifier_list(self);
113 opened_group = TRUE;
114 break;
115 case PROCFUNC_LIST:
116 visitor->visit_procfunc_list(self);
117 break;
118 case PROCEDURE:
119 visitor->visit_procedure(self);
120 opened_group = TRUE;
121 break;
122 case FUNCTION:
123 visitor->visit_function(self);
124 opened_group = TRUE;
125 break;
126 case PARAM_LIST:
127 visitor->visit_param_list(self);
128 opened_group = TRUE;
129 break;
130 case PARAMETER:
131 visitor->visit_parameter(self);
132 break;
133 case STATEMENT_LIST:
134 visitor->visit_statement_list(self);
135 opened_group = TRUE;
136 break;
137 case PRINTINT_STMT:
138 case PRINTCHAR_STMT:
139 case PRINTBOOL_STMT:
140 case PRINTLINE_STMT:
141 visitor->visit_print_stmt(self);
142 break;
143 case ASSIGNMENT_STMT:
144 visitor->visit_assignment_stmt(self);
145 break;
146 case IF_STMT:
147 visitor->visit_if_stmt(self);
148 break;
149 case WHILE_STMT:
150 visitor->visit_while_stmt(self);
151 break;
152 case FOR_STMT:
153 visitor->visit_for_stmt(self);
154 break;
155 case REL_EXPR:
156 visitor->visit_rel_expr(self);
157 break;
158 case ADD_EXPR:
159 visitor->visit_add_expr(self);
160 break;
161 case MUL_EXPR:
162 visitor->visit_mul_expr(self);
163 break;
164 case NOTFACTOR:
165 visitor->visit_notfactor(self);
166 break;
167 case CALL:
168 visitor->visit_call(self);
169 break;
170 case CALLPARAM_LIST:
171 visitor->visit_callparam_list(self);
172 opened_group = TRUE;
173 break;
174 case IDENTIFIER:
175 visitor->visit_identifier(self);
176 break;
177 case INT_LITERAL:
178 case BOOL_LITERAL:
179 case CHAR_LITERAL:
180 visitor->visit_literal(self);
181 break;
184 for (temp = self->children; temp != NULL; temp = temp->sibling)
185 ast_node_accept(temp, visitor);
187 if (opened_group) {
188 if (visitor->close_group != NULL)
189 visitor->close_group();