harec

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

commit b74b70a610d9f6b226dac14cabf945cd84ef3290
parent ea6d4c92cd331f1177eaea69e41d3d91a116b130
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 26 Dec 2020 13:47:37 -0500

check: implement index access

Diffstat:
Minclude/ast.h | 2+-
Minclude/expr.h | 10++++++++--
Msrc/check.c | 40+++++++++++++++++++++++++++++-----------
Msrc/parse.c | 2+-
4 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -102,7 +102,7 @@ struct ast_expression_access { union { struct identifier ident; struct { - struct ast_expression *object; + struct ast_expression *array; struct ast_expression *index; }; // TODO: Field selection diff --git a/include/expr.h b/include/expr.h @@ -38,9 +38,15 @@ enum access_type { }; struct expression_access { - const struct scope_object *object; enum access_type type; - // TODO: Details for index, field selection + union { + const struct scope_object *object; + struct { + struct expression *array; + struct expression *index; + }; + // TODO: Field selection + }; }; struct expression_assign { diff --git a/src/check.c b/src/check.c @@ -41,18 +41,36 @@ check_expr_access(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr) { - char buf[1024]; - identifier_unparse_static(&aexpr->access.ident, buf, sizeof(buf)); - - trace(TR_CHECK, "access %s", buf); + trace(TR_CHECK, "access"); expr->type = EXPR_ACCESS; - - const struct scope_object *obj = scope_lookup( - ctx->scope, &aexpr->access.ident); - expect(obj, "Unknown object %s", buf); - - expr->result = obj->type; - expr->access.object = obj; + expr->access.type = aexpr->access.type; + + const struct scope_object *obj; + switch (expr->access.type) { + case ACCESS_IDENTIFIER: + obj = scope_lookup(ctx->scope, &aexpr->access.ident); + char buf[1024]; + identifier_unparse_static(&aexpr->access.ident, buf, sizeof(buf)); + expect(obj, "Unknown object", buf); + expr->result = obj->type; + expr->access.object = obj; + break; + case ACCESS_INDEX: + expr->access.array = xcalloc(1, sizeof(struct expression)); + expr->access.index = xcalloc(1, sizeof(struct expression)); + check_expression(ctx, aexpr->access.array, expr->access.array); + check_expression(ctx, aexpr->access.index, expr->access.index); + const struct type *atype = expr->access.array->result; + const struct type *itype = expr->access.index->result; + expect(atype->storage == TYPE_STORAGE_ARRAY + || atype->storage == TYPE_STORAGE_SLICE, + "Cannot index non-array, non-slice object"); + expect(type_is_integer(itype), "Cannot use non-integer type as slice/array index"); + expr->result = atype->array.members; + break; + case ACCESS_FIELD: + assert(0); // TODO + } } static void diff --git a/src/parse.c b/src/parse.c @@ -876,7 +876,7 @@ parse_index_slice_expression(struct parser *par, struct ast_expression *lvalue) if (!is_slice) { exp->type = EXPR_ACCESS; exp->access.type = ACCESS_INDEX; - exp->access.object = lvalue; + exp->access.array = lvalue; exp->access.index = start; trleave(TR_PARSE, "slice-index (index)"); return exp;