-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path9cc.h
More file actions
141 lines (121 loc) · 2.9 KB
/
9cc.h
File metadata and controls
141 lines (121 loc) · 2.9 KB
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
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum
{
TK_NUM = 256, // integer token
TK_IDENT, // Identifier
TK_RETURN, // return
TK_IF, // if
TK_ELSE, // else
TK_WHILE, // while
TK_FOR, // for
TK_EQ, // ==
TK_NE, // !=
TK_LE, // <=
TK_GE, // >=
TK_EOF, // token representing end of input
};
enum
{
ND_NUM = 256, // integer node type
ND_IDENT, // Idenfitifer
ND_CALL, // function call
ND_RETURN, // return
ND_IF, // if
ND_ELSE, // else
ND_WHILE, // while
ND_FOR, // for
ND_BLOCK, // block
ND_EQ, // ==
ND_NE, // !=
ND_LE, // <=
ND_GE, // >=
};
/*
struct Token
int ty: TK_NUM if the content is an integer,
ASCII expression if the content is an operator like '+',
TK_EOF if the content is the end of input
int val: set to the integer value if ty is TK_NUM
char *input: pointer to the start of the token
*/
typedef struct
{
int ty; // type of token
int val; // if ty is TK_NUM, store its value
char *input; // token str (for error message)
int len; // Stores the length of the token, used only for TK_IDENT
} Token;
typedef struct
{
void **data;
int capacity;
int len;
} Vector;
typedef struct Node Node;
struct Node
{
int ty; // type
Node *lhs; // lhs
Node *rhs; // rhs
int val; // Used only when ty is ND_NUM
int offset; // Used only when ty is ND_IDENT
// while ('cond') 'body'
// if ('cond') 'then' else 'els
// for ('init'; 'cond'; 'then') 'body
Node *init;
Node *cond;
Node *body;
Node *then;
Node *els;
// Used when a block needs to store a series of stmts
Vector* stmts;
// Used when ty is ND_CALL
char *fnct_name;
};
typedef struct LVar LVar;
struct LVar
{
LVar *next;
char *name;
int len;
int offset;
};
/*
container.c
*/
Node *new_node(int ty, Node *lhs, Node *rhs);
Node *new_node_num(int val);
Node *new_node_ident(int offset);
Token *new_token();
// Vector
Vector *new_vector();
void vec_push(Vector *vec, void *elem);
void *vec_get(Vector *vec, int pos);
LVar *find_lvar(Token *token);
// parse.c
int consume(Vector *tokens, int ty);
void *program(Vector *tokens);
Node *assign(Vector *tokens);
Node *expr(Vector *tokens);
Node *stmt(Vector *tokens);
Node *add(Vector *tokens);
Node *mul(Vector *tokens);
Node *unary(Vector *tokens);
Node *term(Vector *tokens);
Node *relational(Vector *tokens);
Node *equality(Vector *tokens);
void vec_push(Vector *vec, void *elem);
// codegen.c
void gen_lval(Node *node);
void gen(Node *node);
// tokenize.c
int is_alnum(char c);
void tokenize(char *p, Vector *tokens);
// main.c
extern int pos;
extern Node *code[100];
extern LVar *locals;
extern unsigned int jump_count;