mirror of https://github.com/rui314/chibicc
Add GNU expression statement
This commit is contained in:
parent
e648f9fba5
commit
ca52c2c7fd
3
chibi.h
3
chibi.h
|
@ -98,6 +98,7 @@ typedef enum {
|
|||
ND_BLOCK, // { ... }
|
||||
ND_FUNCALL, // Function call
|
||||
ND_EXPR_STMT, // Expression statement
|
||||
ND_STMT_EXPR, // Statement expression
|
||||
ND_VAR, // Variable
|
||||
ND_NUM, // Integer
|
||||
ND_NULL, // Empty statement
|
||||
|
@ -121,7 +122,7 @@ struct Node {
|
|||
Node *init;
|
||||
Node *inc;
|
||||
|
||||
// Block
|
||||
// Block or statement expression
|
||||
Node *body;
|
||||
|
||||
// Function call
|
||||
|
|
|
@ -139,6 +139,7 @@ static void gen(Node *node) {
|
|||
return;
|
||||
}
|
||||
case ND_BLOCK:
|
||||
case ND_STMT_EXPR:
|
||||
for (Node *n = node->body; n; n = n->next)
|
||||
gen(n);
|
||||
return;
|
||||
|
|
33
parse.c
33
parse.c
|
@ -463,6 +463,26 @@ static Node *postfix(void) {
|
|||
return node;
|
||||
}
|
||||
|
||||
// stmt-expr = "(" "{" stmt stmt* "}" ")"
|
||||
//
|
||||
// Statement expression is a GNU C extension.
|
||||
static Node *stmt_expr(Token *tok) {
|
||||
Node *node = new_node(ND_STMT_EXPR, tok);
|
||||
node->body = stmt();
|
||||
Node *cur = node->body;
|
||||
|
||||
while (!consume("}")) {
|
||||
cur->next = stmt();
|
||||
cur = cur->next;
|
||||
}
|
||||
expect(")");
|
||||
|
||||
if (cur->kind != ND_EXPR_STMT)
|
||||
error_tok(cur->tok, "stmt expr returning void is not supported");
|
||||
memcpy(cur, cur->lhs, sizeof(Node));
|
||||
return node;
|
||||
}
|
||||
|
||||
// func-args = "(" (assign ("," assign)*)? ")"
|
||||
static Node *func_args(void) {
|
||||
if (consume(")"))
|
||||
|
@ -478,12 +498,19 @@ static Node *func_args(void) {
|
|||
return head;
|
||||
}
|
||||
|
||||
// primary = "(" expr ")" | "sizeof" unary | ident func-args? | str | num
|
||||
// args = "(" ident ("," ident)* ")"
|
||||
// primary = "(" "{" stmt-expr-tail
|
||||
// | "(" expr ")"
|
||||
// | "sizeof" unary
|
||||
// | ident func-args?
|
||||
// | str
|
||||
// | num
|
||||
static Node *primary(void) {
|
||||
Token *tok;
|
||||
|
||||
if (consume("(")) {
|
||||
if (tok = consume("(")) {
|
||||
if (consume("{"))
|
||||
return stmt_expr(tok);
|
||||
|
||||
Node *node = expr();
|
||||
expect(")");
|
||||
return node;
|
||||
|
|
5
test.sh
5
test.sh
|
@ -183,4 +183,9 @@ assert 106 'int main() { return "\j"[0]; }'
|
|||
assert 107 'int main() { return "\k"[0]; }'
|
||||
assert 108 'int main() { return "\l"[0]; }'
|
||||
|
||||
assert 0 'int main() { return ({ 0; }); }'
|
||||
assert 2 'int main() { return ({ 0; 1; 2; }); }'
|
||||
assert 1 'int main() { ({ 0; return 1; 2; }); return 3; }'
|
||||
assert 3 'int main() { return ({ int x=3; x; }); }'
|
||||
|
||||
echo OK
|
||||
|
|
Loading…
Reference in New Issue