polish tarjan
[ccc.git] / sem.c
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "list.h"
5 #include "sem/scc.h"
6 #include "ast.h"
7
8 void type_error(const char *msg, ...)
9 {
10 va_list ap;
11 va_start(ap, msg);
12 fprintf(stderr, "type error: ");
13 vfprintf(stderr, msg, ap);
14 va_end(ap);
15 die("");
16 }
17
18 void check_expr_constant(struct expr *expr)
19 {
20 switch (expr->type) {
21 case ebinop:
22 check_expr_constant(expr->data.ebinop.l);
23 check_expr_constant(expr->data.ebinop.r);
24 break;
25 case eunop:
26 check_expr_constant(expr->data.eunop.l);
27 break;
28 case efuncall:
29 case eident:
30 type_error("Initialiser is not constant\n");
31 break;
32 default:
33 break;
34 }
35 }
36
37 struct vardecl *type_vardecl(struct vardecl *vardecl)
38 {
39 return vardecl;
40 }
41
42 struct decl *type_decl(struct decl *decl)
43 {
44 switch (decl->type) {
45 case dcomp:
46 fprintf(stderr, "type_decl:component unsupported\n");
47 break;
48 case dfundecl:
49 fprintf(stderr, "type_decl:fundecl unsupported\n");
50 break;
51 case dvardecl:
52 decl->data.dvar = type_vardecl(decl->data.dvar);
53 break;
54 }
55 return decl;
56 }
57
58 struct ast *sem(struct ast *ast)
59 {
60 ast = ast_scc(ast);
61
62 //Check that all globals are constant
63 for (int i = 0; i<ast->ndecls; i++) {
64 if (ast->decls[i]->type == dvardecl) {
65 //Check globals
66 check_expr_constant(ast->decls[i]->data.dvar->expr);
67 break;
68 }
69 }
70 return ast;
71 }