summaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-02-07 19:24:25 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-02-07 19:24:25 -0500
commitb40db0bcddda8472f3d4f5fbf7d86a4efb77a6a4 (patch)
tree2d0237797d613b1fd1e964a72e4a9b9a1aee4be4 /types.c
parent26dea17ba28448c1562fe75d183dd9fc2244abc6 (diff)
allow namespace access with nms[string]
Diffstat (limited to 'types.c')
-rw-r--r--types.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/types.c b/types.c
index 4483d2e..ede7275 100644
--- a/types.c
+++ b/types.c
@@ -2009,6 +2009,12 @@ static bool types_expr(Typer *tr, Expression *e) {
err_print(e->where, "The index of an array must be a builtin numerical type.");
return false;
}
+ if (lhs_type->kind == TYPE_PTR) {
+ if (lhs_type->ptr->kind == TYPE_STRUCT
+ || type_is_builtin(lhs_type->ptr, BUILTIN_NMS)) {
+ lhs_type = lhs_type->ptr;
+ }
+ }
switch (lhs_type->kind) {
case TYPE_ARR:
*t = *lhs_type->arr.of;
@@ -2016,10 +2022,6 @@ static bool types_expr(Typer *tr, Expression *e) {
case TYPE_SLICE:
*t = *lhs_type->slice;
break;
- case TYPE_PTR:
- lhs_type = lhs_type->ptr;
- if (lhs_type->kind != TYPE_STRUCT) break;
- /* fallthrough */
case TYPE_STRUCT: {
/* allow accessing struct members with a string */
if (!type_is_slicechar(rhs_type)) {
@@ -2050,12 +2052,37 @@ static bool types_expr(Typer *tr, Expression *e) {
return false;
}
} break;
+ case TYPE_BUILTIN:
+ if (lhs_type->builtin == BUILTIN_NMS) {
+ if (!type_is_slicechar(rhs_type))
+ break;
+ }
+ /* fallthrough */
default: {
- char *s = type_to_str(lhs_type);
- err_print(e->where, "Trying to take index of non-array type %s.", s);
- free(s);
- return false;
- }
+ /* allow accessing namespace members with a string */
+ if (!type_is_slicechar(rhs_type)) {
+ char *s = type_to_str(rhs_type);
+ err_print(e->where, "Expected a string for namsepace member access with [], but got type %s.", s);
+ return false;
+ }
+
+ Value nms_val;
+ if (!eval_expr(tr->evalr, lhs, &nms_val))
+ return false;
+ Namespace *nms = nms_val.nms;
+ lhs->kind = EXPR_VAL;
+ lhs->val.nms = nms;
+
+ Value member_name;
+ if (!eval_expr(tr->evalr, rhs, &member_name)) return false;
+ e->binary.op = BINARY_DOT;
+ e->binary.rhs->kind = EXPR_IDENT;
+ Identifier ident = e->binary.rhs->ident = e->binary.dot.translated_ident =
+ ident_get_with_len(&nms->body.idents, member_name.slice.data, (size_t)member_name.slice.n);
+ if (!type_of_ident(tr, rhs->where, &ident, t)) {
+ return false;
+ }
+ } break;
}
break;
case BINARY_DOT: {