From 5fc7577b5a3bc2c445522dfd5b287e1c6eddc3e9 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 31 Aug 2025 23:33:22 -0400 Subject: Switch to using optional return values for list indexing. --- src/compile/assignments.c | 18 +++++++----------- src/compile/indexing.c | 10 ++-------- 2 files changed, 9 insertions(+), 19 deletions(-) (limited to 'src/compile') diff --git a/src/compile/assignments.c b/src/compile/assignments.c index ab28b972..5fedad9a 100644 --- a/src/compile/assignments.c +++ b/src/compile/assignments.c @@ -92,7 +92,8 @@ Text_t compile_assignment_statement(env_t *env, ast_t *ast) { if (assign->targets && !assign->targets->next) { type_t *lhs_t = get_type(env, assign->targets->ast); if (assign->targets->ast->tag == Index && lhs_t->tag == OptionalType - && value_type(get_type(env, Match(assign->targets->ast, Index)->indexed))->tag == TableType) + && (value_type(get_type(env, Match(assign->targets->ast, Index)->indexed))->tag == TableType + || value_type(get_type(env, Match(assign->targets->ast, Index)->indexed))->tag == ListType)) lhs_t = Match(lhs_t, OptionalType)->type; if (has_stack_memory(lhs_t)) code_err(ast, "Stack references cannot be assigned to " @@ -110,7 +111,8 @@ Text_t compile_assignment_statement(env_t *env, ast_t *ast) { value = value->next, target = target->next) { type_t *lhs_t = get_type(env, target->ast); if (target->ast->tag == Index && lhs_t->tag == OptionalType - && value_type(get_type(env, Match(target->ast, Index)->indexed))->tag == TableType) + && (value_type(get_type(env, Match(target->ast, Index)->indexed))->tag == TableType + || value_type(get_type(env, Match(target->ast, Index)->indexed))->tag == ListType)) lhs_t = Match(lhs_t, OptionalType)->type; if (has_stack_memory(lhs_t)) code_err(ast, "Stack references cannot be assigned to " @@ -166,14 +168,9 @@ Text_t compile_lvalue(env_t *env, ast_t *ast) { ? compile_int_to_type(env, index->index, Type(IntType, .bits = TYPE_IBITS64)) : (index_t->tag == BigIntType ? Texts("Int64$from_int(", compile(env, index->index), ", no)") : Texts("(Int64_t)(", compile(env, index->index), ")")); - if (index->unchecked) { - return Texts("List_lvalue_unchecked(", compile_type(item_type), ", ", target_code, ", ", index_code, - ")"); - } 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)), ")"); - } + 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)), + ")"); } else if (container_t->tag == TableType) { DeclareMatch(table_type, container_t, TableType); if (table_type->default_value) { @@ -184,7 +181,6 @@ Text_t compile_lvalue(env_t *env, ast_t *ast) { compile_to_type(env, table_type->default_value, table_type->value_type), ", ", compile_type_info(container_t), ")"); } - if (index->unchecked) code_err(ast, "Table indexes cannot be unchecked"); return Texts("*(", 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, table_type->key_type, .is_stack = true)), diff --git a/src/compile/indexing.c b/src/compile/indexing.c index e99feeb2..d2e98388 100644 --- a/src/compile/indexing.c +++ b/src/compile/indexing.c @@ -34,21 +34,15 @@ Text_t compile_indexing(env_t *env, ast_t *ast) { code_err(indexing->index, "Lists can only be indexed by integers, not ", type_to_str(index_t)); type_t *item_type = Match(container_t, ListType)->item_type; Text_t list = compile_to_pointer_depth(env, indexing->indexed, 0, false); - file_t *f = indexing->index->file; Text_t index_code = indexing->index->tag == Int ? compile_int_to_type(env, indexing->index, Type(IntType, .bits = TYPE_IBITS64)) : (index_t->tag == BigIntType ? Texts("Int64$from_int(", compile(env, indexing->index), ", no)") : Texts("(Int64_t)(", compile(env, indexing->index), ")")); - if (indexing->unchecked) - 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)), ")"); + return Texts("List_get(", list, ", ", index_code, ", ", compile_type(item_type), ", value, ", + promote_to_optional(item_type, Text("value")), ", ", compile_none(item_type), ")"); } else if (container_t->tag == TableType) { DeclareMatch(table_type, container_t, TableType); - if (indexing->unchecked) code_err(ast, "Table indexes cannot be unchecked"); if (table_type->default_value) { return Texts("Table$get_or_default(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", compile_type(table_type->key_type), ", ", compile_type(table_type->value_type), ", ", -- cgit v1.2.3 From 0a7062e2d711b5ac7fb71e873f293a8f0d0e8bc6 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 12:43:08 -0400 Subject: Improved error messages --- src/compile/expressions.c | 2 +- src/compile/indexing.c | 20 +++++++++++++++++--- src/compile/indexing.h | 4 +++- src/compile/optionals.c | 4 +++- 4 files changed, 24 insertions(+), 6 deletions(-) (limited to 'src/compile') diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 2320474a..e21ee263 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -234,7 +234,7 @@ Text_t compile(env_t *env, ast_t *ast) { case If: return compile_if_expression(env, ast); case Reduction: return compile_reduction(env, ast); case FieldAccess: return compile_field_access(env, ast); - case Index: return compile_indexing(env, ast); + case Index: return compile_indexing(env, ast, false); case InlineCCode: { type_t *t = get_type(env, ast); if (t->tag == VoidType) return Texts("{\n", compile_statement(env, ast), "\n}"); diff --git a/src/compile/indexing.c b/src/compile/indexing.c index d2e98388..cca06184 100644 --- a/src/compile/indexing.c +++ b/src/compile/indexing.c @@ -1,5 +1,7 @@ // This file defines how to compile indexing like `list[i]` or `ptr[]` +#include + #include "../ast.h" #include "../config.h" #include "../environment.h" @@ -9,7 +11,7 @@ #include "compilation.h" public -Text_t compile_indexing(env_t *env, ast_t *ast) { +Text_t compile_indexing(env_t *env, ast_t *ast, bool checked) { DeclareMatch(indexing, ast, Index); type_t *indexed_type = get_type(env, indexing->indexed); if (!indexing->index) { @@ -39,8 +41,14 @@ Text_t compile_indexing(env_t *env, ast_t *ast) { ? compile_int_to_type(env, indexing->index, Type(IntType, .bits = TYPE_IBITS64)) : (index_t->tag == BigIntType ? Texts("Int64$from_int(", compile(env, indexing->index), ", no)") : Texts("(Int64_t)(", compile(env, indexing->index), ")")); - return Texts("List_get(", list, ", ", index_code, ", ", compile_type(item_type), ", value, ", - promote_to_optional(item_type, Text("value")), ", ", compile_none(item_type), ")"); + if (checked) { + int64_t start = (int64_t)(ast->start - ast->file->text), end = (int64_t)(ast->end - ast->file->text); + return Texts("List_get_checked(", list, ", ", index_code, ", ", compile_type(item_type), ", ", + String(start), ", ", String(end), ")"); + } else { + return Texts("List_get(", list, ", ", index_code, ", ", compile_type(item_type), ", value, ", + promote_to_optional(item_type, Text("value")), ", ", compile_none(item_type), ")"); + } } else if (container_t->tag == TableType) { DeclareMatch(table_type, container_t, TableType); if (table_type->default_value) { @@ -49,6 +57,12 @@ Text_t compile_indexing(env_t *env, ast_t *ast) { compile(env, indexing->index), ", ", compile_to_type(env, table_type->default_value, table_type->value_type), ", ", compile_type_info(container_t), ")"); + } else if (checked) { + int64_t start = (int64_t)(ast->start - ast->file->text), end = (int64_t)(ast->end - ast->file->text); + return Texts("Table$get_checked(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", + compile_type(table_type->key_type), ", ", compile_type(table_type->value_type), ", ", + compile(env, indexing->index), ", ", String(start), ", ", String(end), ", ", + compile_type_info(container_t), ")"); } else { return Texts("Table$get_optional(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", compile_type(table_type->key_type), ", ", compile_type(table_type->value_type), ", ", diff --git a/src/compile/indexing.h b/src/compile/indexing.h index bf30f98a..5b76692b 100644 --- a/src/compile/indexing.h +++ b/src/compile/indexing.h @@ -2,8 +2,10 @@ #pragma once +#include + #include "../ast.h" #include "../environment.h" #include "../stdlib/datatypes.h" -Text_t compile_indexing(env_t *env, ast_t *ast); +Text_t compile_indexing(env_t *env, ast_t *ast, bool checked); diff --git a/src/compile/optionals.c b/src/compile/optionals.c index b3d94005..f32e925e 100644 --- a/src/compile/optionals.c +++ b/src/compile/optionals.c @@ -8,6 +8,7 @@ #include "../typecheck.h" #include "../types.h" #include "compilation.h" +#include "indexing.h" Text_t optional_into_nonnone(type_t *t, Text_t value) { if (t->tag == OptionalType) t = Match(t, OptionalType)->type; @@ -122,6 +123,7 @@ Text_t compile_optional(env_t *env, ast_t *ast) { public Text_t compile_non_optional(env_t *env, ast_t *ast) { ast_t *value = Match(ast, NonOptional)->value; + if (value->tag == Index && Match(value, Index)->index != NULL) return compile_indexing(env, value, true); type_t *t = get_type(env, value); Text_t value_code = compile(env, value); int64_t line = get_line_number(ast->file, ast->start); @@ -129,6 +131,6 @@ Text_t compile_non_optional(env_t *env, ast_t *ast) { 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")), + "\"This was expected to be a value, but it's `none`\\n\");\n", optional_into_nonnone(t, Text("opt")), "; })"); } -- cgit v1.2.3 From 639d5ddfca562e5b3645955551be244b5e8ca9c6 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 12:51:19 -0400 Subject: Make text indexing optional --- src/compile/indexing.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/compile') diff --git a/src/compile/indexing.c b/src/compile/indexing.c index cca06184..9d3501c9 100644 --- a/src/compile/indexing.c +++ b/src/compile/indexing.c @@ -73,8 +73,15 @@ Text_t compile_indexing(env_t *env, ast_t *ast, bool checked) { compile_none(table_type->value_type), ", ", compile_type_info(container_t), ")"); } } else if (container_t->tag == TextType) { - return Texts("Text$cluster(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", - compile_to_type(env, indexing->index, Type(BigIntType)), ")"); + if (checked) { + int64_t start = (int64_t)(ast->start - ast->file->text), end = (int64_t)(ast->end - ast->file->text); + return Texts("Text$cluster_checked(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", + compile_to_type(env, indexing->index, Type(BigIntType)), ", ", String(start), ", ", + String(end), ")"); + } else { + return Texts("Text$cluster(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", + compile_to_type(env, indexing->index, Type(BigIntType)), ")"); + } } else { code_err(ast, "Indexing is not supported for type: ", type_to_str(container_t)); } -- cgit v1.2.3