harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 1696ab0af0305d71ce23bac0b6a2b8a0b4404b3c
parent 7a4cff9e909810d7f69928dd1089c5f6a9c49789
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 26 Dec 2020 09:14:00 -0500

parse: implement array literals

Diffstat:
Minclude/ast.h | 7+++++++
Msrc/parse.c | 52+++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/include/ast.h b/include/ast.h @@ -132,6 +132,12 @@ struct ast_expression_call { struct ast_call_argument *args; }; +struct ast_array_constant { + struct ast_expression *value; + struct ast_array_constant *next; + bool expand; +}; + struct ast_expression_constant { enum type_storage storage; union { @@ -143,6 +149,7 @@ struct ast_expression_constant { size_t len; char *value; } string; + struct ast_array_constant *array; }; }; diff --git a/src/parse.c b/src/parse.c @@ -677,6 +677,55 @@ parse_constant(struct parser *par) } static struct ast_expression * +parse_array_literal(struct parser *par) +{ + trenter(TR_PARSE, "array-literal"); + + struct token tok; + want(par, T_LBRACKET, &tok); + + struct ast_expression *exp = xcalloc(1, sizeof(struct ast_expression)); + exp->type = EXPR_CONSTANT; + exp->constant.storage = TYPE_STORAGE_ARRAY; + + struct ast_array_constant *item, **next = &exp->constant.array; + + while (lex(par->lex, &tok) != T_RBRACKET) { + unlex(par->lex, &tok); + + item = *next = xcalloc(1, sizeof(struct ast_expression)); + item->value = parse_simple_expression(par); + next = &item->next; + + switch (lex(par->lex, &tok)) { + case T_ELLIPSIS: + item->expand = true; + lex(par->lex, &tok); + if (tok.token == T_COMMA) { + want(par, T_RBRACKET, &tok); + unlex(par->lex, &tok); + } else if (tok.token == T_RBRACKET) { + unlex(par->lex, &tok); + } else { + synassert(false, &tok, T_COMMA, T_RBRACKET, T_EOF); + } + break; + case T_COMMA: + // Move on + break; + case T_RBRACKET: + unlex(par->lex, &tok); + break; + default: + synassert(false, &tok, T_ELLIPSIS, T_COMMA, T_RBRACKET, T_EOF); + } + } + + trleave(TR_PARSE, NULL); + return exp; +} + +static struct ast_expression * parse_plain_expression(struct parser *par) { trace(TR_PARSE, "plain"); @@ -694,7 +743,8 @@ parse_plain_expression(struct parser *par) unlex(par->lex, &tok); return parse_access(par); case T_LBRACKET: - assert(0); // TODO: Array literal + unlex(par->lex, &tok); + return parse_array_literal(par); case T_STRUCT: assert(0); // TODO: Struct literal default: