From bb354d6d3626cdc0c2a1b802a954df244cd1facc Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 22 Nov 2025 19:11:55 -0500 Subject: Fixes for conditional expressions for optional types --- src/compile/expressions.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/compile/expressions.c') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 108bda80..130a267c 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -66,7 +66,9 @@ Text_t compile_empty(type_t *t) { Text_t compile(env_t *env, ast_t *ast) { switch (ast->tag) { case None: { - code_err(ast, "I can't figure out what this `none`'s type is!"); + type_t *type = Match(ast, None)->type; + if (type == NULL) code_err(ast, "I can't figure out what this `none`'s type is!"); + return compile_none(non_optional(type)); } case Bool: return Match(ast, Bool)->b ? Text("yes") : Text("no"); case Var: { -- cgit v1.2.3 From a21f9ddfd05c643049c22bb52ab3a60f41933492 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 26 Nov 2025 21:04:12 -0500 Subject: Bugfix for accidental violation of immutable value guarantees due to inner field members --- src/compile/expressions.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'src/compile/expressions.c') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 130a267c..a69a7d56 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -11,11 +11,39 @@ public Text_t compile_maybe_incref(env_t *env, ast_t *ast, type_t *t) { - if (is_idempotent(ast) && can_be_mutated(env, ast)) { - type_t *actual = get_type(with_enum_scope(env, t), ast); - if (t->tag == ListType && type_eq(t, actual)) return Texts("LIST_COPY(", compile_to_type(env, ast, t), ")"); - else if (t->tag == TableType && type_eq(t, actual)) - return Texts("TABLE_COPY(", compile_to_type(env, ast, t), ")"); + if (!has_refcounts(t) || !can_be_mutated(env, ast)) { + return compile_to_type(env, ast, t); + } + + // When using a struct as a value, we need to increment the refcounts of the inner fields as well: + if (t->tag == StructType) { + // If the struct is non-idempotent, we have to stash it in a local var first + if (is_idempotent(ast)) { + Text_t code = Texts("((", compile_type(t), "){"); + for (arg_t *field = Match(t, StructType)->fields; field; field = field->next) { + Text_t val = compile_maybe_incref(env, WrapAST(ast, FieldAccess, .fielded = ast, .field = field->name), + get_arg_type(env, field)); + code = Texts(code, val); + if (field->next) code = Texts(code, ", "); + } + return Texts(code, "})"); + } else { + Text_t code = Texts("({ ", compile_declaration(t, Text("_tmp")), " = ", compile_to_type(env, ast, t), "; ", + "((", compile_type(t), "){"); + ast_t *tmp = WrapAST(ast, InlineCCode, + .chunks = new (ast_list_t, .ast = WrapAST(ast, TextLiteral, Text("_tmp"))), .type = t); + for (arg_t *field = Match(t, StructType)->fields; field; field = field->next) { + Text_t val = compile_maybe_incref(env, WrapAST(ast, FieldAccess, .fielded = tmp, .field = field->name), + get_arg_type(env, field)); + code = Texts(code, val); + if (field->next) code = Texts(code, ", "); + } + return Texts(code, "}); })"); + } + } else if (t->tag == ListType && ast->tag != List && can_be_mutated(env, ast) && type_eq(get_type(env, ast), t)) { + return Texts("LIST_COPY(", compile_to_type(env, ast, t), ")"); + } else if (t->tag == TableType && ast->tag != Table && can_be_mutated(env, ast) && type_eq(get_type(env, ast), t)) { + return Texts("TABLE_COPY(", compile_to_type(env, ast, t), ")"); } return compile_to_type(env, ast, t); } -- cgit v1.2.3 From 3ad07260f369dc285e5ae856b78a58c3b13ee622 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 26 Nov 2025 21:12:11 -0500 Subject: Close loophole in `when` statements that allowed mutating inner field members --- src/compile/expressions.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/compile/expressions.c') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index a69a7d56..19e0672e 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -30,8 +30,7 @@ Text_t compile_maybe_incref(env_t *env, ast_t *ast, type_t *t) { } else { Text_t code = Texts("({ ", compile_declaration(t, Text("_tmp")), " = ", compile_to_type(env, ast, t), "; ", "((", compile_type(t), "){"); - ast_t *tmp = WrapAST(ast, InlineCCode, - .chunks = new (ast_list_t, .ast = WrapAST(ast, TextLiteral, Text("_tmp"))), .type = t); + ast_t *tmp = WrapLiteralCode(ast, Text("_tmp"), .type = t); for (arg_t *field = Match(t, StructType)->fields; field; field = field->next) { Text_t val = compile_maybe_incref(env, WrapAST(ast, FieldAccess, .fielded = tmp, .field = field->name), get_arg_type(env, field)); -- cgit v1.2.3 From 06f5270edfa8231025125909880af27d42e2e52b Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 29 Nov 2025 11:14:14 -0500 Subject: Fix accidental naming collision with _tmp var --- src/compile/expressions.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/compile/expressions.c') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 19e0672e..8b339352 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -28,9 +28,12 @@ Text_t compile_maybe_incref(env_t *env, ast_t *ast, type_t *t) { } return Texts(code, "})"); } else { - Text_t code = Texts("({ ", compile_declaration(t, Text("_tmp")), " = ", compile_to_type(env, ast, t), "; ", + static int64_t tmp_index = 1; + Text_t tmp_name = Texts("_tmp", tmp_index); + tmp_index += 1; + Text_t code = Texts("({ ", compile_declaration(t, tmp_name), " = ", compile_to_type(env, ast, t), "; ", "((", compile_type(t), "){"); - ast_t *tmp = WrapLiteralCode(ast, Text("_tmp"), .type = t); + ast_t *tmp = WrapLiteralCode(ast, tmp_name, .type = t); for (arg_t *field = Match(t, StructType)->fields; field; field = field->next) { Text_t val = compile_maybe_incref(env, WrapAST(ast, FieldAccess, .fielded = tmp, .field = field->name), get_arg_type(env, field)); -- cgit v1.2.3 From 544b1fb6a70d55bf368b827136cf0f37a26e8288 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 7 Dec 2025 21:42:45 -0500 Subject: Change Paths to be an enum of their different types. --- src/compile/expressions.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/compile/expressions.c') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 8b339352..c3918de3 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -57,7 +57,6 @@ Text_t compile_empty(type_t *t) { if (t->tag == OptionalType) return compile_none(t); if (t == PATH_TYPE) return Text("NONE_PATH"); - else if (t == PATH_TYPE_TYPE) return Text("PATHTYPE_ABSOLUTE"); switch (t->tag) { case BigIntType: return Text("I(0)"); -- cgit v1.2.3