Hmm... I see your point. But then how would I be able to store an object's 
address? (perhaps, the solution would be to use no GC whatsoever which is 
pretty much what I'm doing?)

Btw... here is an experimental implementation of NaN-tagging I've just written 
(roughly based on this article: 
[https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-representations.html)](https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-representations.html\)).
 I believe it's working though I haven't had time to thoroughly test it.

**Code:**
    
    
    import bitops
    
    type
        ObjType = enum
            strObj, arrObj
        
        Obj = ref object
            case kind: ObjType:
                of strObj: s: string
                of arrObj: a: seq[Obj]
        
        Val {.final,union,pure.} = object
            asDouble: float64
            asBits: int64
    
    const MaxDouble     = cast[int64](0xfff8000000000000)
    const Int32Tag      = cast[int64](0xfff9000000000000)
    const PtrTag        = cast[int64](0xfffa000000000000)
    
    proc newVal(num:int64): Val {.inline.} =
        Val(asBits: bitor(num,Int32Tag))
    
    proc newVal(num: float64): Val {.inline.} =
        Val(asDouble:num)
    
    proc newVal(obj: Obj): Val {.inline.} =
        Val(asBits: bitor(cast[int64](obj),PtrTag))
    
    proc isDouble(v: Val): bool {.inline.} =
        v.asBits < MaxDouble
    
    proc isInt32(v: Val): bool {.inline.} =
        bitand(v.asBits,Int32Tag) == Int32Tag
    
    proc isObj(v: Val): bool {.inline.} =
        bitand(v.asBits,PtrTag) == PtrTag
    
    proc getDouble(v: Val): float64 {.inline.} =
        v.asDouble
    
    proc getInt32(v: Val): int32 {.inline.} =
        cast[int32](bitand(v.asBits,bitnot(Int32Tag)))
    
    proc getObj(v: Val): Obj {.inline.} =
        result = cast[Obj](bitand(v.asBits,bitNot(PtrTag)))
    
    let a = newVal(32)
    echo a.getInt32()
    
    let b = newVal(34.53)
    echo b.getDouble()
    
    let c = newVal(Obj(kind:strObj, s:"hello"))
    echo c.getObj().s
    
    
    Run

**Output:**
    
    
    32
    34.53
    hello
    
    
    Run

Reply via email to