Skip to content

Commit 6452fa5

Browse files
authored
refactor: move Box from a compiler built-in to a core recursive type (#1571)
1 parent 8e190f2 commit 6452fa5

6 files changed

Lines changed: 76 additions & 314 deletions

File tree

CarpHask.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ library
1818
hs-source-dirs: src
1919
exposed-modules: ArrayTemplates,
2020
AssignTypes,
21-
BoxTemplates,
2221
ColorText,
2322
Commands,
2423
Concretize,

core/Box.carp

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,72 @@
1+
(doc Box
2+
"A heap-allocated, owning box: a single managed value behind one pointer.
3+
4+
`Box` is an ordinary user type that opts into heap indirection via the
5+
`recursive` flag, so it can break value-recursion the same way a built-in
6+
indirection would, e.g.
7+
8+
(deftype IntList (Cons [Int (Box IntList)]) (Nil []))
9+
10+
It is the reference implementation of a `recursive` type.")
11+
(deftype (Box a) [data (Ptr a)])
12+
(recursive Box)
13+
114
(defmodule Box
15+
(hidden heap-alloc)
16+
(deftemplate heap-alloc (Fn [a] (Ptr a)) "$a* $NAME($a v)"
17+
"$DECL { $a* p = CARP_MALLOC(sizeof($a)); *p = v; return p; }")
18+
19+
(hidden heap-free)
20+
(deftemplate heap-free (Fn [(Ptr a)] ()) "void $NAME($a* p)"
21+
"$DECL { CARP_FREE(p); }")
22+
23+
; the value-taking `init` below shadows the generated field constructor
24+
(hidden from-ptr)
25+
(deftemplate from-ptr (Fn [(Ptr a)] (Box a)) "Box__$a $NAME($a* p)"
26+
"$DECL { Box__$a b; b.data = p; return b; }")
27+
28+
(doc init "Initializes a box pointing to value `t`.")
29+
(sig init (Fn [a] (Box a)))
30+
(defn init [value] (Box.from-ptr (Box.heap-alloc value)))
31+
32+
(doc peek
33+
"Returns a reference to the value stored in a box without an allocation.")
34+
(sig peek (Fn [(Ref (Box a) q)] (Ref a q)))
35+
(defn peek [b] (Pointer.to-ref @(Box.data b)))
36+
37+
(doc unbox "Converts a boxed value to a local value, deleting the box.")
38+
(sig unbox (Fn [(Box a)] a))
39+
(defn unbox [b]
40+
(let-do [p @(Box.data &b)
41+
local (Pointer.to-value p)]
42+
(Box.heap-free p)
43+
(Unsafe.leak b)
44+
local))
45+
46+
(doc copy "Copies a box and its contents.")
47+
(sig copy (Fn [(Ref (Box a) q)] (Box a)))
48+
(defn copy [b] (Box.init @(Box.peek b)))
49+
(implements copy Box.copy)
50+
51+
(doc delete "Deletes a box, deleting its contents and freeing its memory.")
52+
(sig delete (Fn [(Box a)] ()))
53+
(defn delete [b]
54+
(let-do [p @(Box.data &b)]
55+
(ignore (Pointer.to-value p))
56+
(Box.heap-free p)))
57+
(implements delete Box.delete)
58+
59+
(doc prn "Returns a string representation of a Box.")
60+
(sig prn (Fn [(Ref (Box a) q)] String))
61+
(defn prn [b] (fmt "(Box %s)" &(prn (Box.peek b))))
62+
(implements prn Box.prn)
63+
64+
(doc str "Returns a string representation of a Box.")
65+
(sig str (Fn [(Ref (Box a) q)] String))
66+
(defn str [b] (Box.prn b))
67+
(implements str Box.str)
68+
69+
(doc = "Equality on boxes, by their contents.")
270
(defn = [box-a box-b]
3-
(= (Box.unbox @box-a) (Box.unbox @box-b)))
4-
(implements = =)
5-
)
71+
(= (Box.peek box-a) (Box.peek box-b)))
72+
(implements = Box.=))

core/Core.carp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
(load-once "Interfaces.carp")
1919
(load-once "Blitable.carp")
2020
(load-once "Bool.carp")
21-
(load-once "Box.carp")
2221
(load-once "Macros.carp")
2322
(load-once "BoolExtras.carp")
2423
(load-once "List.carp")
@@ -48,6 +47,7 @@
4847
(load-once "StdInt.carp")
4948
(load-once "Char.carp")
5049
(load-once "String.carp")
50+
(load-once "Box.carp")
5151
(load-once "ArrayExt.carp")
5252
(load-once "System.carp")
5353
(load-once "IO.carp")

src/BoxTemplates.hs

Lines changed: 0 additions & 271 deletions
This file was deleted.

0 commit comments

Comments
 (0)