commit a02d0da4f9ed04682a9b6792c2830d30a6e086ac
parent da66525c524b3f07c735c9472d40ebca725e9492
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 21 Dec 2020 16:31:51 -0500
parse: handle binding lists
Diffstat:
5 files changed, 87 insertions(+), 5 deletions(-)
diff --git a/include/ast.h b/include/ast.h
@@ -88,6 +88,13 @@ struct ast_expression_access {
struct identifier ident;
};
+struct ast_expression_binding {
+ char *name;
+ struct ast_type *type;
+ struct ast_expression *initializer;
+ struct ast_expression_binding *next;
+};
+
struct ast_expression_constant {
enum type_storage storage;
union {
@@ -114,6 +121,7 @@ struct ast_expression {
enum expr_type type;
union {
struct ast_expression_access access;
+ struct ast_expression_binding binding;
struct ast_expression_constant constant;
struct ast_expression_list list;
struct ast_return_expression _return;
diff --git a/include/expr.h b/include/expr.h
@@ -12,7 +12,7 @@ enum expr_type {
EXPR_ASSERT,
EXPR_ASSIGN,
EXPR_BINARITHM,
- EXPR_BINDING_LIST,
+ EXPR_BINDING,
EXPR_BREAK,
EXPR_CALL,
EXPR_CAST,
diff --git a/src/check.c b/src/check.c
@@ -164,7 +164,7 @@ check_expression(struct context *ctx,
case EXPR_ASSERT:
case EXPR_ASSIGN:
case EXPR_BINARITHM:
- case EXPR_BINDING_LIST:
+ case EXPR_BINDING:
case EXPR_BREAK:
case EXPR_CALL:
case EXPR_CAST:
diff --git a/src/gen.c b/src/gen.c
@@ -203,7 +203,7 @@ gen_expression(struct gen_context *ctx,
case EXPR_ASSERT:
case EXPR_ASSIGN:
case EXPR_BINARITHM:
- case EXPR_BINDING_LIST:
+ case EXPR_BINDING:
case EXPR_BREAK:
case EXPR_CALL:
case EXPR_CAST:
diff --git a/src/parse.c b/src/parse.c
@@ -334,6 +334,9 @@ parse_type(struct parser *par, struct ast_type *type)
type_storage_unparse(type->storage));
}
+static void parse_complex_expression(struct parser *par,
+ struct ast_expression *exp);
+
static void
parse_access(struct parser *par, struct ast_expression *exp)
{
@@ -344,6 +347,64 @@ parse_access(struct parser *par, struct ast_expression *exp)
}
static void
+parse_binding_list(struct parser *par, struct ast_expression *exp)
+{
+ trenter(TR_PARSE, "binding-list");
+ exp->type = EXPR_BINDING;
+ unsigned int flags = 0;
+
+ struct token tok;
+ switch (lex(par->lex, &tok)) {
+ case T_CONST:
+ flags = TYPE_CONST;
+ // fallthrough
+ case T_LET:
+ // no-op
+ break;
+ default:
+ synassert(false, &tok, T_LET, T_CONST, T_EOF);
+ }
+
+ struct ast_expression_binding *binding = &exp->binding;
+ struct ast_expression_binding **next = &exp->binding.next;
+
+ bool more = true;
+ while (more) {
+ want(par, T_NAME, &tok);
+ binding->name = tok.name;
+ binding->initializer = calloc(1, sizeof(struct ast_expression));
+
+ switch (lex(par->lex, &tok)) {
+ case T_COLON:
+ binding->type = calloc(1, sizeof(struct ast_type));
+ parse_type(par, binding->type);
+ binding->type->flags |= flags;
+ want(par, T_EQUAL, &tok);
+ parse_complex_expression(par, binding->initializer);
+ break;
+ case T_EQUAL:
+ break;
+ default:
+ synassert(false, &tok, T_COLON, T_COMMA, T_EOF);
+ }
+
+ switch (lex(par->lex, &tok)) {
+ case T_COMMA:
+ *next = calloc(1, sizeof(struct ast_expression_binding));
+ binding = *next;
+ next = &binding->next;
+ break;
+ default:
+ unlex(par->lex, &tok);
+ more = false;
+ break;
+ }
+ }
+
+ trleave(TR_PARSE, NULL);
+}
+
+static void
parse_constant(struct parser *par, struct ast_expression *exp)
{
trenter(TR_PARSE, "constant");
@@ -432,9 +493,22 @@ parse_complex_expression(struct parser *par, struct ast_expression *exp)
static void
parse_scope_expression(struct parser *par, struct ast_expression *exp)
{
- // TODO: other scope expressions
trenter(TR_PARSE, "scope-expression");
- parse_complex_expression(par, exp);
+
+ struct token tok;
+ switch (lex(par->lex, &tok)) {
+ case T_LET:
+ case T_CONST:
+ unlex(par->lex, &tok);
+ parse_binding_list(par, exp);
+ break;
+ default:
+ unlex(par->lex, &tok);
+ parse_complex_expression(par, exp);
+ break;
+ // TODO: allocations, assignments
+ }
+
trleave(TR_PARSE, NULL);
}