-
Notifications
You must be signed in to change notification settings - Fork 0
/
ast.h
189 lines (164 loc) · 3.91 KB
/
ast.h
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#ifndef AST_INCLUDED
#define AST_INCLUDED
#include <stdio.h>
#include "hash_table.h"
struct prog {
struct decl *ast;
struct hash_table *strings;
struct symbol *symbols;
};
extern struct prog *prog_make(struct decl *ast);
extern void prog_add_string(struct prog *prog, const char *string);
extern void prog_free(struct prog **pp);
enum reg {
REG_EBX = 1,
REG_ECX = 2,
REG_EDX = 4,
REG_ESI = 8,
REG_EDI = 16,
REG_EAX = 32
};
extern const char *reg_to_s(enum reg);
struct decl {
char *name;
struct type *type;
struct expr *value;
struct stmt *code;
struct symbol *symbol;
struct decl *next;
int num_locals;
enum reg regs;
};
extern struct decl *decl_make(char *name, struct type *type, struct expr *value, struct stmt *code);
extern void decl_free(struct decl **dp);
enum type_kind {
TYPE_UNKNOWN,
TYPE_CHAR,
TYPE_INT,
TYPE_STRING,
TYPE_BOOLEAN,
TYPE_VOID,
TYPE_FUNCTION
};
extern const char *type_kind_to_s(enum type_kind kind);
struct type {
enum type_kind kind;
struct param *params;
struct type *rtype;
};
extern struct type *type_make(enum type_kind kind, struct param *params, struct type *rtype);
extern void type_free(struct type **tp);
enum expr_kind {
EXPR_LE = 1,
EXPR_LT,
EXPR_EQ,
EXPR_NE,
EXPR_GT,
EXPR_GE,
EXPR_NOT,
EXPR_ADD,
EXPR_SUB,
EXPR_MUL,
EXPR_DIV,
EXPR_POS,
EXPR_NEG,
EXPR_MOD,
EXPR_ASSIGN,
EXPR_CALL,
EXPR_ARG,
EXPR_NAME,
EXPR_INT,
EXPR_CHAR,
EXPR_BOOLEAN,
EXPR_PRE_INCR,
EXPR_PRE_DECR,
EXPR_POST_INCR,
EXPR_POST_DECR,
EXPR_OR,
EXPR_AND,
EXPR_POW,
EXPR_STRING
};
extern const char *expr_kind_to_s(enum expr_kind kind);
struct expr {
enum expr_kind kind;
struct expr *left;
struct expr *right;
char *name;
int constant;
struct symbol *symbol;
enum reg reg;
};
extern struct expr *expr_make(enum expr_kind kind, struct expr *left, struct expr *right, char *name, int constant);
extern struct expr *expr_copy(struct expr *e);
extern void expr_free(struct expr **ep);
extern enum type_kind expr_to_type_kind(struct expr *e);
extern int expr_is_const(struct expr *e);
extern int expr_has_effects(struct expr *e);
enum stmt_kind {
STMT_DECL,
STMT_EXPR,
STMT_IF_ELSE,
STMT_WHILE,
STMT_RETURN,
STMT_BLOCK,
STMT_PRINT
};
struct stmt {
enum stmt_kind kind;
struct decl *decl;
struct expr *expr;
struct stmt *body;
struct stmt *ebody;
struct stmt *next;
};
extern struct stmt *stmt_make(enum stmt_kind kind, struct decl *decl, struct expr *expr, struct stmt *body, struct stmt *ebody);
extern void stmt_free(struct stmt **sp);
enum symbol_kind {
SYMBOL_GLOBAL,
SYMBOL_PARAM,
SYMBOL_LOCAL
};
struct symbol {
enum symbol_kind kind;
int which;
struct type *type;
char *name;
int offset;
int init;
struct expr *value;
int num_reads;
int num_writes;
struct symbol *next;
};
extern struct symbol *symbol_make(enum symbol_kind kind, struct type *type, char *name, struct prog *prog);
extern void symbol_free(struct symbol **sp);
struct param {
char *name;
struct type *type;
struct param *next;
};
extern struct param *param_make(char *name, struct type *type, struct param *next);
extern void param_free(struct param **pp);
enum config_flag {
FLAG_PRINT_RESOLVE = 1,
FLAG_PRINT_ANNOTATE = 2
};
struct config {
FILE *fout;
FILE *ferr;
int opt_level;
enum config_flag flags;
};
typedef void (*ast_pass)(struct prog *, struct config *);
extern void ast_print(struct prog *prog, struct config *cfg);
extern void ast_resolve(struct prog *prog, struct config *cfg);
extern void ast_typecheck(struct prog *prog, struct config *cfg);
extern void ast_canon(struct prog *prog, struct config *cfg);
extern void ast_reduce(struct prog *prog, struct config *cfg);
extern void ast_annotate(struct prog *prog, struct config *cfg);
extern void ast_inline(struct prog *prog, struct config *cfg);
extern void ast_prune(struct prog *prog, struct config *cfg);
extern void ast_alloc(struct prog *prog, struct config *cfg);
extern void ast_codegen(struct prog *prog, struct config *cfg);
#endif