Carp/core/Pointer.carp
2021-07-05 14:48:35 +02:00

76 lines
3.7 KiB
Plaintext

(doc Pointer "is a data type for representing C pointers.")
(defmodule Pointer
(doc eq "checks two pointers for equality.")
(deftemplate eq (Fn [(Ptr p) (Ptr p)] Bool) "bool $NAME($p *p1, $p *p2)" " $DECL { return p1 == p2; }")
(implements = Pointer.eq)
(doc eq "checks two pointer references for equality.")
(deftemplate ref-eq (Fn [(Ref (Ptr p)) (Ref (Ptr p))] Bool) "bool $NAME($p **p1, $p **p2)" " $DECL { return *p1 == *p2; }")
(implements = Pointer.ref-eq)
(doc address "returns the memory address of a reference. Equivalent to the `&` operator when placed before a variable in C.")
(deftemplate address (Fn [(Ref a)] (Ptr a)) "$a * $NAME($a * a)" "$DECL { return a; }")
(doc to-ref "converts a pointer to a reference type.
The user will have to ensure themselves that this is a safe operation.")
(deftemplate to-ref (Fn [(Ptr p)] (Ref p)) "$p* $NAME($p* p)" " $DECL { return p; }")
(doc to-value "converts a pointer to a value.
The user will have to ensure themselves that this is a safe operation.")
(deftemplate to-value (Fn [(Ptr p)] p) "$p $NAME($p* p)" " $DECL { return *p; }")
(doc add "adds a long integer value to a pointer.")
(deftemplate add (Fn [(Ptr p) Long] (Ptr p)) "$p* $NAME($p* p, Long x)" " $DECL { return p + x; }")
(doc sub "subtracts a long integer value from a pointer.")
(deftemplate sub (Fn [(Ptr p) Long] (Ptr p)) "$p* $NAME($p* p, Long x)" " $DECL { return p - x; }")
(doc width "gets the byte size of a pointer.")
(deftemplate width (Fn [(Ptr p)] Long) "Long $NAME($p* p)" " $DECL { return sizeof(*p); }")
(doc to-long "converts a pointer to a long integer.")
(deftemplate to-long (Fn [(Ptr p)] Long) "Long $NAME($p* p)" " $DECL { return (Long)p; }")
(doc from-long "converts a long integer to a pointer.")
(deftemplate from-long (Fn [Long] (Ptr p)) "$p* $NAME(Long p)" " $DECL { return ($p*)p; }")
(doc unsafe-set
"Sets the value of a pointer to a value of any type."
"The user will have to ensure this operation is safe.")
(deftemplate unsafe-set (Fn [(Ptr p) a] Unit) "void $NAME($p* p, $a a)" "$DECL { *p = ($p)a; }")
(doc unsafe-alloc
"Allocate a new pointer to the value `a`."
("This pointer won't be managed by Carp's borrow checker and will cause " false)
"memory leaks unless explicitly freed using `Pointer.free`."
""
("See `Unsafe.leak` if you want to prevent Carp's automatic memory management " false)
"from deallocating a value without performing an allocation."
""
"```"
"(let-do [x (Pointer.unsafe-alloc @\"c\")]"
" (Pointer.set x @\"carp\")"
" (println* (Pointer.to-value x))"
" (Pointer.free x))"
"```")
(deftemplate unsafe-alloc (Fn [a] (Ptr a)) "$a* $NAME($a r)" "$DECL { void *leak = CARP_MALLOC(sizeof($a)); *($a*)leak= r; return ($a*)leak;}")
(doc free
"Free a pointer, deallocating the memory associated with it."
("Carp's borrow checker handles deallocation automatically for managed types. " false)
("The Ptr type is unmanaged, so pointers allocated with functions " false)
"such as `Pointer.unsafe-alloc` need to be deallocated manually using this function."
"Users need to manually verify that this operation is safe."
""
"```"
"(let-do [x (Pointer.unsafe-alloc @\"c\")]"
" (Pointer.set x @\"carp\")"
" (println* (Pointer.to-value x))"
" (Pointer.free x))"
"```")
(deftemplate free (Fn [(Ptr p)] Unit) "void $NAME($p* p)" "$DECL {CARP_FREE(p);}")
(doc set "Sets the value of a pointer.")
(deftemplate set (Fn [(Ptr p) p] Unit) "void $NAME($p* p, $p a)" "$DECL { *p = a; }")
(defn inc [a] (Pointer.add a 1l))
(implements inc Pointer.inc)
(defn dec [a] (Pointer.sub a 1l))
(implements dec Pointer.dec)
)