From d25d5642392f93623d1eb4d11156d293fe6df546 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 26 Aug 2025 14:39:11 -0400 Subject: Formatting for min/max and cleanup for ints/nums --- src/compile/expressions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/compile') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 2320474a..58288c50 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -152,7 +152,7 @@ Text_t compile(env_t *env, ast_t *ast) { ast_t *key = ast->tag == Min ? Match(ast, Min)->key : Match(ast, Max)->key; ast_t *lhs = ast->tag == Min ? Match(ast, Min)->lhs : Match(ast, Max)->lhs; ast_t *rhs = ast->tag == Min ? Match(ast, Min)->rhs : Match(ast, Max)->rhs; - const char *key_name = "$"; + const char *key_name = ast->tag == Min ? "_min_" : "_max_"; if (key == NULL) key = FakeAST(Var, key_name); env_t *expr_env = fresh_scope(env); -- cgit v1.2.3 From cb1d36c6d8bc84f3422c71ab3eb29606e80f7837 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 26 Aug 2025 14:58:51 -0400 Subject: Formatting for reductions --- src/compile/comparisons.c | 14 +++++++++++++- src/compile/reductions.c | 7 ++++--- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src/compile') diff --git a/src/compile/comparisons.c b/src/compile/comparisons.c index d73664de..d7531261 100644 --- a/src/compile/comparisons.c +++ b/src/compile/comparisons.c @@ -7,6 +7,18 @@ #include "../typecheck.h" #include "compilation.h" +static CONSTFUNC const char *comparison_operator(ast_e tag) { + switch (tag) { + case Equals: return "=="; + case NotEquals: return "!="; + case LessThan: return "<"; + case LessThanOrEquals: return "<="; + case GreaterThan: return ">"; + case GreaterThanOrEquals: return ">="; + default: return NULL; + } +} + Text_t compile_comparison(env_t *env, ast_t *ast) { switch (ast->tag) { @@ -75,7 +87,7 @@ Text_t compile_comparison(env_t *env, ast_t *ast) { if (ast->tag == Compare) return Texts("generic_compare(stack(", lhs, "), stack(", rhs, "), ", compile_type_info(operand_t), ")"); - const char *op = binop_operator(ast->tag); + const char *op = comparison_operator(ast->tag); switch (operand_t->tag) { case BigIntType: return Texts("(Int$compare_value(", lhs, ", ", rhs, ") ", op, " 0)"); case BoolType: diff --git a/src/compile/reductions.c b/src/compile/reductions.c index e0477a9c..1652384c 100644 --- a/src/compile/reductions.c +++ b/src/compile/reductions.c @@ -12,6 +12,7 @@ public Text_t compile_reduction(env_t *env, ast_t *ast) { DeclareMatch(reduction, ast, Reduction); ast_e op = reduction->op; + const char *op_str = binop_operator(op); type_t *iter_t = get_type(env, reduction->iter); type_t *item_t = get_iterated_type(iter_t); @@ -29,7 +30,7 @@ Text_t compile_reduction(env_t *env, ast_t *ast) { type_t *item_value_type = item_t; ast_t *item_value = item; if (reduction->key) { - set_binding(body_scope, "$", item_t, compile(body_scope, item)); + set_binding(body_scope, op_str, item_t, compile(body_scope, item)); item_value = reduction->key; item_value_type = get_type(body_scope, reduction->key); } @@ -67,7 +68,7 @@ Text_t compile_reduction(env_t *env, ast_t *ast) { ast_e cmp_op = op == Min ? LessThan : GreaterThan; if (reduction->key) { env_t *key_scope = fresh_scope(env); - set_binding(key_scope, "$", item_t, item_code); + set_binding(key_scope, op_str, item_t, item_code); type_t *key_type = get_type(key_scope, reduction->key); Text_t superlative_key = op == Min ? Text("min_key") : Text("max_key"); code = Texts(code, compile_declaration(key_type, superlative_key), ";\n"); @@ -111,7 +112,7 @@ Text_t compile_reduction(env_t *env, ast_t *ast) { type_t *reduction_type = Match(get_type(env, ast), OptionalType)->type; ast_t *item_value = item; if (reduction->key) { - set_binding(body_scope, "$", item_t, compile(body_scope, item)); + set_binding(body_scope, op_str, item_t, compile(body_scope, item)); item_value = reduction->key; } -- cgit v1.2.3 From 43105107b9d1e985e9c182b904f2ac79b17fb460 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 29 Aug 2025 13:32:17 -0400 Subject: Improvements to text and inline C code formatting/parsing --- src/compile/expressions.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/compile') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 58288c50..544b7723 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -237,7 +237,8 @@ Text_t compile(env_t *env, ast_t *ast) { case Index: return compile_indexing(env, ast); case InlineCCode: { type_t *t = get_type(env, ast); - if (t->tag == VoidType) return Texts("{\n", compile_statement(env, ast), "\n}"); + if (Match(ast, InlineCCode)->type_ast != NULL) return Texts("({", compile_statement(env, ast), "; })"); + else if (t->tag == VoidType) return Texts("{\n", compile_statement(env, ast), "\n}"); else return compile_statement(env, ast); } case Use: code_err(ast, "Compiling 'use' as expression!"); -- cgit v1.2.3 From ee020c72d92c3807fa4afcd1e170d3df81688b97 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 13:17:43 -0400 Subject: Switch to using Texts(x) instead of Texts(String(x)) when possible --- src/compile/assertions.c | 35 +++++++++++++++++------------------ src/compile/assignments.c | 7 +++---- src/compile/conditionals.c | 2 +- src/compile/doctests.c | 17 ++++++++--------- src/compile/enums.c | 20 ++++++++++---------- src/compile/files.c | 4 ++-- src/compile/functions.c | 24 +++++++++++------------- src/compile/indexing.c | 4 ++-- src/compile/lists.c | 2 +- src/compile/loops.c | 4 ++-- src/compile/optionals.c | 11 +++++------ src/compile/promotions.c | 12 ++++++------ src/compile/sets.c | 2 +- src/compile/statements.c | 4 ++-- src/compile/structs.c | 9 ++++----- src/compile/tables.c | 2 +- src/compile/types.c | 4 ++-- 17 files changed, 78 insertions(+), 85 deletions(-) (limited to 'src/compile') diff --git a/src/compile/assertions.c b/src/compile/assertions.c index ce9abcbc..0f1d27b6 100644 --- a/src/compile/assertions.c +++ b/src/compile/assertions.c @@ -53,27 +53,26 @@ Text_t compile_assertion(env_t *env, ast_t *ast) { ast_t *var_comparison = new (ast_t, .file = expr->file, .start = expr->start, .end = expr->end, .tag = expr->tag, .__data.Equals = {.lhs = lhs_var, .rhs = rhs_var}); int64_t line = get_line_number(ast->file, ast->start); - return Texts("{ // assertion\n", compile_declaration(operand_t, Text("_lhs")), " = ", - compile_to_type(env, cmp.lhs, operand_t), ";\n", "\n#line ", String(line), "\n", - compile_declaration(operand_t, Text("_rhs")), " = ", compile_to_type(env, cmp.rhs, operand_t), - ";\n", "\n#line ", String(line), "\n", "if (!(", compile_condition(env, var_comparison), "))\n", - "#line ", String(line), "\n", - Texts("fail_source(", quoted_str(ast->file->filename), ", ", - String((int64_t)(expr->start - expr->file->text)), ", ", - String((int64_t)(expr->end - expr->file->text)), ", ", - message ? Texts("Text$as_c_string(", compile_to_type(env, message, Type(TextType)), ")") - : Text("\"This assertion failed!\""), - ", ", "\" (\", ", expr_as_text(Text("_lhs"), operand_t, Text("no")), - ", " - "\" ", - failure, " \", ", expr_as_text(Text("_rhs"), operand_t, Text("no")), ", \")\");\n"), - "}\n"); + return Texts( + "{ // assertion\n", compile_declaration(operand_t, Text("_lhs")), " = ", + compile_to_type(env, cmp.lhs, operand_t), ";\n", "\n#line ", line, "\n", + compile_declaration(operand_t, Text("_rhs")), " = ", compile_to_type(env, cmp.rhs, operand_t), ";\n", + "\n#line ", line, "\n", "if (!(", compile_condition(env, var_comparison), "))\n", "#line ", line, "\n", + Texts("fail_source(", quoted_str(ast->file->filename), ", ", (int64_t)(expr->start - expr->file->text), + ", ", (int64_t)(expr->end - expr->file->text), ", ", + message ? Texts("Text$as_c_string(", compile_to_type(env, message, Type(TextType)), ")") + : Text("\"This assertion failed!\""), + ", ", "\" (\", ", expr_as_text(Text("_lhs"), operand_t, Text("no")), + ", " + "\" ", + failure, " \", ", expr_as_text(Text("_rhs"), operand_t, Text("no")), ", \")\");\n"), + "}\n"); } default: { int64_t line = get_line_number(ast->file, ast->start); - return Texts("if (!(", compile_condition(env, expr), "))\n", "#line ", String(line), "\n", "fail_source(", - quoted_str(ast->file->filename), ", ", String((int64_t)(expr->start - expr->file->text)), ", ", - String((int64_t)(expr->end - expr->file->text)), ", ", + return Texts("if (!(", compile_condition(env, expr), "))\n", "#line ", line, "\n", "fail_source(", + quoted_str(ast->file->filename), ", ", (int64_t)(expr->start - expr->file->text), ", ", + (int64_t)(expr->end - expr->file->text), ", ", message ? Texts("Text$as_c_string(", compile_to_type(env, message, Type(TextType)), ")") : Text("\"This assertion failed!\""), ");\n"); diff --git a/src/compile/assignments.c b/src/compile/assignments.c index ab28b972..3cb60fd5 100644 --- a/src/compile/assignments.c +++ b/src/compile/assignments.c @@ -119,12 +119,12 @@ Text_t compile_assignment_statement(env_t *env, ast_t *ast) { "stack memory."); env_t *val_env = with_enum_scope(env, lhs_t); Text_t val = compile_to_type(val_env, value->ast, lhs_t); - code = Texts(code, compile_type(lhs_t), " $", String(i), " = ", val, ";\n"); + code = Texts(code, compile_type(lhs_t), " $", i, " = ", val, ";\n"); i += 1; } i = 1; for (ast_list_t *target = assign->targets; target; target = target->next) { - code = Texts(code, compile_assignment(env, target->ast, Texts("$", String(i))), ";\n"); + code = Texts(code, compile_assignment(env, target->ast, Texts("$", i)), ";\n"); i += 1; } return Texts(code, "\n}"); @@ -171,8 +171,7 @@ Text_t compile_lvalue(env_t *env, ast_t *ast) { ")"); } else { return Texts("List_lvalue(", compile_type(item_type), ", ", target_code, ", ", index_code, ", ", - String((int)(ast->start - ast->file->text)), ", ", - String((int)(ast->end - ast->file->text)), ")"); + (int64_t)(ast->start - ast->file->text), ", ", (int64_t)(ast->end - ast->file->text), ")"); } } else if (container_t->tag == TableType) { DeclareMatch(table_type, container_t, TableType); diff --git a/src/compile/conditionals.c b/src/compile/conditionals.c index 23d2a177..f9dfa751 100644 --- a/src/compile/conditionals.c +++ b/src/compile/conditionals.c @@ -59,7 +59,7 @@ Text_t compile_if_statement(env_t *env, ast_t *ast) { code = Texts(code, compile_block(nonnull_scope, if_->body)); if (if_->else_body) { - Text_t label = Texts("_falsey_", String((int64_t)(ast->start - ast->file->text))); + Text_t label = Texts("_falsey_", (int64_t)(ast->start - ast->file->text)); code = Texts(code, "else goto ", label, ";\n" "} else {\n", diff --git a/src/compile/doctests.c b/src/compile/doctests.c index 872684ed..20081ae7 100644 --- a/src/compile/doctests.c +++ b/src/compile/doctests.c @@ -4,7 +4,6 @@ #include "../config.h" #include "../environment.h" #include "../stdlib/datatypes.h" -#include "../stdlib/print.h" #include "../stdlib/text.h" #include "../stdlib/util.h" #include "../typecheck.h" @@ -69,12 +68,12 @@ Text_t compile_doctest(env_t *env, ast_t *ast) { if (target == assign->targets) expr_t = lhs_t; env_t *val_scope = with_enum_scope(env, lhs_t); Text_t val_code = compile_to_type(val_scope, value->ast, lhs_t); - test_code = Texts(test_code, compile_type(lhs_t), " $", String(i), " = ", val_code, ";\n"); + test_code = Texts(test_code, compile_type(lhs_t), " $", i, " = ", val_code, ";\n"); i += 1; } i = 1; for (ast_list_t *target = assign->targets; target; target = target->next) { - test_code = Texts(test_code, compile_assignment(env, target->ast, Texts("$", String(i))), ";\n"); + test_code = Texts(test_code, compile_assignment(env, target->ast, Texts("$", i)), ";\n"); i += 1; } @@ -104,16 +103,16 @@ Text_t compile_doctest(env_t *env, ast_t *ast) { if (test->expected) { return Texts(setup, "test(", compile_type(expr_t), ", ", test_code, ", ", compile_to_type(env, test->expected, expr_t), ", ", compile_type_info(expr_t), ", ", - String((int64_t)(test->expr->start - test->expr->file->text)), ", ", - String((int64_t)(test->expr->end - test->expr->file->text)), ");"); + (int64_t)(test->expr->start - test->expr->file->text), ", ", + (int64_t)(test->expr->end - test->expr->file->text), ");"); } else { if (expr_t->tag == VoidType || expr_t->tag == AbortType) { return Texts(setup, "inspect_void(", test_code, ", ", compile_type_info(expr_t), ", ", - String((int64_t)(test->expr->start - test->expr->file->text)), ", ", - String((int64_t)(test->expr->end - test->expr->file->text)), ");"); + (int64_t)(test->expr->start - test->expr->file->text), ", ", + (int64_t)(test->expr->end - test->expr->file->text), ");"); } return Texts(setup, "inspect(", compile_type(expr_t), ", ", test_code, ", ", compile_type_info(expr_t), ", ", - String((int64_t)(test->expr->start - test->expr->file->text)), ", ", - String((int64_t)(test->expr->end - test->expr->file->text)), ");"); + (int64_t)(test->expr->start - test->expr->file->text), ", ", + (int64_t)(test->expr->end - test->expr->file->text), ");"); } } diff --git a/src/compile/enums.c b/src/compile/enums.c index d9c29f26..f5500831 100644 --- a/src/compile/enums.c +++ b/src/compile/enums.c @@ -30,12 +30,12 @@ Text_t compile_enum_typeinfo(env_t *env, ast_t *ast) { type_t *t = Table$str_get(*env->types, def->name); const char *metamethods = is_packed_data(t) ? "PackedDataEnum$metamethods" : "Enum$metamethods"; Text_t info = namespace_name(env, env->namespace, Texts(def->name, "$$info")); - Text_t typeinfo = Texts("public const TypeInfo_t ", info, " = {", String((int64_t)type_size(t)), "u, ", - String((int64_t)type_align(t)), "u, .metamethods=", metamethods, - ", {.tag=EnumInfo, .EnumInfo={.name=\"", def->name, - "\", " - ".num_tags=", - String((int64_t)num_tags), ", .tags=(NamedType_t[]){"); + Text_t typeinfo = + Texts("public const TypeInfo_t ", info, " = {", (int64_t)type_size(t), "u, ", (int64_t)type_align(t), + "u, .metamethods=", metamethods, ", {.tag=EnumInfo, .EnumInfo={.name=\"", def->name, + "\", " + ".num_tags=", + (int64_t)num_tags, ", .tags=(NamedType_t[]){"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { const char *tag_type_name = String(def->name, "$", tag->name); @@ -144,10 +144,10 @@ Text_t compile_empty_enum(type_t *t) { assert(tag); assert(tag->type); if (Match(tag->type, StructType)->fields) - return Texts("((", compile_type(t), "){.$tag=", String(tag->tag_value), ", .", tag->name, "=", - compile_empty(tag->type), "})"); - else if (enum_has_fields(t)) return Texts("((", compile_type(t), "){.$tag=", String(tag->tag_value), "})"); - else return Texts("((", compile_type(t), ")", String(tag->tag_value), ")"); + return Texts("((", compile_type(t), "){.$tag=", tag->tag_value, ", .", tag->name, "=", compile_empty(tag->type), + "})"); + else if (enum_has_fields(t)) return Texts("((", compile_type(t), "){.$tag=", tag->tag_value, "})"); + else return Texts("((", compile_type(t), ")", tag->tag_value, ")"); } public diff --git a/src/compile/files.c b/src/compile/files.c index 2b0ac4bf..a6af2300 100644 --- a/src/compile/files.c +++ b/src/compile/files.c @@ -103,7 +103,7 @@ static Text_t compile_top_level_code(env_t *env, ast_t *ast) { "types, not ", type_to_str(Match(type, FunctionType)->ret)); Text_t name_code = - namespace_name(env, env->namespace, Texts(name, "$", String(get_line_number(ast->file, ast->start)))); + namespace_name(env, env->namespace, Texts(name, "$", get_line_number(ast->file, ast->start))); return compile_function(env, name_code, ast, &env->code->staticdefs); } case StructDef: { @@ -125,7 +125,7 @@ static Text_t compile_top_level_code(env_t *env, ast_t *ast) { DeclareMatch(def, ast, LangDef); Text_t code = Texts("public const TypeInfo_t ", namespace_name(env, env->namespace, Texts(def->name, "$$info")), " = {", - String((int64_t)sizeof(Text_t)), ", ", String((int64_t)__alignof__(Text_t)), + (int64_t)sizeof(Text_t), ", ", (int64_t)__alignof__(Text_t), ", .metamethods=Text$metamethods, .tag=TextInfo, .TextInfo={", quoted_str(def->name), "}};\n"); env_t *ns_env = namespace_env(env, def->name); return Texts(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : EMPTY_TEXT); diff --git a/src/compile/functions.c b/src/compile/functions.c index 01de26e3..6caefa8b 100644 --- a/src/compile/functions.c +++ b/src/compile/functions.c @@ -32,7 +32,7 @@ Text_t compile_function_declaration(env_t *env, ast_t *ast) { if (ret_t->tag == AbortType) ret_type_code = Texts("__attribute__((noreturn)) _Noreturn ", ret_type_code); Text_t name = namespace_name(env, env->namespace, Text$from_str(decl_name)); if (env->namespace && env->namespace->parent && env->namespace->name && streq(decl_name, env->namespace->name)) - name = namespace_name(env, env->namespace, Text$from_str(String(get_line_number(ast->file, ast->start)))); + name = namespace_name(env, env->namespace, Texts(get_line_number(ast->file, ast->start))); return Texts(ret_type_code, " ", name, arg_signature, ";\n"); } @@ -56,8 +56,7 @@ Text_t compile_convert_declaration(env_t *env, ast_t *ast) { "Conversions are only supported for text, struct, and enum " "types, not ", type_to_str(ret_t)); - Text_t name_code = - namespace_name(env, env->namespace, Texts(name, "$", String(get_line_number(ast->file, ast->start)))); + Text_t name_code = namespace_name(env, env->namespace, Texts(name, "$", get_line_number(ast->file, ast->start))); return Texts(ret_type_code, " ", name_code, arg_signature, ";\n"); } @@ -248,7 +247,7 @@ Text_t compile_function_call(env_t *env, ast_t *ast) { public Text_t compile_lambda(env_t *env, ast_t *ast) { DeclareMatch(lambda, ast, Lambda); - Text_t name = namespace_name(env, env->namespace, Texts("lambda$", String(lambda->id))); + Text_t name = namespace_name(env, env->namespace, Texts("lambda$", lambda->id)); env_t *body_scope = fresh_scope(env); body_scope->deferred = NULL; @@ -736,7 +735,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static // FIXME: this currently just deletes the first entry, but this // should be more like a least-recently-used cache eviction policy // or least-frequently-used - pop_code = Texts("if (cache.entries.length > ", String(cache_size.value), + pop_code = Texts("if (cache.entries.length > ", cache_size.value, ") Table$remove(&cache, cache.entries.data + " "cache.entries.stride*0, table_type);\n"); } @@ -772,14 +771,13 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static int64_t num_fields = used_names.entries.length; const char *metamethods = is_packed_data(t) ? "PackedData$metamethods" : "Struct$metamethods"; - Text_t args_typeinfo = - Texts("((TypeInfo_t[1]){{.size=sizeof(args), " - ".align=__alignof__(args), .metamethods=", - metamethods, - ", .tag=StructInfo, " - ".StructInfo.name=\"FunctionArguments\", " - ".StructInfo.num_fields=", - String(num_fields), ", .StructInfo.fields=(NamedType_t[", String(num_fields), "]){"); + Text_t args_typeinfo = Texts("((TypeInfo_t[1]){{.size=sizeof(args), " + ".align=__alignof__(args), .metamethods=", + metamethods, + ", .tag=StructInfo, " + ".StructInfo.name=\"FunctionArguments\", " + ".StructInfo.num_fields=", + num_fields, ", .StructInfo.fields=(NamedType_t[", num_fields, "]){"); Text_t args_type = Text("struct { "); for (arg_t *f = fields; f; f = f->next) { args_typeinfo = Texts(args_typeinfo, "{\"", f->name, "\", ", compile_type_info(f->type), "}"); diff --git a/src/compile/indexing.c b/src/compile/indexing.c index e99feeb2..39af1160 100644 --- a/src/compile/indexing.c +++ b/src/compile/indexing.c @@ -44,8 +44,8 @@ Text_t compile_indexing(env_t *env, ast_t *ast) { return Texts("List_get_unchecked(", compile_type(item_type), ", ", list, ", ", index_code, ")"); else return Texts("List_get(", compile_type(item_type), ", ", list, ", ", index_code, ", ", - String((int64_t)(indexing->index->start - f->text)), ", ", - String((int64_t)(indexing->index->end - f->text)), ")"); + (int64_t)(indexing->index->start - f->text), ", ", (int64_t)(indexing->index->end - f->text), + ")"); } else if (container_t->tag == TableType) { DeclareMatch(table_type, container_t, TableType); if (indexing->unchecked) code_err(ast, "Table indexes cannot be unchecked"); diff --git a/src/compile/lists.c b/src/compile/lists.c index 5df39863..d9d71278 100644 --- a/src/compile/lists.c +++ b/src/compile/lists.c @@ -33,7 +33,7 @@ Text_t compile_typed_list(env_t *env, ast_t *ast, type_t *list_type) { { env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : env; if (is_incomplete_type(item_type)) code_err(ast, "This list's type can't be inferred!"); - Text_t code = Texts("TypedListN(", compile_type(item_type), ", ", String(n)); + Text_t code = Texts("TypedListN(", compile_type(item_type), ", ", n); for (ast_list_t *item = list->items; item; item = item->next) { code = Texts(code, ", ", compile_to_type(scope, item->ast, item_type)); } diff --git a/src/compile/loops.c b/src/compile/loops.c index c742589a..332024f4 100644 --- a/src/compile/loops.c +++ b/src/compile/loops.c @@ -405,7 +405,7 @@ Text_t compile_skip(env_t *env, ast_t *ast) { if (matched) { if (ctx->skip_label.length == 0) { static int64_t skip_label_count = 1; - ctx->skip_label = Texts("skip_", String(skip_label_count)); + ctx->skip_label = Texts("skip_", skip_label_count); ++skip_label_count; } Text_t code = EMPTY_TEXT; @@ -431,7 +431,7 @@ Text_t compile_stop(env_t *env, ast_t *ast) { if (matched) { if (ctx->stop_label.length == 0) { static int64_t stop_label_count = 1; - ctx->stop_label = Texts("stop_", String(stop_label_count)); + ctx->stop_label = Texts("stop_", stop_label_count); ++stop_label_count; } Text_t code = EMPTY_TEXT; diff --git a/src/compile/optionals.c b/src/compile/optionals.c index b3d94005..cd50b1bf 100644 --- a/src/compile/optionals.c +++ b/src/compile/optionals.c @@ -125,10 +125,9 @@ Text_t compile_non_optional(env_t *env, ast_t *ast) { type_t *t = get_type(env, value); Text_t value_code = compile(env, value); int64_t line = get_line_number(ast->file, ast->start); - return Texts("({ ", compile_declaration(t, Text("opt")), " = ", value_code, "; ", "if unlikely (", - check_none(t, Text("opt")), ")\n", "#line ", String(line), "\n", "fail_source(", - quoted_str(ast->file->filename), ", ", String((int64_t)(value->start - value->file->text)), ", ", - String((int64_t)(value->end - value->file->text)), ", ", - "\"This was expected to be a value, but it's none\");\n", optional_into_nonnone(t, Text("opt")), - "; })"); + return Texts( + "({ ", compile_declaration(t, Text("opt")), " = ", value_code, "; ", "if unlikely (", + check_none(t, Text("opt")), ")\n", "#line ", line, "\n", "fail_source(", quoted_str(ast->file->filename), ", ", + (int64_t)(value->start - value->file->text), ", ", (int64_t)(value->end - value->file->text), ", ", + "\"This was expected to be a value, but it's none\");\n", optional_into_nonnone(t, Text("opt")), "; })"); } diff --git a/src/compile/promotions.c b/src/compile/promotions.c index fcedce3f..6595e5aa 100644 --- a/src/compile/promotions.c +++ b/src/compile/promotions.c @@ -43,12 +43,12 @@ bool promote(env_t *env, ast_t *ast, Text_t *code, type_t *actual, type_t *neede // Automatic optional checking for nums: if (needed->tag == NumType && actual->tag == OptionalType && Match(actual, OptionalType)->type->tag == NumType) { int64_t line = get_line_number(ast->file, ast->start); - *code = Texts("({ ", compile_declaration(actual, Text("opt")), " = ", *code, "; ", "if unlikely (", - check_none(actual, Text("opt")), ")\n", "#line ", String(line), "\n", "fail_source(", - quoted_str(ast->file->filename), ", ", String((int64_t)(ast->start - ast->file->text)), ", ", - String((int64_t)(ast->end - ast->file->text)), ", ", - "\"This was expected to be a value, but it's none\");\n", - optional_into_nonnone(actual, Text("opt")), "; })"); + *code = + Texts("({ ", compile_declaration(actual, Text("opt")), " = ", *code, "; ", "if unlikely (", + check_none(actual, Text("opt")), ")\n", "#line ", line, "\n", "fail_source(", + quoted_str(ast->file->filename), ", ", (int64_t)(ast->start - ast->file->text), ", ", + (int64_t)(ast->end - ast->file->text), ", ", "\"This was expected to be a value, but it's none\");\n", + optional_into_nonnone(actual, Text("opt")), "; })"); return true; } diff --git a/src/compile/sets.c b/src/compile/sets.c index d33677cc..3346a9aa 100644 --- a/src/compile/sets.c +++ b/src/compile/sets.c @@ -25,7 +25,7 @@ Text_t compile_typed_set(env_t *env, ast_t *ast, type_t *set_type) { } { // No comprehension: - Text_t code = Texts("Set(", compile_type(item_type), ", ", compile_type_info(item_type), ", ", String(n)); + Text_t code = Texts("Set(", compile_type(item_type), ", ", compile_type_info(item_type), ", ", n); env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : env; for (ast_list_t *item = set->items; item; item = item->next) { code = Texts(code, ", ", compile_to_type(scope, item->ast, item_type)); diff --git a/src/compile/statements.c b/src/compile/statements.c index 7c58559d..e296795b 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -22,7 +22,7 @@ public Text_t with_source_info(env_t *env, ast_t *ast, Text_t code) { if (code.length == 0 || !ast || !ast->file || !env->do_source_mapping) return code; int64_t line = get_line_number(ast->file, ast->start); - return Texts("\n#line ", String(line), "\n", code); + return Texts("\n#line ", line, "\n", code); } static Text_t _compile_statement(env_t *env, ast_t *ast) { @@ -121,7 +121,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { if (Text$starts_with(entry->b->code, Text("userdata->"), NULL)) { Table$str_set(defer_env->locals, entry->name, entry->b); } else { - Text_t defer_name = Texts("defer$", String(++defer_id), "$", entry->name); + Text_t defer_name = Texts("defer$", ++defer_id, "$", entry->name); defer_id += 1; code = Texts(code, compile_declaration(entry->b->type, defer_name), " = ", entry->b->code, ";\n"); set_binding(defer_env, entry->name, entry->b->type, defer_name); diff --git a/src/compile/structs.c b/src/compile/structs.c index 526c11c7..8560a790 100644 --- a/src/compile/structs.c +++ b/src/compile/structs.c @@ -18,7 +18,7 @@ Text_t compile_struct_typeinfo(env_t *env, type_t *t, const char *name, arg_ast_ ? Text$from_str(name) : Texts("struct ", namespace_name(env, env->namespace, Texts(name, "$$struct"))); - int num_fields = 0; + int64_t num_fields = 0; for (arg_ast_t *f = fields; f; f = f->next) num_fields += 1; const char *short_name = name; @@ -33,9 +33,9 @@ Text_t compile_struct_typeinfo(env_t *env, type_t *t, const char *name, arg_ast_ ", " ".tag=StructInfo, .StructInfo.name=\"", short_name, "\"", is_secret ? Text(", .StructInfo.is_secret=true") : EMPTY_TEXT, - is_opaque ? Text(", .StructInfo.is_opaque=true") : EMPTY_TEXT, ", .StructInfo.num_fields=", String(num_fields)); + is_opaque ? Text(", .StructInfo.is_opaque=true") : EMPTY_TEXT, ", .StructInfo.num_fields=", num_fields); if (fields) { - typeinfo = Texts(typeinfo, ", .StructInfo.fields=(NamedType_t[", String(num_fields), "]){"); + typeinfo = Texts(typeinfo, ", .StructInfo.fields=(NamedType_t[", num_fields, "]){"); for (arg_ast_t *f = fields; f; f = f->next) { type_t *field_type = get_arg_ast_type(env, f); typeinfo = Texts(typeinfo, "{\"", f->name, "\", ", compile_type_info(field_type), "}"); @@ -70,8 +70,7 @@ Text_t compile_struct_header(env_t *env, ast_t *ast) { Text_t struct_code = def->external ? EMPTY_TEXT : Texts(type_code, " {\n", fields, "};\n"); type_t *t = Table$str_get(*env->types, def->name); - Text_t unpadded_size = - def->opaque ? Texts("sizeof(", type_code, ")") : Text$from_str(String((int64_t)unpadded_struct_size(t))); + Text_t unpadded_size = def->opaque ? Texts("sizeof(", type_code, ")") : Texts((int64_t)unpadded_struct_size(t)); Text_t typeinfo_code = Texts("extern const TypeInfo_t ", typeinfo_name, ";\n"); Text_t optional_code = EMPTY_TEXT; if (!def->opaque) { diff --git a/src/compile/tables.c b/src/compile/tables.c index b955178e..dde8669a 100644 --- a/src/compile/tables.c +++ b/src/compile/tables.c @@ -43,7 +43,7 @@ Text_t compile_typed_table(env_t *env, ast_t *ast, type_t *table_type) { size_t n = 0; for (ast_list_t *entry = table->entries; entry; entry = entry->next) ++n; - code = Texts(code, ", ", String((int64_t)n)); + code = Texts(code, ", ", (int64_t)n); for (ast_list_t *entry = table->entries; entry; entry = entry->next) { DeclareMatch(e, entry->ast, TableEntry); diff --git a/src/compile/types.c b/src/compile/types.c index aa06e2fd..f6f276a5 100644 --- a/src/compile/types.c +++ b/src/compile/types.c @@ -23,10 +23,10 @@ Text_t compile_type(type_t *t) { case ByteType: return Text("Byte_t"); case CStringType: return Text("const char*"); case BigIntType: return Text("Int_t"); - case IntType: return Texts("Int", String(Match(t, IntType)->bits), "_t"); + case IntType: return Texts("Int", (int32_t)Match(t, IntType)->bits, "_t"); case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? Text("Num_t") - : Texts("Num", String(Match(t, NumType)->bits), "_t"); + : Texts("Num", (int32_t)Match(t, NumType)->bits, "_t"); case TextType: { DeclareMatch(text, t, TextType); if (!text->lang || streq(text->lang, "Text")) return Text("Text_t"); -- cgit v1.2.3 From e01383da05d5cf03d080854ac048df37df4d1b9a Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 15:11:52 -0400 Subject: Change module install directory to PREFIX/lib/tomo_vX.Y/* --- src/compile/headers.c | 4 ++-- src/compile/statements.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/compile') diff --git a/src/compile/headers.c b/src/compile/headers.c index 8c0863ee..be564144 100644 --- a/src/compile/headers.c +++ b/src/compile/headers.c @@ -174,8 +174,8 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, - NULL, &tm_files) + if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + &tm_files) != 0) { if (!try_install_module(mod)) code_err(ast, "Could not find library"); } diff --git a/src/compile/statements.c b/src/compile/statements.c index e296795b..82a91a5e 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -204,8 +204,8 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, - NULL, &tm_files) + if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + &tm_files) != 0) { if (!try_install_module(mod)) code_err(ast, "Could not find library"); } -- cgit v1.2.3 From ed50c5fefb8892ad2ba5262491669f268ddbd436 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 16:44:58 -0400 Subject: Overhaul code to stop keeping examples and libraries in the same repo, but instead spin each out into its own repo. --- src/compile/headers.c | 2 +- src/compile/statements.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/compile') diff --git a/src/compile/headers.c b/src/compile/headers.c index be564144..d1131bde 100644 --- a/src/compile/headers.c +++ b/src/compile/headers.c @@ -177,7 +177,7 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(ast, "Could not find library"); + if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); } Text_t includes = EMPTY_TEXT; diff --git a/src/compile/statements.c b/src/compile/statements.c index 82a91a5e..af6a5223 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -207,7 +207,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(ast, "Could not find library"); + if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); } Text_t initialization = EMPTY_TEXT; -- cgit v1.2.3 From 081a26de86eca95ba3ee0887992cdc3d96190cce Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 17:32:42 -0400 Subject: Fixes for local-tomo so that it *actually* uses local header files, which don't need to be installed anymore. --- src/compile/headers.c | 2 +- src/compile/statements.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/compile') diff --git a/src/compile/headers.c b/src/compile/headers.c index d1131bde..6dc69f03 100644 --- a/src/compile/headers.c +++ b/src/compile/headers.c @@ -174,7 +174,7 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + if (glob(String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); diff --git a/src/compile/statements.c b/src/compile/statements.c index af6a5223..a7c5214a 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -204,7 +204,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + if (glob(String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); -- cgit v1.2.3 From aa15f0f78214cefa9fabace61c119e01812a3050 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 6 Sep 2025 13:51:18 -0400 Subject: Refactor a bit in order to catch issue with ConvertDefs creating infinite loops --- src/compile/files.c | 6 +++--- src/compile/functions.c | 20 ++++---------------- src/compile/statements.c | 22 +++++++++++++++------- 3 files changed, 22 insertions(+), 26 deletions(-) (limited to 'src/compile') diff --git a/src/compile/files.c b/src/compile/files.c index a6af2300..c250e6cc 100644 --- a/src/compile/files.c +++ b/src/compile/files.c @@ -95,13 +95,13 @@ static Text_t compile_top_level_code(env_t *env, ast_t *ast) { return compile_function(env, name_code, ast, &env->code->staticdefs); } case ConvertDef: { - type_t *type = get_function_def_type(env, ast); - const char *name = get_type_name(Match(type, FunctionType)->ret); + type_t *type = get_function_return_type(env, ast); + const char *name = get_type_name(type); if (!name) code_err(ast, "Conversions are only supported for text, struct, and enum " "types, not ", - type_to_str(Match(type, FunctionType)->ret)); + type_to_str(type)); Text_t name_code = namespace_name(env, env->namespace, Texts(name, "$", get_line_number(ast->file, ast->start))); return compile_function(env, name_code, ast, &env->code->staticdefs); diff --git a/src/compile/functions.c b/src/compile/functions.c index 6caefa8b..f04a3b59 100644 --- a/src/compile/functions.c +++ b/src/compile/functions.c @@ -256,18 +256,7 @@ Text_t compile_lambda(env_t *env, ast_t *ast) { set_binding(body_scope, arg->name, arg_type, Texts("_$", arg->name)); } - type_t *ret_t = get_type(body_scope, lambda->body); - if (ret_t->tag == ReturnType) ret_t = Match(ret_t, ReturnType)->ret; - - if (lambda->ret_type) { - type_t *declared = parse_type_ast(env, lambda->ret_type); - if (can_promote(ret_t, declared)) ret_t = declared; - else - code_err(ast, "This function was declared to return a value of type ", type_to_str(declared), - ", but actually returns a value of type ", type_to_str(ret_t)); - } - - body_scope->fn_ret = ret_t; + body_scope->fn = ast; Table_t closed_vars = get_closed_vars(env, lambda->args, ast); if (Table$length(closed_vars) > 0) { // Create a typedef for the lambda's closure userdata @@ -289,6 +278,7 @@ Text_t compile_lambda(env_t *env, ast_t *ast) { env->code->local_typedefs = Texts(env->code->local_typedefs, def); } + type_t *ret_t = get_function_return_type(env, ast); Text_t code = Texts("static ", compile_type(ret_t), " ", name, "("); for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); @@ -623,7 +613,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static bool is_private = false; const char *function_name; arg_ast_t *args; - type_t *ret_t; + type_t *ret_t = get_function_return_type(env, ast); ast_t *body; ast_t *cache; bool is_inline; @@ -632,14 +622,12 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static function_name = Match(fndef->name, Var)->name; is_private = function_name[0] == '_'; args = fndef->args; - ret_t = fndef->ret_type ? parse_type_ast(env, fndef->ret_type) : Type(VoidType); body = fndef->body; cache = fndef->cache; is_inline = fndef->is_inline; } else { DeclareMatch(convertdef, ast, ConvertDef); args = convertdef->args; - ret_t = convertdef->ret_type ? parse_type_ast(env, convertdef->ret_type) : Type(VoidType); function_name = get_type_name(ret_t); if (!function_name) code_err(ast, @@ -689,7 +677,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static set_binding(body_scope, arg->name, arg_type, Texts("_$", arg->name)); } - body_scope->fn_ret = ret_t; + body_scope->fn = ast; type_t *body_type = get_type(body_scope, body); if (ret_t->tag == AbortType) { diff --git a/src/compile/statements.c b/src/compile/statements.c index a7c5214a..4e37838c 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -131,7 +131,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { return code; } case Return: { - if (!env->fn_ret) code_err(ast, "This return statement is not inside any function"); + if (!env->fn) code_err(ast, "This return statement is not inside any function"); ast_t *ret = Match(ast, Return)->value; Text_t code = EMPTY_TEXT; @@ -139,22 +139,30 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { code = Texts(code, compile_statement(deferred->defer_env, deferred->block)); } + type_t *ret_type = get_function_return_type(env, env->fn); if (ret) { - if (env->fn_ret->tag == VoidType || env->fn_ret->tag == AbortType) + if (ret_type->tag == VoidType || ret_type->tag == AbortType) code_err(ast, "This function is not supposed to return any values, " "according to its type signature"); - env = with_enum_scope(env, env->fn_ret); - Text_t value = compile_to_type(env, ret, env->fn_ret); + env = with_enum_scope(env, ret_type); + if (env->fn->tag == ConvertDef) { + type_t *value_type = get_type(env, ret); + if (!type_eq(value_type, ret_type)) { + code_err(ret, "This value is a ", type_to_text(value_type), + " but this conversion needs an explicit ", type_to_text(ret_type)); + } + } + Text_t value = compile_to_type(env, ret, ret_type); if (env->deferred) { - code = Texts(compile_declaration(env->fn_ret, Text("ret")), " = ", value, ";\n", code); + code = Texts(compile_declaration(ret_type, Text("ret")), " = ", value, ";\n", code); value = Text("ret"); } return Texts(code, "return ", value, ";"); } else { - if (env->fn_ret->tag != VoidType) - code_err(ast, "This function expects you to return a ", type_to_str(env->fn_ret), " value"); + if (ret_type->tag != VoidType) + code_err(ast, "This function expects you to return a ", type_to_text(ret_type), " value"); return Texts(code, "return;"); } } -- cgit v1.2.3 From cdb326a6e74e80bea9bffbeaaff1c5d1f4c9e733 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 6 Sep 2025 14:34:38 -0400 Subject: Code cleanup --- src/compile/binops.c | 2 +- src/compile/files.c | 41 +++++++++++++++++++++++----------------- src/compile/reductions.c | 2 +- src/compile/statements.c | 49 ++++++++++++++---------------------------------- 4 files changed, 40 insertions(+), 54 deletions(-) (limited to 'src/compile') diff --git a/src/compile/binops.c b/src/compile/binops.c index 87fd2c7a..ed4aaeba 100644 --- a/src/compile/binops.c +++ b/src/compile/binops.c @@ -67,7 +67,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { } } } else if ((ast->tag == Divide || ast->tag == Mod || ast->tag == Mod1) && is_numeric_type(rhs_t)) { - b = get_namespace_binding(env, binop.lhs, binop_method_name(ast->tag)); + b = get_namespace_binding(env, binop.lhs, binop_info[ast->tag].method_name); if (b && b->type->tag == FunctionType) { DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, lhs_t)) { diff --git a/src/compile/files.c b/src/compile/files.c index c250e6cc..3e91976b 100644 --- a/src/compile/files.c +++ b/src/compile/files.c @@ -12,7 +12,16 @@ #include "../types.h" #include "compilation.h" -static void initialize_vars_and_statics(env_t *env, ast_t *ast) { +static void initialize_vars_and_statics(env_t *env, ast_t *ast); +static void initialize_namespace(env_t *env, const char *name, ast_t *namespace); +static Text_t compile_top_level_code(env_t *env, ast_t *ast); +static Text_t compile_namespace(env_t *env, const char *name, ast_t *namespace); + +void initialize_namespace(env_t *env, const char *name, ast_t *namespace) { + initialize_vars_and_statics(namespace_env(env, name), namespace); +} + +void initialize_vars_and_statics(env_t *env, ast_t *ast) { if (!ast) return; for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { @@ -27,24 +36,20 @@ static void initialize_vars_and_statics(env_t *env, ast_t *ast) { if (t->tag == FunctionType) t = Type(ClosureType, t); Text_t val_code = compile_declared_value(env, stmt->ast); if ((decl->value && !is_constant(env, decl->value)) || (!decl->value && has_heap_memory(t))) { - Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, "$$initialized")); + Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, "$initialized")); env->code->variable_initializers = Texts(env->code->variable_initializers, with_source_info(env, stmt->ast, Texts(full_name, " = ", val_code, ",\n", initialized_name, " = true;\n"))); } } else if (stmt->ast->tag == StructDef) { - initialize_vars_and_statics(namespace_env(env, Match(stmt->ast, StructDef)->name), - Match(stmt->ast, StructDef)->namespace); + initialize_namespace(env, Match(stmt->ast, StructDef)->name, Match(stmt->ast, StructDef)->namespace); } else if (stmt->ast->tag == EnumDef) { - initialize_vars_and_statics(namespace_env(env, Match(stmt->ast, EnumDef)->name), - Match(stmt->ast, EnumDef)->namespace); + initialize_namespace(env, Match(stmt->ast, EnumDef)->name, Match(stmt->ast, EnumDef)->namespace); } else if (stmt->ast->tag == LangDef) { - initialize_vars_and_statics(namespace_env(env, Match(stmt->ast, LangDef)->name), - Match(stmt->ast, LangDef)->namespace); + initialize_namespace(env, Match(stmt->ast, LangDef)->name, Match(stmt->ast, LangDef)->namespace); } else if (stmt->ast->tag == Extend) { - initialize_vars_and_statics(namespace_env(env, Match(stmt->ast, Extend)->name), - Match(stmt->ast, Extend)->body); + initialize_namespace(env, Match(stmt->ast, Extend)->name, Match(stmt->ast, Extend)->body); } else if (stmt->ast->tag == Use) { continue; } else { @@ -54,7 +59,12 @@ static void initialize_vars_and_statics(env_t *env, ast_t *ast) { } } -static Text_t compile_top_level_code(env_t *env, ast_t *ast) { +Text_t compile_namespace(env_t *env, const char *name, ast_t *namespace) { + env_t *ns_env = namespace_env(env, name); + return namespace ? compile_top_level_code(ns_env, namespace) : EMPTY_TEXT; +} + +Text_t compile_top_level_code(env_t *env, ast_t *ast) { if (!ast) return EMPTY_TEXT; switch (ast->tag) { @@ -111,15 +121,13 @@ static Text_t compile_top_level_code(env_t *env, ast_t *ast) { type_t *t = Table$str_get(*env->types, def->name); assert(t && t->tag == StructType); Text_t code = compile_struct_typeinfo(env, t, def->name, def->fields, def->secret, def->opaque); - env_t *ns_env = namespace_env(env, def->name); - return Texts(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : EMPTY_TEXT); + return Texts(code, compile_namespace(env, def->name, def->namespace)); } case EnumDef: { DeclareMatch(def, ast, EnumDef); Text_t code = compile_enum_typeinfo(env, ast); code = Texts(code, compile_enum_constructors(env, ast)); - env_t *ns_env = namespace_env(env, def->name); - return Texts(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : EMPTY_TEXT); + return Texts(code, compile_namespace(env, def->name, def->namespace)); } case LangDef: { DeclareMatch(def, ast, LangDef); @@ -127,8 +135,7 @@ static Text_t compile_top_level_code(env_t *env, ast_t *ast) { Texts("public const TypeInfo_t ", namespace_name(env, env->namespace, Texts(def->name, "$$info")), " = {", (int64_t)sizeof(Text_t), ", ", (int64_t)__alignof__(Text_t), ", .metamethods=Text$metamethods, .tag=TextInfo, .TextInfo={", quoted_str(def->name), "}};\n"); - env_t *ns_env = namespace_env(env, def->name); - return Texts(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : EMPTY_TEXT); + return Texts(code, compile_namespace(env, def->name, def->namespace)); } case Extend: { DeclareMatch(extend, ast, Extend); diff --git a/src/compile/reductions.c b/src/compile/reductions.c index 1652384c..438e072b 100644 --- a/src/compile/reductions.c +++ b/src/compile/reductions.c @@ -12,7 +12,7 @@ public Text_t compile_reduction(env_t *env, ast_t *ast) { DeclareMatch(reduction, ast, Reduction); ast_e op = reduction->op; - const char *op_str = binop_operator(op); + const char *op_str = binop_info[op].operator; type_t *iter_t = get_type(env, reduction->iter); type_t *item_t = get_iterated_type(iter_t); diff --git a/src/compile/statements.c b/src/compile/statements.c index 4e37838c..bde9ae36 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -25,6 +25,14 @@ Text_t with_source_info(env_t *env, ast_t *ast, Text_t code) { return Texts("\n#line ", line, "\n", code); } +static Text_t compile_simple_update_assignment(env_t *env, ast_t *ast, const char *op) { + binary_operands_t update = BINARY_OPERANDS(ast); + type_t *lhs_t = get_type(env, update.lhs); + if (is_idempotent(update.lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) + return Texts(compile_lvalue(env, update.lhs), " ", op, "= ", compile_to_type(env, update.rhs, lhs_t), ";"); + return compile_update_assignment(env, ast); +} + static Text_t _compile_statement(env_t *env, ast_t *ast) { switch (ast->tag) { case When: return compile_when_statement(env, ast); @@ -47,41 +55,12 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { } } case Assign: return compile_assignment_statement(env, ast); - case PlusUpdate: { - DeclareMatch(update, ast, PlusUpdate); - type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) - return Texts(compile_lvalue(env, update->lhs), " += ", compile_to_type(env, update->rhs, lhs_t), ";"); - return compile_update_assignment(env, ast); - } - case MinusUpdate: { - DeclareMatch(update, ast, MinusUpdate); - type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) - return Texts(compile_lvalue(env, update->lhs), " -= ", compile_to_type(env, update->rhs, lhs_t), ";"); - return compile_update_assignment(env, ast); - } - case MultiplyUpdate: { - DeclareMatch(update, ast, MultiplyUpdate); - type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) - return Texts(compile_lvalue(env, update->lhs), " *= ", compile_to_type(env, update->rhs, lhs_t), ";"); - return compile_update_assignment(env, ast); - } - case DivideUpdate: { - DeclareMatch(update, ast, DivideUpdate); - type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) - return Texts(compile_lvalue(env, update->lhs), " /= ", compile_to_type(env, update->rhs, lhs_t), ";"); - return compile_update_assignment(env, ast); - } - case ModUpdate: { - DeclareMatch(update, ast, ModUpdate); - type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) - return Texts(compile_lvalue(env, update->lhs), " %= ", compile_to_type(env, update->rhs, lhs_t), ";"); - return compile_update_assignment(env, ast); - } + case PlusUpdate: return compile_simple_update_assignment(env, ast, "+"); + case MinusUpdate: return compile_simple_update_assignment(env, ast, "-"); + case MultiplyUpdate: return compile_simple_update_assignment(env, ast, "*"); + case DivideUpdate: return compile_simple_update_assignment(env, ast, "/"); + case ModUpdate: return compile_simple_update_assignment(env, ast, "%"); + case PowerUpdate: case Mod1Update: case ConcatUpdate: -- cgit v1.2.3 From 73246764f88f6f652316ee0c138a990d836698a7 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 6 Sep 2025 14:38:58 -0400 Subject: Fixes for prior changes --- src/compile/files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/compile') diff --git a/src/compile/files.c b/src/compile/files.c index 3e91976b..4d6fb1a8 100644 --- a/src/compile/files.c +++ b/src/compile/files.c @@ -36,7 +36,7 @@ void initialize_vars_and_statics(env_t *env, ast_t *ast) { if (t->tag == FunctionType) t = Type(ClosureType, t); Text_t val_code = compile_declared_value(env, stmt->ast); if ((decl->value && !is_constant(env, decl->value)) || (!decl->value && has_heap_memory(t))) { - Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, "$initialized")); + Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, "$$initialized")); env->code->variable_initializers = Texts(env->code->variable_initializers, with_source_info(env, stmt->ast, -- cgit v1.2.3