nondescript/src/ndspkg/types/closure.nim

58 lines
1.5 KiB
Nim

import strformat
import strutils
type
UpvalueObj[T] = object
location*: ptr T
next*: Upvalue[T]
closed*: T
Upvalue*[T] = ptr UpvalueObj[T]
ClosureObj[T] = object
start: ptr uint8
upvalueCount*: int
upvalues: UncheckedArray[Upvalue[T]]
Closure*[T] = ptr ClosureObj[T]
proc newClosure*[T](start: ptr uint8, upvalueCount: int): Closure[T] =
result = cast[Closure[T]](alloc0(8 * upvalueCount + sizeof(ClosureObj[T])))
result.start = start
result.upvalueCount = upvalueCount
for i in 0 .. upvalueCount:
result.upvalues[i] = nil
proc getIp*[T](clos: Closure[T]): ptr uint8 =
clos.start
proc set*[T](clos: Closure[T], index: int, val: Upvalue[T]) =
clos.upvalues[index] = val
proc get*[T](clos: Closure[T], index: int): Upvalue[T] =
clos.upvalues[index]
proc debugStr*[T](clos: Closure[T]): string =
let addrUint: uint = cast[uint](clos.start)
let addrStr: string = addrUint.toHex()
let upvalCountStr: string = $clos.upvalueCount
result = &"Closure(start: {addrStr}, length: {upvalCountStr}, upvalues: "
mixin `$`
for i in 0 .. clos.upvalueCount-1:
if clos.upvalues[i] != nil:
let upvalStr = $(clos.upvalues[i].location[])
result &= &"{upvalStr}, "
else:
result &= "<unset>, "
result &= ")"
proc newUpvalue*[T](location: ptr T): Upvalue[T] =
result = cast[Upvalue[T]](alloc0(sizeof(UpvalueObj[T])))
result.location = location
result.next = nil
proc read*[T](upval: Upvalue[T]): T =
upval.location[]
proc write*[T](upval: Upvalue[T], val: T) =
upval.location[]= val