harec

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

commit f9dbf4981add935413649f0b8e77c7edd189648a
parent 9823d8cae6542d9ff805c089395ba19511537f10
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Fri,  3 Sep 2021 22:13:01 +0000

ast: simplify embedded struct literals

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Minclude/ast.h | 12+++---------
Msrc/check.c | 47+++++++++++++++++------------------------------
Msrc/parse.c | 27+++++++++++----------------
3 files changed, 31 insertions(+), 55 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -300,15 +300,9 @@ struct ast_expression_switch { struct ast_expression_struct; struct ast_field_value { - bool is_embedded; - union { - struct { - char *name; - struct ast_type *type; - struct ast_expression *initializer; - } field; - struct ast_expression *embedded; - }; + char *name; + struct ast_type *type; + struct ast_expression *initializer; struct ast_field_value *next; }; diff --git a/src/check.c b/src/check.c @@ -2249,27 +2249,23 @@ check_expr_struct(struct context *ctx, struct ast_field_value *afield = aexpr->_struct.fields; while (afield) { - assert(!afield->is_embedded); // TODO - const struct type *ftype; if (!stype) { - tfield->name = afield->field.name; - tfield->type = afield->field.type; + assert(afield->name); // TODO + if (!afield->type) { + error(ctx, aexpr->loc, expr, + "Unnamed struct must specify field type"); + return; + } + tfield->name = afield->name; + tfield->type = afield->type; ftype = type_store_lookup_atype( ctx->store, tfield->type); } else { - if (!afield->field.name) { - error(ctx, afield->field.initializer->loc, - expr, - "Anonymous fields are not permitted for named struct type"); - return; - // XXX: ^ Is that correct? - } sexpr->field = type_get_field(type_dealias(stype), - afield->field.name); + afield->name); if (!sexpr->field) { - error(ctx, afield->field.initializer->loc, - expr, + error(ctx, afield->initializer->loc, expr, "No field by this name exists for this type"); return; } @@ -2277,12 +2273,11 @@ check_expr_struct(struct context *ctx, } sexpr->value = xcalloc(1, sizeof(struct expression)); - check_expression(ctx, afield->field.initializer, sexpr->value, ftype); + check_expression(ctx, afield->initializer, sexpr->value, ftype); if (stype) { if (!type_is_assignable(sexpr->field->type, sexpr->value->result)) { - error(ctx, afield->field.initializer->loc, - expr, + error(ctx, afield->initializer->loc, expr, "Initializer is not assignable to struct field"); return; } @@ -3182,19 +3177,11 @@ expr_is_specified(struct context *ctx, const struct ast_expression *aexpr) case EXPR_STRUCT: for (struct ast_field_value *field = aexpr->_struct.fields; field; field = field->next) { - if (field->is_embedded) { - if (!expr_is_specified(ctx, field->embedded)) { - return false; - } - } else { - if (!type_is_specified(ctx, - field->field.type)) { - return false; - } - if (!expr_is_specified(ctx, - field->field.initializer)) { - return false; - } + if (field->type && !type_is_specified(ctx, field->type)) { + return false; + } + if (!expr_is_specified(ctx, field->initializer)) { + return false; } } if (aexpr->_struct.type.name) { diff --git a/src/parse.c b/src/parse.c @@ -876,47 +876,42 @@ parse_field_value(struct lexer *lexer) xcalloc(sizeof(struct ast_field_value), 1); char *name; struct token tok = {0}; + struct identifier ident = {0}; + struct identifier *i; switch (lex(lexer, &tok)) { case T_NAME: name = tok.name; switch (lex(lexer, &tok)) { case T_COLON: - exp->is_embedded = false; - exp->field.name = name; - exp->field.type = parse_type(lexer); + exp->name = name; + exp->type = parse_type(lexer); want(lexer, T_EQUAL, NULL); - exp->field.initializer = parse_expression(lexer); + exp->initializer = parse_expression(lexer); break; case T_EQUAL: - exp->is_embedded = false; - exp->field.name = name; - exp->field.initializer = parse_expression(lexer); + exp->name = name; + exp->initializer = parse_expression(lexer); break; case T_DOUBLE_COLON: - exp->is_embedded = true; - struct identifier ident = {0}; - struct identifier *i = &ident; + i = &ident; parse_identifier(lexer, i, false); while (i->ns != NULL) { i = i->ns; } i->ns = xcalloc(sizeof(struct identifier), 1); i->ns->name = name; - exp->embedded = parse_struct_literal(lexer, ident); + exp->initializer = parse_struct_literal(lexer, ident); break; default: unlex(lexer, &tok); - exp->is_embedded = true; ident.name = name; ident.ns = NULL; - exp->embedded = parse_struct_literal(lexer, ident); + exp->initializer = parse_struct_literal(lexer, ident); break; } break; case T_STRUCT: - exp->is_embedded = true; - struct identifier id = {0}; - exp->embedded = parse_struct_literal(lexer, id); + exp->initializer = parse_struct_literal(lexer, ident); break; default: assert(0);