Iniciado trabalho com llvm_codegen_visitor.
[toypasc.git] / typecheck_visitor.c
blob97ef103765ee14ca32feff2a1568a6185e8b94c8
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "typecheck_visitor.h"
5 static bool is_vardecl = FALSE;
6 static Symbol *procfunc_symbol = NULL;
7 static Symbol *_symbol_lookup(Symbol *sym);
8 static Type _get_expression_type(struct AstNode *node);
10 Visitor *
11 typecheck_new()
13 Visitor *visitor = (Visitor *) malloc (sizeof(Visitor));
15 visitor->visit_program = &typecheck_visit_program;
16 visitor->visit_programdecl = &typecheck_visit_programdecl;
17 visitor->visit_vardecl_list = &typecheck_visit_vardecl_list;
18 visitor->visit_vardecl = &typecheck_visit_vardecl;
19 visitor->visit_identifier_list = &typecheck_visit_pass;
20 visitor->visit_procfunc_list = &typecheck_visit_procfunc_list;
21 visitor->visit_procedure = &typecheck_visit_procfunc;
22 visitor->visit_function = &typecheck_visit_procfunc;
23 visitor->visit_param_list = &typecheck_visit_pass;
24 visitor->visit_parameter = &typecheck_visit_parameter;
25 visitor->visit_statement_list = &typecheck_visit_statement_list;
26 visitor->visit_printint_stmt = &typecheck_visit_printint_stmt;
27 visitor->visit_printchar_stmt = &typecheck_visit_printchar_stmt;
28 visitor->visit_printbool_stmt = &typecheck_visit_printbool_stmt;
29 visitor->visit_printline_stmt = &typecheck_visit_pass;
30 visitor->visit_assignment_stmt = &typecheck_visit_assignment_stmt;
31 visitor->visit_if_stmt = &typecheck_visit_if_stmt;
32 visitor->visit_while_stmt = &typecheck_visit_while_stmt;
33 visitor->visit_for_stmt = &typecheck_visit_for_stmt;
34 visitor->visit_rel_expr = &typecheck_visit_binary_expr;
35 visitor->visit_add_expr = &typecheck_visit_binary_expr;
36 visitor->visit_mul_expr = &typecheck_visit_binary_expr;
37 visitor->visit_notfactor = &typecheck_visit_notfactor;
38 visitor->visit_call = &typecheck_visit_call;
39 visitor->visit_callparam_list = &typecheck_visit_callparam_list;
40 visitor->visit_identifier = &typecheck_visit_identifier;
41 visitor->visit_literal = &typecheck_visit_pass;
42 visitor->visit_add_op = &typecheck_visit_pass;
43 visitor->visit_mul_op = &typecheck_visit_pass;
44 visitor->visit_rel_op = &typecheck_visit_pass;
45 visitor->visit_not_op = &typecheck_visit_pass;
47 return visitor;
50 void
51 typecheck_visit_pass(struct _Visitor *visitor, struct AstNode *node)
53 ast_node_accept_children(node->children, visitor);
56 void
57 typecheck_visit_program(struct _Visitor *visitor, struct AstNode *node)
59 node->symbol = symbol_new(NULL);
60 global_symtab = node->symbol;
61 symtab = global_symtab;
62 ast_node_accept_children(node->children, visitor);
65 void
66 typecheck_visit_programdecl(struct _Visitor *visitor, struct AstNode *node)
68 is_vardecl = TRUE;
69 ast_node_accept_children(node->children, visitor);
72 void
73 typecheck_visit_procfunc_list(struct _Visitor *visitor, struct AstNode *node)
75 symtab = global_symtab;
76 ast_node_accept_children(node->children, visitor);
79 void
80 typecheck_visit_procfunc(struct _Visitor *visitor, struct AstNode *node)
82 is_vardecl = FALSE;
83 symtab = node->symbol;
84 procfunc_symbol = node->children->symbol;
85 ast_node_accept_children(node->children, visitor);
88 void
89 typecheck_visit_vardecl_list (struct _Visitor *visitor, struct AstNode *node)
91 is_vardecl = TRUE;
92 symtab = node->parent->symbol;
93 ast_node_accept_children(node->children, visitor);
96 void
97 typecheck_visit_vardecl (struct _Visitor *visitor, struct AstNode *node)
99 declared_type = node->type;
100 ast_node_accept_children(node->children, visitor);
103 void
104 typecheck_visit_parameter (struct _Visitor *visitor, struct AstNode *node)
106 is_vardecl = TRUE;
107 declared_type = node->type;
108 ast_node_accept_children(node->children, visitor);
111 void
112 typecheck_visit_statement_list(struct _Visitor *visitor, struct AstNode *node)
114 is_vardecl = FALSE;
115 declared_type = VOID;
116 symtab = node->parent->symbol;
117 ast_node_accept_children(node->children, visitor);
120 static void
121 _typecheck_print_stmt(struct AstNode *node, Type type, const char *type_str)
123 if (_get_expression_type(node->children) != type) {
124 node->type = ERROR;
125 fprintf(stderr,
126 "Error: Expression Print%s statement must be of "
127 "%s type. Check line %d.\n",
128 type_str, type_get_lexeme(type), node->linenum);
132 void
133 typecheck_visit_printint_stmt (struct _Visitor *visitor, struct AstNode *node)
135 _typecheck_print_stmt(node, INTEGER, "Int");
136 ast_node_accept_children(node->children, visitor);
139 void
140 typecheck_visit_printchar_stmt (struct _Visitor *visitor, struct AstNode *node)
142 _typecheck_print_stmt(node, CHAR, "Char");
143 ast_node_accept_children(node->children, visitor);
146 void
147 typecheck_visit_printbool_stmt (struct _Visitor *visitor, struct AstNode *node)
149 _typecheck_print_stmt(node, BOOLEAN, "Bool");
150 ast_node_accept_children(node->children, visitor);
153 void
154 typecheck_visit_assignment_stmt (struct _Visitor *visitor, struct AstNode *node)
156 struct AstNode *node1 = node->children;
157 struct AstNode *node2 = node1->sibling;
159 if (node1->kind != IDENTIFIER) {
160 fprintf(stderr,
161 "Error: Left side of assignment must be an Identifier. Check line %d.\n",
162 node->linenum);
163 } else if (_get_expression_type(node1) != _get_expression_type(node2)) {
164 node->type = ERROR;
165 fprintf(stderr,
166 "Error: Incompatible types on assignment operation in line %d.\n",
167 node->linenum);
169 ast_node_accept_children(node->children, visitor);
172 void
173 typecheck_visit_if_stmt (struct _Visitor *visitor, struct AstNode *node)
175 struct AstNode *expr = node->children;
177 if (_get_expression_type(expr) != BOOLEAN) {
178 node->type = ERROR;
179 fprintf(stderr,
180 "Error: Condition for if statement must be of Boolean type. "
181 "Check line %d.\n", node->linenum);
183 ast_node_accept_children(node->children, visitor);
186 void
187 typecheck_visit_while_stmt (struct _Visitor *visitor, struct AstNode *node)
189 Type type;
190 struct AstNode *expr = node->children;
192 type = _get_expression_type(expr);
193 if (type != BOOLEAN) {
194 node->type = ERROR;
195 fprintf(stderr,
196 "Error: Expression in While statement must be of "
197 "Boolean type. Check line %d.\n", expr->linenum);
199 ast_node_accept_children(node->children, visitor);
202 void
203 typecheck_visit_for_stmt (struct _Visitor *visitor, struct AstNode *node)
205 Type type;
206 struct AstNode *assign_node = node->children;
207 struct AstNode *id_node = assign_node->children;
208 struct AstNode *expr1_node = id_node->sibling;
209 struct AstNode *expr2_node = assign_node->sibling;
211 type = _get_expression_type(id_node);
212 if (type != INTEGER) {
213 node->type = ERROR;
214 fprintf(stderr,
215 "Error: Identifier '%s' is not of Integer type. "
216 "Check line %d.\n",
217 id_node->symbol->name, id_node->linenum);
219 type = _get_expression_type(expr1_node);
220 if (type != INTEGER) {
221 node->type = ERROR;
222 fprintf(stderr,
223 "Error: Initial value of '%s' is not of Integer type. "
224 "Check line %d.\n",
225 id_node->symbol->name, expr1_node->linenum);
227 type = _get_expression_type(expr1_node);
228 if (type != INTEGER) {
229 node->type = ERROR;
230 fprintf(stderr,
231 "Error: Value of stop condition is not of Integer type. "
232 "Check line %d.\n", expr2_node->linenum);
234 ast_node_accept_children(node->children, visitor);
237 void
238 typecheck_visit_binary_expr (struct _Visitor *visitor, struct AstNode *node)
240 Type type1;
241 Type type2;
242 struct AstNode *node1 = node->children;
243 struct AstNode *operator = node1->sibling;
244 struct AstNode *node2 = operator->sibling;
246 type1 = _get_expression_type(node1);
247 type2 = _get_expression_type(node2);
249 if (type1 != type2) {
250 node->type = ERROR;
251 fprintf(stderr,
252 "Error: Operation '%s' over incompatible types on line %d.\n",
253 operator->name, operator->linenum);
255 ast_node_accept_children(node->children, visitor);
258 void
259 typecheck_visit_notfactor (struct _Visitor *visitor, struct AstNode *node)
261 Type type = _get_expression_type(node->children->sibling);
263 if (type != BOOLEAN) {
264 node->type = ERROR;
265 fprintf(stderr,
266 "Error: Operation 'not' over non-boolean type on line %d.\n",
267 node->linenum);
269 ast_node_accept_children(node->children, visitor);
272 void
273 typecheck_visit_call (struct _Visitor *visitor, struct AstNode *node)
275 int i;
276 char *name;
277 Symbol *sym;
279 name = node->children->symbol->name;
280 sym = symbol_lookup(global_symtab, name);
281 procfunc_symbol = sym;
283 if (sym == NULL) {
284 fprintf(stderr,
285 "Error: Undeclared function or procedure '%s' in line %d\n",
286 name, node->linenum);
287 return;
290 node->type = sym->type;
291 ast_node_accept_children(node->children, visitor);
294 void
295 typecheck_visit_callparam_list (struct _Visitor *visitor, struct AstNode *node)
297 int i;
298 struct AstNode *temp;
300 i = 0;
301 for (temp = node->children; temp != NULL; temp = temp->sibling) {
302 if (temp->type != procfunc_symbol->param_types[i]) {
303 fprintf(stderr, "Error: Call '%s' on line %d, expecting %s "
304 "on parameter %d (",
305 procfunc_symbol->name, node->linenum,
306 type_get_lexeme(procfunc_symbol->param_types[i]), i+1);
307 if (temp->symbol != NULL)
308 fprintf(stderr, "'%s'", temp->symbol->name);
309 else
310 value_print(stderr, &temp->value, temp->type);
312 fprintf(stderr, "), received %s.\n",
313 type_get_lexeme(temp->type));
316 i++;
317 if (i > procfunc_symbol->params)
318 break;
320 if (i != procfunc_symbol->params) {
321 fprintf(stderr, "Error: Expecting %d parameters, received %d.\n",
322 i, procfunc_symbol->params);
325 ast_node_accept_children(node->children, visitor);
328 void
329 typecheck_visit_identifier (struct _Visitor *visitor, struct AstNode *node)
331 Symbol *sym;
333 if (is_vardecl) {
334 node->type = declared_type;
335 node->symbol->type = declared_type;
336 sym = symbol_insert(symtab, node->symbol);
338 if (node->parent->kind == PARAMETER) {
339 procfunc_symbol->param_types[procfunc_symbol->params] = node->symbol->type;
340 procfunc_symbol->params++;
343 if (sym != node->symbol)
344 fprintf(stderr, "Error: Symbol '%s' already defined in line XX\n",
345 sym->name);
347 } else if (node->parent->kind == FUNCTION ||
348 node->parent->kind == PROCEDURE) {
349 sym = symbol_insert(global_symtab, node->symbol);
350 node->type = node->symbol->type;
351 node->parent->type = node->type;
352 procfunc_symbol = node->symbol;
354 if (sym != node->symbol)
355 fprintf(stderr, "Error: Symbol '%s' already defined in line XX\n",
356 sym->name);
358 } else {
359 sym = _symbol_lookup(node->symbol);
361 if (sym != NULL)
362 node->symbol = sym;
363 else {
364 node->symbol->decl_linenum = 0;
365 fprintf(stderr, "Error: Undeclared symbol '%s' in line %d\n",
366 node->symbol->name, node->linenum);
369 if (node->parent->kind == CALLPARAM_LIST) {
370 /*int i;
371 //procfunc_symbol->param_types[procfunc_symbol->params] = node->symbol->type;
372 //procfunc_symbol->params++;
373 fprintf(stderr, "Parameter: %s (%x)\n",
374 procfunc_symbol->name, procfunc_symbol);
375 fprintf(stderr, "types (%d): ", procfunc_symbol->params);
376 for (i = 0; i < procfunc_symbol->params; i++) {
377 fprintf(stderr, "%d ",
378 procfunc_symbol->param_types[procfunc_symbol->params]);
380 fprintf(stderr, "\n");*/
384 ast_node_accept_children(node->children, visitor);
387 static Symbol *
388 _symbol_lookup(Symbol *sym)
390 Symbol *symbol = NULL;
392 symbol = symbol_lookup(symtab, sym->name);
394 if (symbol == NULL)
395 symbol = symbol_lookup(global_symtab, sym->name);
397 return symbol;
400 static Type
401 _get_expression_type(struct AstNode *node)
403 char *name;
404 Symbol *sym;
406 switch (node->kind) {
407 case IDENTIFIER:
408 sym = _symbol_lookup(node->symbol);
409 if (sym != NULL) {
410 node->type = sym->type;
411 return sym->type;
413 break;
415 case INT_LITERAL:
416 case BOOL_LITERAL:
417 case CHAR_LITERAL:
418 return node->type;
420 case NOTFACTOR:
421 return BOOLEAN;
423 case CALL:
424 name = node->children->symbol->name;
425 sym = symbol_lookup(global_symtab, name);
426 if (sym != NULL) {
427 node->type = sym->type;
428 return sym->type;
430 break;
432 default:
433 return node->type;