aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-01-31 14:36:30 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-01-31 14:36:30 -0500
commit0d8d109eaf56aaea4b8826c344056ee4dc801709 (patch)
tree9f25e06087d131bcf8f4c3795991a78aad3313cc
parentb783a218bb6663aea5786641c65bbbcba13616c3 (diff)
Bugfix for typechecking failure on table indexing, also improved codegen
for updates on tables
-rw-r--r--compile.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/compile.c b/compile.c
index 3fb6d3d2..63f5f2bc 100644
--- a/compile.c
+++ b/compile.c
@@ -370,17 +370,15 @@ static CORD compile_lvalue(env_t *env, ast_t *ast)
compile_to_pointer_depth(env, index->indexed, 1, false), ", ",
compile_type(table_type->key_type), ", ",
compile_type(value_type), ", ",
- compile(env, index->index), ", ",
+ compile_to_type(env, index->index, table_type->key_type), ", ",
compile(env, table_type->default_value), ", ",
compile_type_info(env, container_t), ")");
}
- type_t *key_type = Match(container_t, TableType)->key_type;
- type_t *value_type = Match(container_t, TableType)->value_type;
if (index->unchecked)
code_err(ast, "Table indexes cannot be unchecked");
- return CORD_all("*(", compile_type(Type(PointerType, value_type)), ")Table$reserve(",
+ return CORD_all("*(", compile_type(Type(PointerType, table_type->value_type)), ")Table$reserve(",
compile_to_pointer_depth(env, index->indexed, 1, false), ", ",
- compile_to_type(env, index->index, Type(PointerType, key_type, .is_stack=true)), ", NULL,",
+ compile_to_type(env, index->index, Type(PointerType, table_type->key_type, .is_stack=true)), ", NULL,",
compile_type_info(env, container_t), ")");
} else {
code_err(ast, "I don't know how to assign to this target");
@@ -757,15 +755,22 @@ CORD compile_statement(env_t *env, ast_t *ast)
.op=update->op, .rhs=update->rhs)), "; }");
}
+ type_t *lhs_t = get_type(env, update->lhs);
CORD lhs = compile_lvalue(env, update->lhs);
-
- CORD method_call = compile_math_method(env, update->op, update->lhs, update->rhs, get_type(env, update->lhs));
- if (method_call)
- return CORD_all(lhs, " = ", method_call, ";");
+
+ if (update->lhs->tag == Index && value_type(get_type(env, Match(update->lhs, Index)->indexed))->tag == TableType) {
+ ast_t *lhs_placeholder = WrapAST(update->lhs, InlineCCode, .code="(*lhs)", .type=lhs_t);
+ CORD method_call = compile_math_method(env, update->op, lhs_placeholder, update->rhs, lhs_t);
+ if (method_call)
+ return CORD_all("{ ", compile_declaration(Type(PointerType, .pointed=lhs_t), "lhs"), " = &", lhs, "; *lhs = ", method_call, "; }");
+ } else {
+ CORD method_call = compile_math_method(env, update->op, update->lhs, update->rhs, lhs_t);
+ if (method_call)
+ return CORD_all(lhs, " = ", method_call, ";");
+ }
CORD rhs = compile(env, update->rhs);
- type_t *lhs_t = get_type(env, update->lhs);
type_t *rhs_t = get_type(env, update->rhs);
if (update->rhs->tag == Int && is_numeric_type(non_optional(lhs_t))) {
rhs = compile_int_to_type(env, update->rhs, lhs_t);