Skip to content

Commit e4eeff1

Browse files
committed
feat: define variables with type
1 parent da64e95 commit e4eeff1

File tree

8 files changed

+93
-48
lines changed

8 files changed

+93
-48
lines changed

50cc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ typedef enum {
1515
TK_ELSE,
1616
TK_WHILE,
1717
TK_FOR,
18+
TK_TYPE,
1819
TK_EOF
1920
} TokenKind;
2021

@@ -40,6 +41,7 @@ bool consume_if();
4041
bool consume_else();
4142
bool consume_while();
4243
bool consume_for();
44+
bool consume_type();
4345
void expect(char *op);
4446
int expect_number();
4547
bool at_eof();
@@ -101,6 +103,7 @@ Node *add();
101103
Node *mul();
102104
Node *unary();
103105
Node *primary();
106+
Node * define_variable();
104107
Node *variable();
105108

106109
Node *new_node(NodeKind kind, Node *lhs, Node *rhs);

codegen.o

40 Bytes
Binary file not shown.

main.o

40 Bytes
Binary file not shown.

parser.c

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ bool consume_for() {
6464
return true;
6565
}
6666

67+
bool consume_type() {
68+
if (token->kind != TK_TYPE) return false;
69+
token = token->next;
70+
return true;
71+
}
72+
6773
void expect(char *op) {
6874
if (token->kind != TK_RESERVED || strlen(op) != token->len ||
6975
memcmp(token->str, op, token->len))
@@ -201,10 +207,17 @@ Node *stmt() {
201207

202208
if (consume_return()) {
203209
node = new_node(ND_RETURN, expr(), NULL);
204-
} else {
205-
node = expr();
210+
expect(";");
211+
return node;
206212
}
207213

214+
if (consume_type()) {
215+
Token *tok = consume_ident();
216+
node = define_variable(tok);
217+
expect(";");
218+
return node;
219+
}
220+
node = expr();
208221
expect(";");
209222
return node;
210223
}
@@ -311,25 +324,40 @@ Node *primary() {
311324
return new_node_num(expect_number());
312325
}
313326

314-
Node *variable(Token *tok) {
327+
Node *define_variable(Token *tok) {
315328
Node *node = calloc(1, sizeof(Node));
316329
node->kind = ND_LVAR;
317330

318331
LVar *lvar = find_lvar(tok);
319-
if (lvar) {
320-
node->offset = lvar->offset;
332+
if (lvar != NULL) {
333+
char *name = calloc(1, tok->len + 1);
334+
memcpy(name, tok->str, tok->len);
335+
error("duplicated variable: %s\n", name);
336+
}
337+
lvar = calloc(1, sizeof(LVar));
338+
lvar->next = locals[cur_func];
339+
lvar->name = tok->str;
340+
lvar->len = tok->len;
341+
if (locals[cur_func] == NULL) {
342+
lvar->offset = 8;
321343
} else {
322-
lvar = calloc(1, sizeof(LVar));
323-
lvar->next = locals[cur_func];
324-
lvar->name = tok->str;
325-
lvar->len = tok->len;
326-
if (locals[cur_func] == NULL) {
327-
lvar->offset = 8;
328-
} else {
329-
lvar->offset = locals[cur_func]->offset + 8;
330-
}
331-
node->offset = lvar->offset;
332-
locals[cur_func] = lvar;
344+
lvar->offset = locals[cur_func]->offset + 8;
345+
}
346+
node->offset = lvar->offset;
347+
locals[cur_func] = lvar;
348+
349+
return node;
350+
}
351+
352+
Node *variable(Token *tok) {
353+
Node *node = calloc(1, sizeof(Node));
354+
node->kind = ND_LVAR;
355+
LVar *lvar = find_lvar(tok);
356+
if (lvar == NULL) {
357+
char *name = calloc(1, tok->len + 1);
358+
memcpy(name, tok->str, tok->len);
359+
error("undefined variable: %s\n", name);
333360
}
361+
node->offset = lvar->offset;
334362
return node;
335363
}

parser.o

1.7 KB
Binary file not shown.

test.sh

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,39 +20,22 @@ assert(){
2020
fi
2121
}
2222

23-
# assert 2 "main () { return 2;}"
24-
# assert 3 "
25-
# main() return func(1, 2);
26-
# func(a, b) { return a + b; }
27-
# "
28-
29-
# assert 4 "
30-
# main() return func(1, 2, 3);
31-
# func(a, b, c) { return a + c; }
32-
# "
33-
34-
# assert 3 "main() {
35-
# a = 4;
36-
# return fib(a);
37-
# }
38-
# fib(n){
39-
# if(n == 0) return 0;
40-
# if(n == 1) return 1;
41-
# return fib(n - 1)+ fib(n -2);
42-
# }
43-
# "
44-
45-
assert 4 "main(){x = 4;
46-
y = &x;
47-
return *y;
23+
# define variables with type "int"
24+
assert 5 "main() {
25+
int x;
26+
x = 5;
27+
return x;
4828
}"
49-
# assert 42 "42;"
50-
# assert 21 "5+20-4;"
51-
# assert 2 " 5 - 3; "
52-
# assert 47 "5+6*7;"
53-
# assert 15 "5*(9-6);"
54-
# assert 4 "(3+5)/2;"
55-
# assert 10 "-10+20;"
29+
30+
# basic test case
31+
assert 2 "main () { return 2;}"
32+
assert 42 "main()return 42;"
33+
assert 21 "main(){return 5+20-4;}"
34+
assert 2 "main(){return 5 - 3;}"
35+
assert 47 "main(){return 5+6*7;}"
36+
assert 15 "main(){return 5*(9-6);}"
37+
assert 4 "main(){ return (3+5)/2;}"
38+
assert 10 "main(){ return -10+20;}"
5639

5740
# assert 0 "0==1;"
5841
# assert 1 "42==42;"
@@ -87,6 +70,31 @@ return *y;
8770
# else return 6;
8871
# return 2;
8972
# "
73+
# assert 3 "
74+
# main() return func(1, 2);
75+
# func(a, b) { return a + b; }
76+
# "
77+
78+
# assert 4 "
79+
# main() return func(1, 2, 3);
80+
# func(a, b, c) { return a + c; }
81+
# "
82+
83+
# assert 3 "main() {
84+
# a = 4;
85+
# return fib(a);
86+
# }
87+
# fib(n){
88+
# if(n == 0) return 0;
89+
# if(n == 1) return 1;
90+
# return fib(n - 1)+ fib(n -2);
91+
# }
92+
# "
93+
94+
# assert 4 "main(){x = 4;
95+
# y = &x;
96+
# return *y;
97+
# }"
9098

9199
# assert 10 "i = 0;
92100
# while (i < 10) i = i + 1;

tokenize.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ Token *tokenize() {
7575
continue;
7676
}
7777

78+
if (startswith(p, "int") && !isalnum(p[3])) {
79+
cur = new_token(TK_TYPE, cur, p, 3);
80+
p += 3;
81+
continue;
82+
}
83+
7884
if ('a' <= *p && *p <= 'z') {
7985
char *c = p;
8086
while ('a' <= *c && *c <= 'z') {

tokenize.o

280 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)