Skip to content

Commit d11399a

Browse files
scolsenTimDeve
andcommitted
feat: add Box.peek
Box.peek allows users to transform a reference to a box into a a reference to the box's contained value. The returned reference will have the same lifetime as the box. This function allows callers to manipulate the value in a box without re-allocation, for example: ```clojure (deftype Num [val Int]) (let-do [box (Box.init (Num.init 0))] (Num.set-val! (Box.peek &box) 1) @(Num.val (Box.peek &box))) ``` This commit also includes tests for Box.peek. Co-authored-by: TimDeve <[email protected]>
1 parent 7cef1a6 commit d11399a

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

src/BoxTemplates.hs

+16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module BoxTemplates
77
BoxTemplates.init,
88
copy,
99
unbox,
10+
peek,
1011
)
1112
where
1213

@@ -56,6 +57,21 @@ unbox = let path = SymPath ["Box"] "unbox"
5657
template = TemplateCreator $ \_ _ -> Template t decl body deps
5758
in defineTypeParameterizedTemplate template path t docs
5859

60+
-- | Defines a template for getting a reference to the value stored in a box without performing an additional allocation.
61+
peek :: (String, Binder)
62+
peek = let path = SymPath ["Box"] "peek"
63+
t = FuncTy [(RefTy (StructTy (ConcreteNameTy (SymPath [] "Box")) [(VarTy "t")]) (VarTy "q"))] (RefTy (VarTy "t") (VarTy "q")) StaticLifetimeTy
64+
docs = "Returns a reference to the value stored in a box without performing an additional allocation."
65+
decl = templateLiteral "$t* $NAME($t** box_ref)"
66+
body = const (multilineTemplate
67+
[ "$DECL {",
68+
" return *box_ref;",
69+
"}"
70+
])
71+
deps = const []
72+
template = TemplateCreator $ \_ _ -> Template t decl body deps
73+
in defineTypeParameterizedTemplate template path t docs
74+
5975
-- | Defines a template for copying a box. The copy will also be heap allocated.
6076
copy :: (String, Binder)
6177
copy =

src/StartingEnv.hs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ boxModule =
124124
bindings = Map.fromList
125125
[ BoxTemplates.init,
126126
BoxTemplates.unbox,
127+
BoxTemplates.peek,
127128
BoxTemplates.delete,
128129
BoxTemplates.copy,
129130
BoxTemplates.prn,

test/box.carp

+11-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33

44
(Debug.sanitize-addresses)
55

6-
(deftest test
7-
(assert-equal test
6+
(deftype Num [val Int])
7+
8+
(deftest test
9+
(assert-equal test
810
&(Box.init @"foo")
911
&(Box.init @"foo")
1012
"init works as expected")
1113
(assert-equal test
1214
2
1315
(Box.unbox (Box.init 2))
1416
"unbox works as expected")
17+
(assert-equal test
18+
1
19+
(let-do [box (Box.init (Num.init 0))]
20+
(Num.set-val! (Box.peek &box) 1)
21+
@(Num.val (Box.peek &box)))
22+
"peek works as expected"
23+
)
1524
)

0 commit comments

Comments
 (0)