-
Notifications
You must be signed in to change notification settings - Fork 0
/
9cc.h
193 lines (160 loc) · 3.22 KB
/
9cc.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
190
191
192
193
// vim:set filetype=c tabstop=8 shiftwidth=8 noexpandtab:
#ifndef NINE_CC_H
#define NINE_CC_H
// Vector
struct Vector;
typedef struct Vector Vector;
Vector *new_vector();
void vec_push(Vector *vec, void *elem);
int vec_len(Vector *vec);
void *vec_at(Vector *vec, int i);
char *string_join(Vector *strings, char *sep);
//
// Tokenizer
//
// input
extern char *user_input;
// token types
enum TokenKind {
TK_NUM = 256, // integer
TK_IF,
TK_ELSE,
TK_WHILE,
TK_FOR,
TK_RETURN,
TK_SIZEOF,
TK_IDENT,
TK_EOF,
TK_EQ,
TK_NE,
TK_LE,
TK_GE,
TK_INT,
};
// token
typedef struct {
enum TokenKind kind;
int val;
char *name;
char *input;
} Token;
void init_tokens();
Token *tokens(int i);
void dump_tokens();
// function for reporting an error
void error(char *fmt, ...);
// function for reporting error location
void error_at(char *loc, char *fmt, ...);
// tokenize a string pointed by user_input and save them to tokens
void tokenize(char *p);
//
// Parser
//
struct Node;
typedef struct Node Node;
// position for parser
extern int pos;
// types
enum TypeKind {
TP_UNDETERMINED,
TP_INT,
TP_POINTER,
TP_FUNCTION,
TP_ARRAY,
};
typedef struct Type {
enum TypeKind kind;
struct Type *ptr_to;
Vector *params;
struct Type *returning;
int array_size;
} Type;
Type *new_type_int();
Type *new_type_ptr(Type *ptr_to);
Type *new_type_function(Vector *params, Type *returning);
Type *new_type_array(Type *ptr_to, int array_size);
Type *new_type_undetermined();
char *type_name(Type *tp);
int type_size(Type *tp);
int type_size_refering(Type *tp);
// variables
typedef struct Var {
struct Var *next;
char *name;
int offset;
Type *type;
} Var;
void var_use(Node *node);
void var_put(char *name, Type *tp);
Var *var_get(char *name);
int var_duplicated(char *name);
typedef struct Scope {
struct Scope *next;
Var *vars;
Var *sentinel;
} Scope;
Scope *scope_use(Scope *scope);
void init_global_scope();
void init_function_scope();
void set_function_scope(Node *node);
void set_scope(Node *node);
void push_scope();
void pop_scope();
void dump_scope(Scope *scope, int level);
// node types
enum NodeKind {
ND_NUM = 256,
ND_DEREF,
ND_ENREF,
ND_DECLARE_FUNC,
ND_DEFINE_FUNC,
ND_DEFINE_INT_VAR,
ND_BLOCK,
ND_FUNCALL,
ND_IF,
ND_ELSE,
ND_WHILE,
ND_FOR,
ND_RETURN,
ND_SIZEOF,
ND_IDENT,
ND_EQ,
ND_NE,
ND_LE,
};
struct Node {
int kind; // node type
Node *lhs, *rhs; // for binary/unary operators
Node *cond; // for ND_IF, ND_WHILE, ND_FOR
Node *thenc, *elsec; // for ND_IF syntax
Node *init, *update; // for ND_FOR syntax
Node *body; // for ND_DEFINE_FUNC, ND_WHILE, ND_FOR
int val; // for ND_NUM
char *name; // for ND_IDENT, ND_DEFINE_FUNC
Vector *stmts; // for ND_BLOCK
Vector *args; // for ND_FUNCALL
Vector *params; // for ND_DEFINE_FUNC
Scope *scope; // for ND_DEFINE_FUNC, ND_BLOCK
int max_offset; // for ND_DEFINE_FUNC
Type *type; // for ND_IDENT
char *input; // for ND_DEFINE_INT_VAR, ND_IDENT
};
Node *new_node(int node_type, Node *lhs, Node *rhs);
Node *new_node_num(int val);
Node *node_dup(Node *node);
void dump_nodes();
Node *code(int i);
void program();
//
// Semantic Analysis
//
void sema();
//
// Code Generator
//
void gen(Node *node);
//
// Test
//
void runtest();
#endif // NINE_CC_H