aboutsummaryrefslogtreecommitdiff
path: root/src/compile
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2026-01-02 15:10:48 -0500
committerBruce Hill <bruce@bruce-hill.com>2026-01-02 15:10:48 -0500
commit9653a7c2e53e2bc5e8f146a7d9ea1e71eed19e08 (patch)
tree7f026a142b4f8efcdbf517cc58adc97eb3b37cd5 /src/compile
parente4d5bf73e4ad9dc51f923a32903011edfeae2908 (diff)
parentce49f93da58d007c0a52ee82e2421adfe06012f9 (diff)
Merge branch 'dev' into constructive-reals
Diffstat (limited to 'src/compile')
-rw-r--r--src/compile/assertions.c14
-rw-r--r--src/compile/blocks.c4
-rw-r--r--src/compile/cli.c4
-rw-r--r--src/compile/comparisons.c1
-rw-r--r--src/compile/files.c4
-rw-r--r--src/compile/functions.c3
-rw-r--r--src/compile/headers.c4
-rw-r--r--src/compile/indexing.c2
-rw-r--r--src/compile/optionals.c8
-rw-r--r--src/compile/promotions.c16
-rw-r--r--src/compile/statements.c2
-rw-r--r--src/compile/text.c15
-rw-r--r--src/compile/text.h8
13 files changed, 41 insertions, 44 deletions
diff --git a/src/compile/assertions.c b/src/compile/assertions.c
index 34055998..18531fd9 100644
--- a/src/compile/assertions.c
+++ b/src/compile/assertions.c
@@ -60,13 +60,10 @@ Text_t compile_assertion(env_t *env, ast_t *ast) {
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"),
+ ", ", (int64_t)(expr->end - expr->file->text), ", Text$concat(",
+ message ? compile_to_type(env, message, Type(TextType)) : Text("Text(\"This assertion failed!\")"),
+ ", Text(\" (\"), ", expr_as_text(Text("_lhs"), operand_t, Text("no")), ", Text(\" ", failure,
+ " \"), ", expr_as_text(Text("_rhs"), operand_t, Text("no")), ", Text(\")\")));\n"),
"}\n");
}
default: {
@@ -74,8 +71,7 @@ Text_t compile_assertion(env_t *env, ast_t *ast) {
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!\""),
+ message ? compile_to_type(env, message, Type(TextType)) : Text("Text(\"This assertion failed!\")"),
");\n");
}
}
diff --git a/src/compile/blocks.c b/src/compile/blocks.c
index 1059fd34..66869ecc 100644
--- a/src/compile/blocks.c
+++ b/src/compile/blocks.c
@@ -9,7 +9,9 @@
#include "compilation.h"
public
-Text_t compile_block(env_t *env, ast_t *ast) { return Texts("{\n", compile_inline_block(env, ast), "}\n"); }
+Text_t compile_block(env_t *env, ast_t *ast) {
+ return Texts("{\n", compile_inline_block(env, ast), "}\n");
+}
Text_t compile_block_expression(env_t *env, ast_t *ast) {
ast_list_t *stmts = Match(ast, Block)->statements;
diff --git a/src/compile/cli.c b/src/compile/cli.c
index 63a467ca..ade6caa7 100644
--- a/src/compile/cli.c
+++ b/src/compile/cli.c
@@ -83,10 +83,8 @@ static Text_t generate_usage(env_t *env, type_t *fn_type) {
else if (t->tag == ListType) usage = Texts(usage, "[", flags, " ", get_flag_options(t, Text("|")), "]");
else if (t->tag == EnumType) usage = Texts(usage, "[", flags, " val]");
else usage = Texts(usage, "[", flags, " ", get_flag_options(t, Text("|")), "]");
- } else if (t->tag == EnumType) {
- usage = Texts(usage, "\x1b[1m", flag, "\x1b[m");
} else {
- usage = Texts(usage, "\x1b[1m", get_flag_options(t, Text("|")), "\x1b[m");
+ usage = Texts(usage, "\x1b[1m", flag, "\x1b[m");
}
}
return usage;
diff --git a/src/compile/comparisons.c b/src/compile/comparisons.c
index 5e95459c..afb5dc15 100644
--- a/src/compile/comparisons.c
+++ b/src/compile/comparisons.c
@@ -41,6 +41,7 @@ Text_t compile_comparison(env_t *env, ast_t *ast) {
} else {
code_err(ast, "I can't do comparisons between ", type_to_text(lhs_t), " and ", type_to_text(rhs_t));
}
+ assert(operand_t);
Text_t lhs, rhs;
lhs = compile_to_type(env, binop.lhs, operand_t);
diff --git a/src/compile/files.c b/src/compile/files.c
index 27c2e041..555f848c 100644
--- a/src/compile/files.c
+++ b/src/compile/files.c
@@ -194,8 +194,8 @@ Text_t compile_file(env_t *env, ast_t *ast) {
const char *name = file_base_name(ast->file->filename);
return Texts(env->do_source_mapping ? Texts("#line 1 ", quoted_str(ast->file->filename), "\n") : EMPTY_TEXT,
- "#define __SOURCE_FILE__ ", quoted_str(ast->file->filename), "\n",
- "#include <tomo@" TOMO_VERSION "/tomo.h>\n"
+ "#define __SOURCE_FILE__ ", quoted_str(ast->file->filename), "\n", "#include <tomo@", TOMO_VERSION,
+ "/tomo.h>\n"
"#include \"",
name, ".tm.h\"\n\n", includes, env->code->local_typedefs, "\n", env->code->lambdas, "\n",
env->code->staticdefs, "\n", top_level_code, "public void ",
diff --git a/src/compile/functions.c b/src/compile/functions.c
index 77393ab2..cadd0453 100644
--- a/src/compile/functions.c
+++ b/src/compile/functions.c
@@ -630,7 +630,10 @@ static void check_unused_vars(env_t *env, arg_ast_t *args, ast_t *body) {
const char *name;
} *entry = unused.entries.data + i * unused.entries.stride;
if (streq(entry->name, "_")) continue;
+ // Global/file scoped vars are okay to mutate without reading
+ if (get_binding(env, entry->name) != NULL) continue;
ast_t *var = Table$str_get(assigned_vars, entry->name);
+ assert(var);
code_err(var, "This variable was assigned to, but never read from.");
}
}
diff --git a/src/compile/headers.c b/src/compile/headers.c
index e90556a1..df7142d1 100644
--- a/src/compile/headers.c
+++ b/src/compile/headers.c
@@ -135,7 +135,7 @@ Text_t compile_file_header(env_t *env, Path_t header_path, ast_t *ast) {
Text_t header =
Texts("#pragma once\n",
env->do_source_mapping ? Texts("#line 1 ", quoted_str(ast->file->filename), "\n") : EMPTY_TEXT,
- "#include <tomo@" TOMO_VERSION "/tomo.h>\n");
+ "#include <tomo@", TOMO_VERSION, "/tomo.h>\n");
compile_typedef_info_t info = {.env = env, .header = &header, .header_path = header_path};
visit_topologically(Match(ast, Block)->statements, (Closure_t){.fn = (void *)_make_typedefs, &info});
@@ -161,7 +161,7 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast)
module_info_t mod = get_used_module_info(ast);
glob_t tm_files;
const char *folder = mod.version ? String(mod.name, "@", mod.version) : mod.name;
- if (glob(String(TOMO_PATH, "/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/indexing.c b/src/compile/indexing.c
index 13062641..031ef9a0 100644
--- a/src/compile/indexing.c
+++ b/src/compile/indexing.c
@@ -50,7 +50,7 @@ Text_t compile_indexing(env_t *env, ast_t *ast, bool checked) {
return Texts("({ ", compile_declaration(item_type, Text("opt")), " = ", code, "; ", "if unlikely (",
check_none(item_type, Text("opt")), ")\n", "#line ", line, "\n", "fail_source(",
quoted_str(ast->file->filename), ", ", start, ", ", end, ", ",
- "\"This was expected to be a value, but it's `none`\\n\");\n",
+ "Text(\"This was expected to be a value, but it's `none`\\n\"));\n",
optional_into_nonnone(item_type, Text("opt")), "; })");
}
return code;
diff --git a/src/compile/optionals.c b/src/compile/optionals.c
index 9aca84d0..f54d8931 100644
--- a/src/compile/optionals.c
+++ b/src/compile/optionals.c
@@ -134,9 +134,9 @@ Text_t compile_non_optional(env_t *env, ast_t *ast) {
compile_to_pointer_depth(env, f->fielded, 0, true), ";",
"if unlikely (_test_enum.$tag != ", tag_name, ") {\n", "#line ", line, "\n", "fail_source(",
quoted_str(f->fielded->file->filename), ", ", (int64_t)(f->fielded->start - f->fielded->file->text),
- ", ", (int64_t)(f->fielded->end - f->fielded->file->text), ", ", "\"This was expected to be ",
- tag->name, ", but it was: \", ", expr_as_text(Text("_test_enum"), enum_t, Text("false")),
- ", \"\\n\");\n}\n",
+ ", ", (int64_t)(f->fielded->end - f->fielded->file->text), ", ",
+ "Text$concat(Text(\"This was expected to be ", tag->name, ", but it was: \"), ",
+ expr_as_text(Text("_test_enum"), enum_t, Text("false")), ", Text(\"\\n\")));\n}\n",
compile_maybe_incref(
env, WrapLiteralCode(value, Texts("_test_enum.", tag->name), .type = tag->type), tag->type),
"; })");
@@ -149,7 +149,7 @@ Text_t compile_non_optional(env_t *env, ast_t *ast) {
check_none(value_t, Text("opt")), ")\n", "#line ", line, "\n", "fail_source(",
quoted_str(value->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\");\n",
+ "Text(\"This was expected to be a value, but it's `none`\\n\"));\n",
optional_into_nonnone(value_t, Text("opt")), "; })");
}
}
diff --git a/src/compile/promotions.c b/src/compile/promotions.c
index 4b5458c9..151850f0 100644
--- a/src/compile/promotions.c
+++ b/src/compile/promotions.c
@@ -8,7 +8,9 @@
#include "../types.h"
#include "compilation.h"
-static Text_t quoted_str(const char *str) { return Text$quoted(Text$from_str(str), false, Text("\"")); }
+static Text_t quoted_str(const char *str) {
+ return Text$quoted(Text$from_str(str), false, Text("\""));
+}
public
bool promote(env_t *env, ast_t *ast, Text_t *code, type_t *actual, type_t *needed) {
@@ -62,12 +64,12 @@ bool promote(env_t *env, ast_t *ast, Text_t *code, type_t *actual, type_t *neede
if (needed->tag == FloatType && actual->tag == OptionalType
&& Match(actual, OptionalType)->type->tag == FloatType) {
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 ", 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")), "; })");
+ *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), ", ",
+ "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/statements.c b/src/compile/statements.c
index 81a10ddd..c9a0fd0e 100644
--- a/src/compile/statements.c
+++ b/src/compile/statements.c
@@ -197,7 +197,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) {
module_info_t mod = get_used_module_info(ast);
glob_t tm_files;
const char *folder = mod.version ? String(mod.name, "@", mod.version) : mod.name;
- if (glob(String(TOMO_PATH, "/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/text.c b/src/compile/text.c
index 25a6e9a7..7f11169b 100644
--- a/src/compile/text.c
+++ b/src/compile/text.c
@@ -4,7 +4,6 @@
#include "../ast.h"
#include "../environment.h"
-#include "../naming.h"
#include "../stdlib/datatypes.h"
#include "../stdlib/tables.h"
#include "../stdlib/text.h"
@@ -102,19 +101,12 @@ Text_t compile_text_ast(env_t *env, ast_t *ast) {
type_t *text_t = lang ? Table$str_get(*env->types, lang) : TEXT_TYPE;
if (!text_t || text_t->tag != TextType) code_err(ast, quoted(lang), " is not a valid text language name");
- Text_t lang_constructor;
- if (!lang || streq(lang, "Text")) lang_constructor = Text("Text");
- else
- lang_constructor = namespace_name(Match(text_t, TextType)->env, Match(text_t, TextType)->env->namespace->parent,
- Text$from_str(lang));
-
ast_list_t *chunks = Match(ast, TextJoin)->children;
if (!chunks) {
- return Texts(lang_constructor, "(\"\")");
+ return Text("EMPTY_TEXT");
} else if (!chunks->next && chunks->ast->tag == TextLiteral) {
Text_t literal = Match(chunks->ast, TextLiteral)->text;
- if (string_literal_is_all_ascii(literal))
- return Texts(lang_constructor, "(", compile_text_literal(literal), ")");
+ if (string_literal_is_all_ascii(literal)) return Texts("Text(", compile_text_literal(literal), ")");
return Texts("((", compile_type(text_t), ")", compile(env, chunks->ast), ")");
} else {
Text_t code = EMPTY_TEXT;
@@ -142,7 +134,6 @@ Text_t compile_text_ast(env_t *env, ast_t *ast) {
code = Texts(code, chunk_code);
if (chunk->next) code = Texts(code, ", ");
}
- if (chunks->next) return Texts(lang_constructor, "s(", code, ")");
- else return code;
+ return Texts("Text$concat(", code, ")");
}
}
diff --git a/src/compile/text.h b/src/compile/text.h
index c160c7a9..ae3cc5c3 100644
--- a/src/compile/text.h
+++ b/src/compile/text.h
@@ -14,5 +14,9 @@ Text_t compile_text(env_t *env, ast_t *ast, Text_t color);
Text_t compile_text_literal(Text_t literal);
Text_t expr_as_text(Text_t expr, type_t *t, Text_t color);
-MACROLIKE Text_t quoted_str(const char *str) { return Text$quoted(Text$from_str(str), false, Text("\"")); }
-MACROLIKE Text_t quoted_text(Text_t text) { return Text$quoted(text, false, Text("\"")); }
+MACROLIKE Text_t quoted_str(const char *str) {
+ return Text$quoted(Text$from_str(str), false, Text("\""));
+}
+MACROLIKE Text_t quoted_text(Text_t text) {
+ return Text$quoted(text, false, Text("\""));
+}