-
Notifications
You must be signed in to change notification settings - Fork 0
/
9cc.h
175 lines (136 loc) · 3.55 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
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef struct Type Type;
typedef struct Token Token;
typedef struct Var Var;
typedef struct Node Node;
typedef struct Function Function;
// トークンの種類
typedef enum {
TK_RESERVED, // 記号
TK_IDENT, // 識別子
TK_STR,
TK_NUM, // 整数トークン
TK_EOF // 入力の終わりを表すトークン
} TokenKind;
// 抽象構文木のノードの種類
typedef enum {
// statement
ND_IF,
ND_WHILE,
ND_FOR,
ND_RETURN,
ND_BLOCK,
ND_LVAR_DEF,
// expression
ND_ADD, // +
ND_SUB, // -
ND_MUL, // *
ND_DIV, // /
ND_MOD, // %
ND_ASSIGN, // 代入 =
ND_EQ, // ==
ND_NE, // !=
ND_LE, // <=
ND_LT, // <
ND_NUM, // 整数
ND_VAR, // 変数
ND_ADDR, // &
ND_DEREF, // *
ND_FUNC_CALL, // func()
ND_EXPR_STMT,
ND_STMT_EXPR,
ND_SIZEOF // sizeof add_type()で置き換えるのでcodegenでは出てこないはず
} NodeKind;
// トークン型
struct Token {
TokenKind kind; // トークンの型
Token *next; // 次の入力トークン
int val; // kindがTK_NUMの場合、その数値
char *str; // ソースコードの中でトークン文字列の開始部分
int len; // トークンの長さ
char *contents; // トークンの文字列(\nで終わる)
int contents_len; // contentsの長さ(len+1)
};
// 変数の型
struct Var {
Var *next; // 次の変数かNULL
char *name; // 変数の名前
Type *ty; // 型
int offset; // RBPからのオフセット
bool is_local;
char *init_data;
};
// 抽象構文木のノードの型
struct Node {
NodeKind kind; // ノードの型
Node *next; // リストの次のノード
Node *lhs; // 左辺
Node *rhs; // 右辺
int val; // kindがND_NUMの場合のみ使う
int offset; // kindがND_LVARの場合のみ使う
Var *var;
// if, while, for用
Node *cond;
Node *then;
Node *els;
Node *init;
Node *inc;
Node *body; // ステートメントのリスト
char *func_name;
Node *args; // 引数のリスト
Type *ty;
char *code; // 該当箇所のコード
Token *token_start; // 該当箇所の開始トークン
Token *token_end; // 該当箇所の終了トークン
};
struct Function {
Function *next;
char *name;
Node *block; // ND_BLOCKのNodeへのポインタ
Var *locals; // ローカル変数のリスト(引数含む)
Var *args; // 引数のリスト
Type *ret_ty; // 戻り値の型
};
typedef struct {
Var *globals;
Function *functions;
} Program;
typedef enum {
TY_CHAR,
TY_INT,
TY_PTR,
TY_ARRAY
} TypeKind;
struct Type {
TypeKind kind;
Type *base;
int size;
};
void file_error_at(char *loc, char *msg);
// tokenize.c
Token *tokenize(char *p);
void error(char *fmt, ...);
void error_at(char *loc, char *fmt, ...);
// parse.c
Program *program();
// type.c
void add_type(Function *prog);
Type *new_type(TypeKind kind);
Type *pointer_to(Type *base);
Type *array_of(Type *base, int length);
// codegen.c
void codegen(Program *pg);
/**
* グローバル変数
*/
extern Token *token; // 現在着目しているトークン
extern Token *prev_token; // 1つ前のトークン
// 入力プログラム
extern char *user_input;