-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathynicc.h
308 lines (265 loc) · 8.12 KB
/
ynicc.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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
#ifndef INCLUDED_YNICC
#define INCLUDED_YNICC
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
typedef struct Node Node;
typedef struct Var Var;
typedef struct VarList VarList;
typedef struct Program Program;
typedef struct Function Function;
typedef struct Token Token;
typedef struct Initializer Initializer;
// tokenize.c
typedef enum {
TK_DUMMY, // dummy
TK_RESERVED, // RESERVEDとなっているが今の時点では + または - の記号
TK_IDENT, // 識別子
TK_NUM, // 整数トークン
TK_RETURN, // return
TK_WHILE, // while
TK_DO, // do
TK_IF, // if
TK_ELSE, // else
TK_FOR, // for
TK_VOID, // void型
TK_BOOL, // bool型
TK_INT, // int型
TK_CHAR, // char型
TK_LONG, // long型
TK_SHORT, // short型
TK_STRUCT, // 構造体
TK_ENUM, // enum
TK_SIZEOF, // sizeof キーワード
TK_ALIGNOF, // _Alignof キーワード
TK_STR, // 文字列リテラル
TK_TYPEDEF, // typedef キーワード
TK_STATIC, // static キーワード
TK_EXTERN, // extern キーワード
TK_BREAK, // break キーワード
TK_CONTINUE, // continue キーワード
TK_GOTO, // goto キーワード
TK_SWITCH, // switch キーワード
TK_CASE, // case キーワード
TK_DEFAULT, // default キーワード
TK_EOF, // 入力終了
} TokenKind;
struct Token {
TokenKind kind; // トークンの型
Token *next; // 次の入力トークン
long val; // kindがTK_NUMの場合、その数値
char *str; // トークン文字列
int len; // str の長さ
// 文字列リテラル
char *contents;
// 文字列リテラルの長さ
int content_length;
};
Token *tokenize(char *p);
void free_tokens(Token *cur);
void dump_token(Token *token);
char *token_kind_to_s(TokenKind kind);
char *read_file(char *path);
// 現在着目しているトークン
extern Token *token;
// 入力プログラム
extern char *filename;
// 入力プログラム
extern char *user_input;
// type.c
typedef struct Type Type;
typedef struct Member Member;
typedef enum {
TY_DUMMY,
TY_VOID,
TY_BOOL,
TY_INT,
TY_CHAR,
TY_SHORT,
TY_LONG,
TY_PTR,
TY_ARRAY,
TY_STRUCT,
TY_ENUM,
TY_FUNC,
} TypeKind;
struct Type {
TypeKind kind;
int size; //サイズ(TY_ARRAYの場合は sizeof(要素) * array_size, それ以外の場合はsizeof(要素))
int align; // アラインされるバイト数
bool is_incomplete; // int ary[] のようなサイズがわからない状態で宣言されているときにtrueになるフラグ
Type *ptr_to; // arrayかpointerの場合の型
long array_size; // kind が TY_ARRAY のときに配列サイズがセットされる
Member *members; // 構造体の場合のフィールド達
Type *return_ty; // 関数型の場合の戻り値の型
};
struct Member {
Member *next;
Type *ty;
char *name;
int offset; // 構造体の変数自体からこのメンバーへのオフセット
};
extern Type *void_type;
extern Type *bool_type;
extern Type *int_type;
extern Type *char_type;
extern Type *long_type;
extern Type *short_type;
void add_type(Node *node);
bool is_integer(Type *t);
bool is_pointer(Type *t);
Type *pointer_to(Type *t);
int node_type_size(Node * node);
Type *array_of(Type *ptr_to, int array_size);
Type *func_type(Type *ret_type);
Type *enum_type(void);
Type *struct_type(void);
// parser.c
// ASTのノード種別
typedef enum {
ND_DUMMY, // dummy
ND_ADD, // num + num
ND_PTR_ADD, // num + ptr, ptr + num
ND_SUB, // num - num
ND_PTR_SUB, // ptr - num
ND_PTR_DIFF, // ptr - ptr
ND_MUL, // *
ND_DIV, // /
ND_MOD, // %
ND_LT, // <
ND_LTE, // <=
ND_OR, // ||
ND_AND, // &&
ND_BIT_OR, // |
ND_BIT_AND, // &
ND_A_LSHIFT , // 算術左シフト
ND_A_RSHIFT , // 算術右シフト
ND_BIT_XOR, // ^
ND_EQL, // ==
ND_NOT_EQL, // !=
ND_NOT, // 否定?演算子 if (!x) とかの!
ND_BIT_NOT, // ~演算子 bit反転する
ND_ASSIGN, // =
ND_VAR, // ローカル変数
ND_RETURN, // return
ND_WHILE, // while
ND_BLOCK, // { stmt* } のブロック
ND_IF, // if文
ND_FOR, // for文
ND_CALL, // 関数呼び出し
ND_ADDR, // &演算子でのアドレス取得
ND_DEREF, // *演算子でのアドレス参照
ND_VAR_DECL, // 変数定義
ND_EXPR_STMT, // 式文
ND_NUM, // 整数
ND_MEMBER, // 構造体のメンバーへの参照
ND_CAST, // cast
ND_COMMA, // カンマ演算子
ND_POST_INC, // x++
ND_POST_DEC, // x--
ND_PRE_INC, // ++x
ND_PRE_DEC, // --x
ND_BREAK, // break
ND_CONTINUE, // continue
ND_GOTO, // goto
ND_LABEL, // ラベル
ND_SWITCH, // switch
ND_CASE, // case
ND_TERNARY, // x ? y : z (コード生成の実態はifと同じにする)
ND_NULL, // 何もしないノード
} NodeKind;
struct Program {
VarList *global_var;
Function *functions;
};
struct Function {
Function *next; //次の関数
Type *return_type; //戻り値の型
char *name; // 関数名
Node *body; // 関数定義本体
VarList *locals; //この関数のローカル変数情報
VarList *params; //この関数の仮引数
int stack_size; //この関数のスタックサイズ
bool is_staitc;
bool has_vararg; // 引数に ... をとるかどうか
};
struct Node {
NodeKind kind;
Token *tok;
Type *ty;
Node *lhs; // 二項演算での左辺
Node *rhs; // 二項演算での右辺
Node *body; //while, forとかの本文
Node *next; // ブロックや関数引数など複数Nodeになる場合の次のnode
Node *cond; // if, while, for の条件式
Node *then; // ifの then節
Node *els; // ifのelse節
bool is_do_while; // do_while と while 分の区別
Node *init; // forの初期化式
Node *inc; // forの継続式
Node *initializer; // 変数の初期化式
Node *arg; //関数の引数
Var *var; //ND_VAR, ND_VAR_DECLのときの変数情報
long val; // kindがND_NUMの場合の値
char *funcname; // 関数名
int funcarg_num; // 関数呼び出しの引数の数
Member *member; // 構造体のメンバーへのアクセス時の対象のメンバー
char *label_name;
long case_cond_val; // switch文のcaseの値
bool is_default_case; // ND_CASEの場合にそれがdefaultならtrue
Node *default_case; // ND_SWITHの場合にdefault節のノード
Node *case_next; // caseのジャンプのコード生成用の1switch中のcaseノードのリスト
};
struct Var {
Type *type; // この変数の型
char *name; // この変数の名前
int offset; // rbpからのオフセット
bool is_local; // local、global変数の識別用フラグ
// グローバル変数の初期化式(文字列リテラル用の変数も含む)
Initializer *initializer;
bool is_static;
};
struct VarList {
VarList *next; // 次の変数
Var *var; // 変数の実体へのポインタ
};
// グローバル変数の初期化式
// グルーバル変数は定数式か他のグローバル変数へのポインタのみ設定できる
struct Initializer {
Initializer *next;
// 定数式用
int sz;
long val;
// ポインタ用(指す先のグローバル変数のラベル)
char *label;
long addend;
};
void error_at(char *loc, char *fmt, ...);
void error(char *fmt, ...);
void free_program(Program *function);
char *node_kind_to_s(Node *nd);
char *my_strndup(char *str, int len);
Node *new_var_node(Var *var, Token *tk);
Program *program();
// codegen.c
void codegen(Program *prg);
// debug.c
char *function_body_ast(Function *f);
char *node_ast(Node *node);
void dump_function(Function *f);
void dump_globals(VarList *vars);
void dump_tokens(Token *t);
char *type_info(Type *type);
// string_buffer.c
typedef struct string_buffer string_buffer;
string_buffer *sb_init();
void sb_append_char(string_buffer *sb, int ch);
void sb_free(string_buffer *sb);
char *sb_str(string_buffer *sb);
int sb_str_len(string_buffer *sb);
#endif