code / tomo

Lines41.3K C23.7K Markdown9.7K YAML5.0K Tomo2.3K
7 others 763
Python231 Shell230 make212 INI47 Text21 SVG16 Lua6
(69 lines)
1 // This file defines how to compile pointers and allocated memory
3 #include <gc.h>
4 #include <glob.h>
5 #include <gmp.h>
6 #include <uninorm.h>
8 #include "../ast.h"
9 #include "../config.h"
10 #include "../environment.h"
11 #include "../stdlib/text.h"
12 #include "../typecheck.h"
13 #include "compilation.h"
15 public
16 Text_t compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bool needs_incref) {
17 Text_t val = compile(env, ast);
18 type_t *t = get_type(env, ast);
19 int64_t depth = 0;
20 for (type_t *tt = t; tt->tag == PointerType; tt = Match(tt, PointerType)->pointed)
21 ++depth;
23 // Passing a literal value won't trigger an incref, because it's ephemeral,
24 // e.g. [10, 20].reversed()
25 if (t->tag != PointerType && needs_incref && !can_be_mutated(env, ast)) needs_incref = false;
27 while (depth != target_depth) {
28 if (depth < target_depth) {
29 if (ast->tag == Var && target_depth == 1) val = Texts("(&", val, ")");
30 else code_err(ast, "This should be a pointer, not ", type_to_text(get_type(env, ast)));
31 t = Type(PointerType, .pointed = t, .is_stack = true);
32 ++depth;
33 } else {
34 DeclareMatch(ptr, t, PointerType);
35 val = Texts("*(", val, ")");
36 t = ptr->pointed;
37 --depth;
41 while (t->tag == PointerType) {
42 DeclareMatch(ptr, t, PointerType);
43 t = ptr->pointed;
46 if (needs_incref && t->tag == ListType) val = Texts("LIST_COPY(", val, ")");
47 else if (needs_incref && t->tag == TableType) val = Texts("TABLE_COPY(", val, ")");
49 return val;
52 public
53 Text_t compile_typed_allocation(env_t *env, ast_t *ast, type_t *pointer_type) {
54 // TODO: for constructors, do new(T, ...) instead of heap((T){...})
55 type_t *pointed = Match(pointer_type, PointerType)->pointed;
56 switch (ast->tag) {
57 case HeapAllocate: {
58 return Texts("heap(", compile_maybe_incref(env, Match(ast, HeapAllocate)->value, pointed), ")");
60 case StackReference: {
61 ast_t *subject = Match(ast, StackReference)->value;
62 if (can_be_mutated(env, subject) && type_eq(pointed, get_type(env, subject)))
63 return Texts("(&", compile_lvalue(env, subject), ")");
64 else return Texts("stack(", compile_maybe_incref(env, subject, pointed), ")");
66 default: code_err(ast, "Not an allocation!");
68 return EMPTY_TEXT;