blob: f914c349ee926696663bfcb6b800caea865a8c6a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#include "ast.h"
#include "scope.h"
#include <stdio.h>
#include <stdlib.h>
#define TYPE_PANIC(format, ...) {\
fprintf(\
stderr,\
"ccc: type error: " format "\n" __VA_OPT__(,)\
__VA_ARGS__);\
exit(1);\
}
static struct scope* scope;
static void type_check_group(struct group_node* node);
static void type_check_expr(struct expr_node* node) {}
static void type_check_var_decl(struct var_decl_node* node) {}
static void type_check_return(struct return_node* node) {}
static void type_check_stmt(struct stmt_node* node) {
switch (node->type) {
case STMT_EMPTY:
break;
case STMT_EXPR:
type_check_expr(&node->inner.expr);
break;
case STMT_VAR_DECL:
type_check_var_decl(&node->inner.var_decl);
break;
case STMT_RETURN:
type_check_return(&node->inner.return_);
break;
case STMT_GROUP:
type_check_group(&node->inner.group);
break;
}
}
static void type_check_group(struct group_node* node) {
if (node->scope->next_out != scope) TYPE_PANIC("scopes are borked");
scope = node->scope;
struct stmt_node* stmt = node->head;
while (stmt != NULL) {
type_check_stmt(stmt);
stmt = stmt->next;
}
}
static void type_check_fn_decl(struct fn_decl_node* node) {
scope = node->scope;
type_check_group(&node->body);
}
static void type_check_root(struct root_node* node) {
switch (node->type) {
case ROOT_FN_DECL:
type_check_fn_decl(&node->inner.fn_decl);
break;
}
}
void type_check(struct ast* ast) {
scope = ast->root_scope;
struct root_node* node = ast->root_node;
while (node != NULL) {
type_check_root(node);
node = node->next;
}
}
|