mirror of
https://github.com/carp-lang/Carp.git
synced 2024-10-26 05:45:37 +03:00
76 lines
3.7 KiB
Plaintext
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)
|
|
)
|