diff --git a/parse.c b/parse.c index a5afba7a..a17b99b6 100644 --- a/parse.c +++ b/parse.c @@ -34,6 +34,7 @@ static Node *equality(Token **rest, Token *tok); static Node *relational(Token **rest, Token *tok); static Node *add(Token **rest, Token *tok); static Node *mul(Token **rest, Token *tok); +static Node *postfix(Token **rest, Token *tok); static Node *unary(Token **rest, Token *tok); static Node *primary(Token **rest, Token *tok); @@ -446,7 +447,7 @@ static Node *mul(Token **rest, Token *tok) { } // unary = ("+" | "-" | "*" | "&") unary -// | primary +// | postfix static Node *unary(Token **rest, Token *tok) { if (equal(tok, "+")) return unary(rest, tok->next); @@ -460,7 +461,22 @@ static Node *unary(Token **rest, Token *tok) { if (equal(tok, "*")) return new_unary(ND_DEREF, unary(rest, tok->next), tok); - return primary(rest, tok); + return postfix(rest, tok); +} + +// postfix = primary ("[" expr "]")* +static Node *postfix(Token **rest, Token *tok) { + Node *node = primary(&tok, tok); + + while (equal(tok, "[")) { + // x[y] is short for *(x+y) + Token *start = tok; + Node *idx = expr(&tok, tok->next); + tok = skip(tok, "]"); + node = new_unary(ND_DEREF, new_add(node, idx, start), start); + } + *rest = tok; + return node; } // funcall = ident "(" (assign ("," assign)*)? ")" diff --git a/test.sh b/test.sh index bdd2dc15..8918c0d7 100755 --- a/test.sh +++ b/test.sh @@ -125,4 +125,17 @@ assert 3 'int main() { int x[2][3]; int *y=x; *(y+3)=3; return **(x+1); }' assert 4 'int main() { int x[2][3]; int *y=x; *(y+4)=4; return *(*(x+1)+1); }' assert 5 'int main() { int x[2][3]; int *y=x; *(y+5)=5; return *(*(x+1)+2); }' +assert 3 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *x; }' +assert 4 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *(x+1); }' +assert 5 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *(x+2); }' +assert 5 'int main() { int x[3]; *x=3; x[1]=4; x[2]=5; return *(x+2); }' +assert 5 'int main() { int x[3]; *x=3; x[1]=4; 2[x]=5; return *(x+2); }' + +assert 0 'int main() { int x[2][3]; int *y=x; y[0]=0; return x[0][0]; }' +assert 1 'int main() { int x[2][3]; int *y=x; y[1]=1; return x[0][1]; }' +assert 2 'int main() { int x[2][3]; int *y=x; y[2]=2; return x[0][2]; }' +assert 3 'int main() { int x[2][3]; int *y=x; y[3]=3; return x[1][0]; }' +assert 4 'int main() { int x[2][3]; int *y=x; y[4]=4; return x[1][1]; }' +assert 5 'int main() { int x[2][3]; int *y=x; y[5]=5; return x[1][2]; }' + echo OK