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
);
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
;
51 typecheck_visit_pass(struct _Visitor
*visitor
, struct AstNode
*node
)
53 ast_node_accept_children(node
->children
, visitor
);
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
);
66 typecheck_visit_programdecl(struct _Visitor
*visitor
, struct AstNode
*node
)
69 ast_node_accept_children(node
->children
, visitor
);
73 typecheck_visit_procfunc_list(struct _Visitor
*visitor
, struct AstNode
*node
)
75 symtab
= global_symtab
;
76 ast_node_accept_children(node
->children
, visitor
);
80 typecheck_visit_procfunc(struct _Visitor
*visitor
, struct AstNode
*node
)
83 symtab
= node
->symbol
;
84 procfunc_symbol
= node
->children
->symbol
;
85 ast_node_accept_children(node
->children
, visitor
);
89 typecheck_visit_vardecl_list (struct _Visitor
*visitor
, struct AstNode
*node
)
92 symtab
= node
->parent
->symbol
;
93 ast_node_accept_children(node
->children
, visitor
);
97 typecheck_visit_vardecl (struct _Visitor
*visitor
, struct AstNode
*node
)
99 declared_type
= node
->type
;
100 ast_node_accept_children(node
->children
, visitor
);
104 typecheck_visit_parameter (struct _Visitor
*visitor
, struct AstNode
*node
)
107 declared_type
= node
->type
;
108 ast_node_accept_children(node
->children
, visitor
);
112 typecheck_visit_statement_list(struct _Visitor
*visitor
, struct AstNode
*node
)
115 declared_type
= VOID
;
116 symtab
= node
->parent
->symbol
;
117 ast_node_accept_children(node
->children
, visitor
);
121 _typecheck_print_stmt(struct AstNode
*node
, Type type
, const char *type_str
)
123 if (_get_expression_type(node
->children
) != type
) {
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
);
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
);
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
);
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
);
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
) {
161 "Error: Left side of assignment must be an Identifier. Check line %d.\n",
163 } else if (_get_expression_type(node1
) != _get_expression_type(node2
)) {
166 "Error: Incompatible types on assignment operation in line %d.\n",
169 ast_node_accept_children(node
->children
, visitor
);
173 typecheck_visit_if_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
175 struct AstNode
*expr
= node
->children
;
177 if (_get_expression_type(expr
) != BOOLEAN
) {
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
);
187 typecheck_visit_while_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
190 struct AstNode
*expr
= node
->children
;
192 type
= _get_expression_type(expr
);
193 if (type
!= BOOLEAN
) {
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
);
203 typecheck_visit_for_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
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
) {
215 "Error: Identifier '%s' is not of Integer type. "
217 id_node
->symbol
->name
, id_node
->linenum
);
219 type
= _get_expression_type(expr1_node
);
220 if (type
!= INTEGER
) {
223 "Error: Initial value of '%s' is not of Integer type. "
225 id_node
->symbol
->name
, expr1_node
->linenum
);
227 type
= _get_expression_type(expr1_node
);
228 if (type
!= INTEGER
) {
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
);
238 typecheck_visit_binary_expr (struct _Visitor
*visitor
, struct AstNode
*node
)
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
) {
252 "Error: Operation '%s' over incompatible types on line %d.\n",
253 operator->name
, operator->linenum
);
255 ast_node_accept_children(node
->children
, visitor
);
259 typecheck_visit_notfactor (struct _Visitor
*visitor
, struct AstNode
*node
)
261 Type type
= _get_expression_type(node
->children
->sibling
);
263 if (type
!= BOOLEAN
) {
266 "Error: Operation 'not' over non-boolean type on line %d.\n",
269 ast_node_accept_children(node
->children
, visitor
);
273 typecheck_visit_call (struct _Visitor
*visitor
, struct AstNode
*node
)
279 name
= node
->children
->symbol
->name
;
280 sym
= symbol_lookup(global_symtab
, name
);
281 procfunc_symbol
= sym
;
285 "Error: Undeclared function or procedure '%s' in line %d\n",
286 name
, node
->linenum
);
290 node
->type
= sym
->type
;
291 ast_node_accept_children(node
->children
, visitor
);
295 typecheck_visit_callparam_list (struct _Visitor
*visitor
, struct AstNode
*node
)
298 struct AstNode
*temp
;
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
));
310 if (i
> procfunc_symbol
->params
)
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
);
322 typecheck_visit_identifier (struct _Visitor
*visitor
, struct AstNode
*node
)
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",
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",
352 sym
= _symbol_lookup(node
->symbol
);
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
) {
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
);
381 _symbol_lookup(Symbol
*sym
)
383 Symbol
*symbol
= NULL
;
385 symbol
= symbol_lookup(symtab
, sym
->name
);
388 symbol
= symbol_lookup(global_symtab
, sym
->name
);
394 _get_expression_type(struct AstNode
*node
)
399 switch (node
->kind
) {
401 sym
= _symbol_lookup(node
->symbol
);
403 node
->type
= sym
->type
;
417 name
= node
->children
->symbol
->name
;
418 sym
= symbol_lookup(global_symtab
, name
);
420 node
->type
= sym
->type
;