diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 15:32:17 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 15:32:17 -0400 |
| commit | c62c3200c7078f58b218def14c54bbfd26677069 (patch) | |
| tree | b4e2d4b943ca3a63a95d6e516ff5bb45a46f238e /src/compile/pointers.c | |
| parent | 3f9f82ca53ed353d10ae65fc958e73193e8d9739 (diff) | |
Pluralize filenames
Diffstat (limited to 'src/compile/pointers.c')
| -rw-r--r-- | src/compile/pointers.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/compile/pointers.c b/src/compile/pointers.c new file mode 100644 index 00000000..cb11844d --- /dev/null +++ b/src/compile/pointers.c @@ -0,0 +1,48 @@ +// 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" + +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; +} |
