Quase gerando codigo C.
[toypasc.git] / typecheck_visitor.c
blobe5a8dd523751055cc72c4df475823f542558717d
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, received %s.\n",
304 procfunc_symbol->name, node->linenum,
305 type_get_lexeme(procfunc_symbol->param_types[i]),
306 type_get_lexeme(temp->type));
309 i++;
310 if (i > procfunc_symbol->params)
311 break;
313 if (i != procfunc_symbol->params) {
314 fprintf(stderr, "Error: Expecting %d parameters, received %d.\n",
315 i, procfunc_symbol->params);
318 ast_node_accept_children(node->children, visitor);
321 void
322 typecheck_visit_identifier (struct _Visitor *visitor, struct AstNode *node)
324 Symbol *sym;
326 if (is_vardecl) {
327 node->type = declared_type;
328 node->symbol->type = declared_type;
329 sym = symbol_insert(symtab, node->symbol);
331 if (node->parent->kind == PARAMETER) {
332 procfunc_symbol->param_types[procfunc_symbol->params] = node->symbol->type;
333 procfunc_symbol->params++;
336 if (sym != node->symbol)
337 fprintf(stderr, "Error: Symbol '%s' already defined in line XX\n",
338 sym->name);
340 } else if (node->parent->kind == FUNCTION ||
341 node->parent->kind == PROCEDURE) {
342 sym = symbol_insert(global_symtab, node->symbol);
343 node->type = node->symbol->type;
344 node->parent->type = node->type;
345 procfunc_symbol = node->symbol;
347 if (sym != node->symbol)
348 fprintf(stderr, "Error: Symbol '%s' already defined in line XX\n",
349 sym->name);
351 } else {
352 sym = _symbol_lookup(node->symbol);
354 if (sym != NULL)
355 node->symbol = sym;
356 else {
357 node->symbol->decl_linenum = 0;
358 fprintf(stderr, "Error: Undeclared symbol '%s' in line %d\n",
359 node->symbol->name, node->linenum);
362 if (node->parent->kind == CALLPARAM_LIST) {
363 int i;
364 //procfunc_symbol->param_types[procfunc_symbol->params] = node->symbol->type;
365 //procfunc_symbol->params++;
366 fprintf(stderr, "Parameter: %s (%x)\n",
367 procfunc_symbol->name, procfunc_symbol);
368 fprintf(stderr, "types (%d): ", procfunc_symbol->params);
369 for (i = 0; i < procfunc_symbol->params; i++) {
370 fprintf(stderr, "%d ",
371 procfunc_symbol->param_types[procfunc_symbol->params]);
373 fprintf(stderr, "\n");
377 ast_node_accept_children(node->children, visitor);
380 static Symbol *
381 _symbol_lookup(Symbol *sym)
383 Symbol *symbol = NULL;
385 symbol = symbol_lookup(symtab, sym->name);
387 if (symbol == NULL)
388 symbol = symbol_lookup(global_symtab, sym->name);
390 return symbol;
393 static Type
394 _get_expression_type(struct AstNode *node)
396 char *name;
397 Symbol *sym;
399 switch (node->kind) {
400 case IDENTIFIER:
401 sym = _symbol_lookup(node->symbol);
402 if (sym != NULL) {
403 node->type = sym->type;
404 return sym->type;
406 break;
408 case INT_LITERAL:
409 case BOOL_LITERAL:
410 case CHAR_LITERAL:
411 return node->type;
413 case NOTFACTOR:
414 return BOOLEAN;
416 case CALL:
417 name = node->children->symbol->name;
418 sym = symbol_lookup(global_symtab, name);
419 if (sym != NULL) {
420 node->type = sym->type;
421 return sym->type;
423 break;
425 default:
426 return node->type;