Wednesday, July 26, 2023

Referencing and Dereferencing in Nim



Here is an executable guide to how referencing and dereferencing work in Nim. I made this to understand it myself, because there is no explanation in the online manual or either book on Nim.

******************


type
refInt = ref int
var
a: int = 1
b: refInt
c: refInt
d: refInt


# UPDATE
# Use this template to make referencing much easier!

template `-->` [T](receiver: ref T, target: T)=
receiver = cast[ref type(target)](target.addr)

echo a
echo "a ", a.addr.repr
# Sadly, the Nim 2.0.0 update removed the physical addresses from repr
new(b)
b[] = a
echo b[]
echo "b ", b.addr.repr
a = 2
echo a
echo "a ", a.addr.repr
echo b[]
b = cast[ref int](alloc0(sizeOf(a))) # primitive, use new(b) instead
b[] = a
echo b[]
echo "b ", b.addr.repr
a = 3
echo a
echo b[]
b = cast[ref int](a.addr) # this works!
echo b[]
new(c)
c = b
echo "c ", c[]
a = 4
echo "a ", a
echo b[]
echo c[]
echo type(c)
echo "a ", a.addr.repr
echo "b ", b.addr.repr
echo "c ", c.addr.repr
echo ""

var x: array[5, int]
type ArrRef = ref array[5, int]
var y, z : ArrRef
x = [1, 2, 3, 4, 5]
y = cast[ArrRef](x.addr)
# addr provides a ptr type
# cast to convert ptr to ref
z = y
echo "x ", x, " is ", x.addr.repr
# repr is a lower-level version of the $ to-string operator
echo "y ", y[], " is ", y.addr.repr
# [] is dereference, so c[] --> b
echo "z ", z[], " is ", z.addr.repr
echo ""
z[4] = 10
echo "x ", x, " is ", x.addr.repr
echo "y ", y[], " is ", y.addr.repr
echo "z ", z[], " is ", z.addr.repr
new(z)
# use new() to allocate space for the value to be referenced
z[] = x
z[4] = 20
echo ""
echo "x ", x, " is ", x.addr.repr
echo "y ", y[], " is ", y.addr.repr
echo "z ", z[], " is ", z.addr.repr
# only z is now [1, 2, 3, 4, 20]

var q: ArrRef
q --> x



No comments:

Post a Comment

I reserve the right to remove egregiously profane or abusive comments, spam, and anything else that really annoys me. Feel free to agree or disagree, but let's keep this reasonably civil.