commit 1696ab0af0305d71ce23bac0b6a2b8a0b4404b3c
parent 7a4cff9e909810d7f69928dd1089c5f6a9c49789
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 26 Dec 2020 09:14:00 -0500
parse: implement array literals
Diffstat:
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: