harec

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

commit a02d0da4f9ed04682a9b6792c2830d30a6e086ac
parent da66525c524b3f07c735c9472d40ebca725e9492
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 21 Dec 2020 16:31:51 -0500

parse: handle binding lists

Diffstat:
Minclude/ast.h | 8++++++++
Minclude/expr.h | 2+-
Msrc/check.c | 2+-
Msrc/gen.c | 2+-
Msrc/parse.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
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); }