aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-24 18:21:39 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-24 18:21:39 -0400
commit74e8aa30901dba029f3e39d187337a09740db4e0 (patch)
treeb17b37dec809aa9c054ab7d82bfe4a52fe5c4fab /src
parent7e5e03f191c4379bf7e34cccfa044ec928189eed (diff)
Move indexing into its own file
Diffstat (limited to 'src')
-rw-r--r--src/compile/expressions.c64
-rw-r--r--src/compile/indexing.c78
-rw-r--r--src/compile/indexing.h8
-rw-r--r--src/compile/reductions.c1
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;