Skip to content

Commit

Permalink
feat: define variables with type
Browse files Browse the repository at this point in the history
  • Loading branch information
togami2864 committed Nov 3, 2021
1 parent da64e95 commit e4eeff1
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 48 deletions.
3 changes: 3 additions & 0 deletions 50cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ typedef enum {
TK_ELSE,
TK_WHILE,
TK_FOR,
TK_TYPE,
TK_EOF
} TokenKind;

Expand All @@ -40,6 +41,7 @@ bool consume_if();
bool consume_else();
bool consume_while();
bool consume_for();
bool consume_type();
void expect(char *op);
int expect_number();
bool at_eof();
Expand Down Expand Up @@ -101,6 +103,7 @@ Node *add();
Node *mul();
Node *unary();
Node *primary();
Node * define_variable();
Node *variable();

Node *new_node(NodeKind kind, Node *lhs, Node *rhs);
Expand Down
Binary file modified codegen.o
Binary file not shown.
Binary file modified main.o
Binary file not shown.
60 changes: 44 additions & 16 deletions parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ bool consume_for() {
return true;
}

bool consume_type() {
if (token->kind != TK_TYPE) return false;
token = token->next;
return true;
}

void expect(char *op) {
if (token->kind != TK_RESERVED || strlen(op) != token->len ||
memcmp(token->str, op, token->len))
Expand Down Expand Up @@ -201,10 +207,17 @@ Node *stmt() {

if (consume_return()) {
node = new_node(ND_RETURN, expr(), NULL);
} else {
node = expr();
expect(";");
return node;
}

if (consume_type()) {
Token *tok = consume_ident();
node = define_variable(tok);
expect(";");
return node;
}
node = expr();
expect(";");
return node;
}
Expand Down Expand Up @@ -311,25 +324,40 @@ Node *primary() {
return new_node_num(expect_number());
}

Node *variable(Token *tok) {
Node *define_variable(Token *tok) {
Node *node = calloc(1, sizeof(Node));
node->kind = ND_LVAR;

LVar *lvar = find_lvar(tok);
if (lvar) {
node->offset = lvar->offset;
if (lvar != NULL) {
char *name = calloc(1, tok->len + 1);
memcpy(name, tok->str, tok->len);
error("duplicated variable: %s\n", name);
}
lvar = calloc(1, sizeof(LVar));
lvar->next = locals[cur_func];
lvar->name = tok->str;
lvar->len = tok->len;
if (locals[cur_func] == NULL) {
lvar->offset = 8;
} else {
lvar = calloc(1, sizeof(LVar));
lvar->next = locals[cur_func];
lvar->name = tok->str;
lvar->len = tok->len;
if (locals[cur_func] == NULL) {
lvar->offset = 8;
} else {
lvar->offset = locals[cur_func]->offset + 8;
}
node->offset = lvar->offset;
locals[cur_func] = lvar;
lvar->offset = locals[cur_func]->offset + 8;
}
node->offset = lvar->offset;
locals[cur_func] = lvar;

return node;
}

Node *variable(Token *tok) {
Node *node = calloc(1, sizeof(Node));
node->kind = ND_LVAR;
LVar *lvar = find_lvar(tok);
if (lvar == NULL) {
char *name = calloc(1, tok->len + 1);
memcpy(name, tok->str, tok->len);
error("undefined variable: %s\n", name);
}
node->offset = lvar->offset;
return node;
}
Binary file modified parser.o
Binary file not shown.
72 changes: 40 additions & 32 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,22 @@ assert(){
fi
}

# assert 2 "main () { return 2;}"
# assert 3 "
# main() return func(1, 2);
# func(a, b) { return a + b; }
# "

# assert 4 "
# main() return func(1, 2, 3);
# func(a, b, c) { return a + c; }
# "

# assert 3 "main() {
# a = 4;
# return fib(a);
# }
# fib(n){
# if(n == 0) return 0;
# if(n == 1) return 1;
# return fib(n - 1)+ fib(n -2);
# }
# "

assert 4 "main(){x = 4;
y = &x;
return *y;
# define variables with type "int"
assert 5 "main() {
int x;
x = 5;
return x;
}"
# assert 42 "42;"
# assert 21 "5+20-4;"
# assert 2 " 5 - 3; "
# assert 47 "5+6*7;"
# assert 15 "5*(9-6);"
# assert 4 "(3+5)/2;"
# assert 10 "-10+20;"

# basic test case
assert 2 "main () { return 2;}"
assert 42 "main()return 42;"
assert 21 "main(){return 5+20-4;}"
assert 2 "main(){return 5 - 3;}"
assert 47 "main(){return 5+6*7;}"
assert 15 "main(){return 5*(9-6);}"
assert 4 "main(){ return (3+5)/2;}"
assert 10 "main(){ return -10+20;}"

# assert 0 "0==1;"
# assert 1 "42==42;"
Expand Down Expand Up @@ -87,6 +70,31 @@ return *y;
# else return 6;
# return 2;
# "
# assert 3 "
# main() return func(1, 2);
# func(a, b) { return a + b; }
# "

# assert 4 "
# main() return func(1, 2, 3);
# func(a, b, c) { return a + c; }
# "

# assert 3 "main() {
# a = 4;
# return fib(a);
# }
# fib(n){
# if(n == 0) return 0;
# if(n == 1) return 1;
# return fib(n - 1)+ fib(n -2);
# }
# "

# assert 4 "main(){x = 4;
# y = &x;
# return *y;
# }"

# assert 10 "i = 0;
# while (i < 10) i = i + 1;
Expand Down
6 changes: 6 additions & 0 deletions tokenize.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ Token *tokenize() {
continue;
}

if (startswith(p, "int") && !isalnum(p[3])) {
cur = new_token(TK_TYPE, cur, p, 3);
p += 3;
continue;
}

if ('a' <= *p && *p <= 'z') {
char *c = p;
while ('a' <= *c && *c <= 'z') {
Expand Down
Binary file modified tokenize.o
Binary file not shown.

0 comments on commit e4eeff1

Please sign in to comment.