Skip to content

Commit 75fbd3d

Browse files
committed
Add [] operator
1 parent 5b2d571 commit 75fbd3d

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

parse.c

+18-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ static Node *equality(Token **rest, Token *tok);
3434
static Node *relational(Token **rest, Token *tok);
3535
static Node *add(Token **rest, Token *tok);
3636
static Node *mul(Token **rest, Token *tok);
37+
static Node *postfix(Token **rest, Token *tok);
3738
static Node *unary(Token **rest, Token *tok);
3839
static Node *primary(Token **rest, Token *tok);
3940

@@ -446,7 +447,7 @@ static Node *mul(Token **rest, Token *tok) {
446447
}
447448

448449
// unary = ("+" | "-" | "*" | "&") unary
449-
// | primary
450+
// | postfix
450451
static Node *unary(Token **rest, Token *tok) {
451452
if (equal(tok, "+"))
452453
return unary(rest, tok->next);
@@ -460,7 +461,22 @@ static Node *unary(Token **rest, Token *tok) {
460461
if (equal(tok, "*"))
461462
return new_unary(ND_DEREF, unary(rest, tok->next), tok);
462463

463-
return primary(rest, tok);
464+
return postfix(rest, tok);
465+
}
466+
467+
// postfix = primary ("[" expr "]")*
468+
static Node *postfix(Token **rest, Token *tok) {
469+
Node *node = primary(&tok, tok);
470+
471+
while (equal(tok, "[")) {
472+
// x[y] is short for *(x+y)
473+
Token *start = tok;
474+
Node *idx = expr(&tok, tok->next);
475+
tok = skip(tok, "]");
476+
node = new_unary(ND_DEREF, new_add(node, idx, start), start);
477+
}
478+
*rest = tok;
479+
return node;
464480
}
465481

466482
// funcall = ident "(" (assign ("," assign)*)? ")"

test.sh

+13
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,17 @@ assert 3 'int main() { int x[2][3]; int *y=x; *(y+3)=3; return **(x+1); }'
125125
assert 4 'int main() { int x[2][3]; int *y=x; *(y+4)=4; return *(*(x+1)+1); }'
126126
assert 5 'int main() { int x[2][3]; int *y=x; *(y+5)=5; return *(*(x+1)+2); }'
127127

128+
assert 3 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *x; }'
129+
assert 4 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *(x+1); }'
130+
assert 5 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *(x+2); }'
131+
assert 5 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *(x+2); }'
132+
assert 5 'int main() { int x[3]; *x=3; x[1]=4; 2[x]=5; return *(x+2); }'
133+
134+
assert 0 'int main() { int x[2][3]; int *y=x; y[0]=0; return x[0][0]; }'
135+
assert 1 'int main() { int x[2][3]; int *y=x; y[1]=1; return x[0][1]; }'
136+
assert 2 'int main() { int x[2][3]; int *y=x; y[2]=2; return x[0][2]; }'
137+
assert 3 'int main() { int x[2][3]; int *y=x; y[3]=3; return x[1][0]; }'
138+
assert 4 'int main() { int x[2][3]; int *y=x; y[4]=4; return x[1][1]; }'
139+
assert 5 'int main() { int x[2][3]; int *y=x; y[5]=5; return x[1][2]; }'
140+
128141
echo OK

0 commit comments

Comments
 (0)