diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 18:21:39 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 18:21:39 -0400 |
| commit | 74e8aa30901dba029f3e39d187337a09740db4e0 (patch) | |
| tree | b17b37dec809aa9c054ab7d82bfe4a52fe5c4fab | |
| parent | 7e5e03f191c4379bf7e34cccfa044ec928189eed (diff) | |
Move indexing into its own file
| -rw-r--r-- | src/compile/expressions.c | 64 | ||||
| -rw-r--r-- | src/compile/indexing.c | 78 | ||||
| -rw-r--r-- | src/compile/indexing.h | 8 | ||||
| -rw-r--r-- | src/compile/reductions.c | 1 |
4 files changed, 89 insertions, 62 deletions
diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 50963fe7..a6bcff75 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -15,6 +15,7 @@ #include "declarations.h" #include "enums.h" #include "functions.h" +#include "indexing.h" #include "integers.h" #include "lists.h" #include "optionals.h" @@ -332,68 +333,7 @@ Text_t compile(env_t *env, ast_t *ast) { default: code_err(ast, "Field accesses are not supported on ", type_to_str(fielded_t), " values"); } } - case Index: { - DeclareMatch(indexing, ast, Index); - type_t *indexed_type = get_type(env, indexing->indexed); - if (!indexing->index) { - if (indexed_type->tag != PointerType) - code_err(ast, "Only pointers can use the '[]' operator to " - "dereference " - "the entire value."); - DeclareMatch(ptr, indexed_type, PointerType); - if (ptr->pointed->tag == ListType) { - return Texts("*({ List_t *list = ", compile(env, indexing->indexed), "; LIST_INCREF(*list); list; })"); - } else if (ptr->pointed->tag == TableType || ptr->pointed->tag == SetType) { - return Texts("*({ Table_t *t = ", compile(env, indexing->indexed), "; TABLE_INCREF(*t); t; })"); - } else { - return Texts("*(", compile(env, indexing->indexed), ")"); - } - } - - type_t *container_t = value_type(indexed_type); - type_t *index_t = get_type(env, indexing->index); - if (container_t->tag == ListType) { - if (index_t->tag != IntType && index_t->tag != BigIntType && index_t->tag != ByteType) - 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)), ")"); - } 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), ", ", - compile(env, indexing->index), ", ", - compile_to_type(env, table_type->default_value, table_type->value_type), ", ", - 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), ", ", - compile(env, indexing->index), - ", " - "_, ", - promote_to_optional(table_type->value_type, Text("(*_)")), ", ", - 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)), ")"); - } else { - code_err(ast, "Indexing is not supported for type: ", type_to_str(container_t)); - } - } + 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}"); diff --git a/src/compile/indexing.c b/src/compile/indexing.c new file mode 100644 index 00000000..7245e9cf --- /dev/null +++ b/src/compile/indexing.c @@ -0,0 +1,78 @@ +// This file defines how to compile indexing like `list[i]` or `ptr[]` + +#include "../ast.h" +#include "../config.h" +#include "../environment.h" +#include "../stdlib/text.h" +#include "../stdlib/util.h" +#include "../typecheck.h" +#include "expressions.h" +#include "integers.h" +#include "optionals.h" +#include "pointers.h" +#include "promotions.h" +#include "types.h" + +public +Text_t compile_indexing(env_t *env, ast_t *ast) { + DeclareMatch(indexing, ast, Index); + type_t *indexed_type = get_type(env, indexing->indexed); + if (!indexing->index) { + if (indexed_type->tag != PointerType) + code_err(ast, "Only pointers can use the '[]' operator to " + "dereference " + "the entire value."); + DeclareMatch(ptr, indexed_type, PointerType); + if (ptr->pointed->tag == ListType) { + return Texts("*({ List_t *list = ", compile(env, indexing->indexed), "; LIST_INCREF(*list); list; })"); + } else if (ptr->pointed->tag == TableType || ptr->pointed->tag == SetType) { + return Texts("*({ Table_t *t = ", compile(env, indexing->indexed), "; TABLE_INCREF(*t); t; })"); + } else { + return Texts("*(", compile(env, indexing->indexed), ")"); + } + } + + type_t *container_t = value_type(indexed_type); + type_t *index_t = get_type(env, indexing->index); + if (container_t->tag == ListType) { + if (index_t->tag != IntType && index_t->tag != BigIntType && index_t->tag != ByteType) + 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)), ")"); + } 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), ", ", + compile(env, indexing->index), ", ", + compile_to_type(env, table_type->default_value, table_type->value_type), ", ", + 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), ", ", + compile(env, indexing->index), + ", " + "_, ", + promote_to_optional(table_type->value_type, Text("(*_)")), ", ", + 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)), ")"); + } else { + code_err(ast, "Indexing is not supported for type: ", type_to_str(container_t)); + } +} diff --git a/src/compile/indexing.h b/src/compile/indexing.h new file mode 100644 index 00000000..59b5a3ad --- /dev/null +++ b/src/compile/indexing.h @@ -0,0 +1,8 @@ +// This file defines how to compile indexing like `list[i]` or `ptr[]` +#pragma once + +#include "../ast.h" +#include "../environment.h" +#include "../stdlib/datatypes.h" + +Text_t compile_indexing(env_t *env, ast_t *ast); diff --git a/src/compile/reductions.c b/src/compile/reductions.c index 163b083e..2d7492af 100644 --- a/src/compile/reductions.c +++ b/src/compile/reductions.c @@ -11,6 +11,7 @@ #include "optionals.h" #include "statements.h" +public Text_t compile_reduction(env_t *env, ast_t *ast) { DeclareMatch(reduction, ast, Reduction); ast_e op = reduction->op; |
