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
*tc_visitor
= (Visitor
*) malloc (sizeof(Visitor
));
15 tc_visitor
->visit_program
= &typecheck_visit_program
;
16 tc_visitor
->visit_programdecl
= &typecheck_visit_programdecl
;
17 tc_visitor
->visit_vardecl_list
= &typecheck_visit_vardecl_list
;
18 tc_visitor
->visit_vardecl
= &typecheck_visit_vardecl
;
19 tc_visitor
->visit_identifier_list
= &typecheck_visit_donothing
;
20 tc_visitor
->visit_procfunc_list
= &typecheck_visit_procfunc_list
;
21 tc_visitor
->visit_procedure
= &typecheck_visit_procfunc
;
22 tc_visitor
->visit_function
= &typecheck_visit_procfunc
;
23 tc_visitor
->visit_param_list
= &typecheck_visit_donothing
;
24 tc_visitor
->visit_parameter
= &typecheck_visit_parameter
;
25 tc_visitor
->visit_statement_list
= &typecheck_visit_statement_list
;
26 tc_visitor
->visit_print_stmt
= &typecheck_visit_print_stmt
;
27 tc_visitor
->visit_assignment_stmt
= &typecheck_visit_assignment_stmt
;
28 tc_visitor
->visit_if_stmt
= &typecheck_visit_if_stmt
;
29 tc_visitor
->visit_while_stmt
= &typecheck_visit_while_stmt
;
30 tc_visitor
->visit_for_stmt
= &typecheck_visit_for_stmt
;
31 tc_visitor
->visit_rel_expr
= &typecheck_visit_binary_expr
;
32 tc_visitor
->visit_add_expr
= &typecheck_visit_binary_expr
;
33 tc_visitor
->visit_mul_expr
= &typecheck_visit_binary_expr
;
34 tc_visitor
->visit_notfactor
= &typecheck_visit_notfactor
;
35 tc_visitor
->visit_call
= &typecheck_visit_call
;
36 tc_visitor
->visit_callparam_list
= &typecheck_visit_callparam_list
;
37 tc_visitor
->visit_identifier
= &typecheck_visit_identifier
;
38 tc_visitor
->visit_literal
= &typecheck_visit_donothing
;
39 tc_visitor
->close_group
= NULL
;
43 typecheck_visit_donothing(struct AstNode
*node
)
48 typecheck_visit_program(struct AstNode
*node
)
50 node
->symbol
= symbol_new(NULL
);
51 global_symtab
= node
->symbol
;
52 symtab
= global_symtab
;
56 typecheck_visit_programdecl(struct AstNode
*node
)
62 typecheck_visit_procfunc_list(struct AstNode
*node
)
64 symtab
= global_symtab
;
68 typecheck_visit_procfunc(struct AstNode
*node
)
71 symtab
= node
->symbol
;
72 procfunc_symbol
= node
->children
->symbol
;
76 typecheck_visit_vardecl_list (struct AstNode
*node
)
79 symtab
= node
->parent
->symbol
;
83 typecheck_visit_vardecl (struct AstNode
*node
)
85 declared_type
= node
->type
;
89 typecheck_visit_parameter (struct AstNode
*node
)
92 declared_type
= node
->type
;
96 typecheck_visit_statement_list(struct AstNode
*node
)
100 symtab
= node
->parent
->symbol
;
104 typecheck_visit_print_stmt (struct AstNode
*node
)
109 typecheck_visit_assignment_stmt (struct AstNode
*node
)
111 struct AstNode
*node1
= node
->children
;
112 struct AstNode
*node2
= node1
->sibling
;
114 if (node1
->kind
!= IDENTIFIER
) {
116 "Error: Left side of assignment must be an Identifier. Check line %d.\n",
121 if (_get_expression_type(node1
) != _get_expression_type(node2
)) {
124 "Error: Incompatible types on assignment operation in line %d.\n",
130 typecheck_visit_if_stmt (struct AstNode
*node
)
132 struct AstNode
*node1
= node
->children
;
133 struct AstNode
*node2
= node1
->sibling
;
134 struct AstNode
*node3
= node2
->sibling
;
136 /*if (_get_expression_type(node1) != BOOLEAN) {
139 "Error: Condition for if statement must return a boolean. Check line %d.\n",
145 typecheck_visit_while_stmt (struct AstNode
*node
)
150 typecheck_visit_for_stmt (struct AstNode
*node
)
153 struct AstNode
*assign_node
= node
->children
;
154 struct AstNode
*id_node
= assign_node
->children
;
155 struct AstNode
*expr1_node
= id_node
->sibling
;
156 struct AstNode
*expr2_node
= assign_node
->sibling
;
158 type
= _get_expression_type(id_node
);
159 if (type
!= INTEGER
) {
162 "Error: Identifier '%s' is not of Integer type. "
164 id_node
->symbol
->name
, id_node
->linenum
);
166 type
= _get_expression_type(expr1_node
);
167 if (type
!= INTEGER
) {
170 "Error: Initial value of '%s' is not of Integer type. "
172 id_node
->symbol
->name
, expr1_node
->linenum
);
174 type
= _get_expression_type(expr1_node
);
175 if (type
!= INTEGER
) {
178 "Error: Value of stop condition is not of Integer type. "
179 "Check line %d.\n", expr2_node
->linenum
);
184 typecheck_visit_binary_expr (struct AstNode
*node
)
189 struct AstNode
*node1
= node
->children
;
190 struct AstNode
*operator = node1
->sibling
;
191 struct AstNode
*node2
= operator->sibling
;
193 type1
= _get_expression_type(node1
);
194 type2
= _get_expression_type(node2
);
196 if (type1
!= type2
) {
199 "Error: Operation '%s' over incompatible types on line %d.\n",
200 operator->name
, operator->linenum
);
205 typecheck_visit_notfactor (struct AstNode
*node
)
210 typecheck_visit_call (struct AstNode
*node
)
216 name
= node
->children
->symbol
->name
;
217 sym
= symbol_lookup(global_symtab
, name
);
218 procfunc_symbol
= sym
;
222 "Error: Undeclared function or procedure '%s' in line %d\n",
223 name
, node
->linenum
);
227 node
->type
= sym
->type
;
231 typecheck_visit_callparam_list (struct AstNode
*node
)
234 struct AstNode
*temp
;
237 for (temp
= node
->children
; temp
!= NULL
; temp
= temp
->sibling
) {
238 if (temp
->type
!= procfunc_symbol
->param_types
[i
]) {
239 fprintf(stderr
, "Error: Call '%s' on line %d, expecting %s, received %s.\n",
240 procfunc_symbol
->name
, node
->linenum
,
241 type_get_lexeme(procfunc_symbol
->param_types
[i
]),
242 type_get_lexeme(temp
->type
));
246 if (i
> procfunc_symbol
->params
)
249 if (i
!= procfunc_symbol
->params
) {
250 fprintf(stderr
, "Error: Expecting %d parameters, received %d.\n",
251 i
, procfunc_symbol
->params
);
256 typecheck_visit_identifier (struct AstNode
*node
)
261 node
->type
= declared_type
;
262 node
->symbol
->type
= declared_type
;
263 sym
= symbol_insert(symtab
, node
->symbol
);
265 if (node
->parent
->kind
== PARAMETER
) {
266 procfunc_symbol
->param_types
[procfunc_symbol
->params
] = node
->symbol
->type
;
267 procfunc_symbol
->params
++;
270 if (sym
!= node
->symbol
)
271 fprintf(stderr
, "Error: Symbol '%s' already defined in line XX\n",
274 } else if (node
->parent
->kind
== FUNCTION
||
275 node
->parent
->kind
== PROCEDURE
) {
276 sym
= symbol_insert(global_symtab
, node
->symbol
);
277 node
->type
= node
->symbol
->type
;
278 node
->parent
->type
= node
->type
;
279 procfunc_symbol
= node
->symbol
;
281 if (sym
!= node
->symbol
)
282 fprintf(stderr
, "Error: Symbol '%s' already defined in line XX\n",
286 sym
= _symbol_lookup(node
->symbol
);
291 node
->symbol
->decl_linenum
= 0;
292 fprintf(stderr
, "Error: Undeclared symbol '%s' in line %d\n",
293 node
->symbol
->name
, node
->linenum
);
296 if (node
->parent
->kind
== CALLPARAM_LIST
) {
298 //procfunc_symbol->param_types[procfunc_symbol->params] = node->symbol->type;
299 //procfunc_symbol->params++;
300 fprintf(stderr
, "Parameter: %s (%x)\n",
301 procfunc_symbol
->name
, procfunc_symbol
);
302 fprintf(stderr
, "types (%d): ", procfunc_symbol
->params
);
303 for (i
= 0; i
< procfunc_symbol
->params
; i
++) {
304 fprintf(stderr
, "%d ",
305 procfunc_symbol
->param_types
[procfunc_symbol
->params
]);
307 fprintf(stderr
, "\n");
314 _symbol_lookup(Symbol
*sym
)
316 Symbol
*symbol
= NULL
;
318 symbol
= symbol_lookup(symtab
, sym
->name
);
321 symbol
= symbol_lookup(global_symtab
, sym
->name
);
327 _get_expression_type(struct AstNode
*node
)
332 switch (node
->kind
) {
334 sym
= _symbol_lookup(node
->symbol
);
336 node
->type
= sym
->type
;
355 name
= node
->children
->symbol
->name
;
356 sym
= symbol_lookup(global_symtab
, name
);
358 node
->type
= sym
->type
;
368 _get_func_type(struct AstNode *node)
373 if (node->kind != FUNCTION)
376 name = node->children->symbol->name;
377 symbol = symbol_lookup(global_symtab, name);
379 if (symbol == NULL) {
380 fprintf(stderr, "Error: Undeclared symbol '%s' in line %d\n",
381 name, node->linenum);