aboutsummaryrefslogtreecommitdiff
path: root/src/compile/pointer.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-24 15:29:52 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-24 15:29:52 -0400
commit3f9f82ca53ed353d10ae65fc958e73193e8d9739 (patch)
treecb92b570cd78a015cb62ae5c776d14cad7fe2b22 /src/compile/pointer.c
parent634d1ad756fca46e1e8aec93a265998232dd58a6 (diff)
Move more stuff into structs/enums files
Diffstat (limited to 'src/compile/pointer.c')
-rw-r--r--src/compile/pointer.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/compile/pointer.c b/src/compile/pointer.c
new file mode 100644
index 00000000..50c267b6
--- /dev/null
+++ b/src/compile/pointer.c
@@ -0,0 +1,49 @@
+// Compilation logic
+#include <gc.h>
+#include <glob.h>
+#include <gmp.h>
+#include <uninorm.h>
+
+#include "../ast.h"
+#include "../compile.h"
+#include "../config.h"
+#include "../environment.h"
+#include "../stdlib/text.h"
+#include "../typecheck.h"
+#include "list.h"
+
+Text_t compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bool needs_incref) {
+ Text_t val = compile(env, ast);
+ type_t *t = get_type(env, ast);
+ int64_t depth = 0;
+ for (type_t *tt = t; tt->tag == PointerType; tt = Match(tt, PointerType)->pointed)
+ ++depth;
+
+ // Passing a literal value won't trigger an incref, because it's ephemeral,
+ // e.g. [10, 20].reversed()
+ if (t->tag != PointerType && needs_incref && !can_be_mutated(env, ast)) needs_incref = false;
+
+ while (depth != target_depth) {
+ if (depth < target_depth) {
+ if (ast->tag == Var && target_depth == 1) val = Texts("(&", val, ")");
+ else code_err(ast, "This should be a pointer, not ", type_to_str(get_type(env, ast)));
+ t = Type(PointerType, .pointed = t, .is_stack = true);
+ ++depth;
+ } else {
+ DeclareMatch(ptr, t, PointerType);
+ val = Texts("*(", val, ")");
+ t = ptr->pointed;
+ --depth;
+ }
+ }
+
+ while (t->tag == PointerType) {
+ DeclareMatch(ptr, t, PointerType);
+ t = ptr->pointed;
+ }
+
+ if (needs_incref && t->tag == ListType) val = Texts("LIST_COPY(", val, ")");
+ else if (needs_incref && (t->tag == TableType || t->tag == SetType)) val = Texts("TABLE_COPY(", val, ")");
+
+ return val;
+}