I'm working on a parsing application and I have to deal with both terminal and 
non-terminal nodes in the model. The terminal nodes (tokens) can have values of 
different types, expressed as an object variant: 
    
    
    type
      TokenKind = enum
        IntegerNumber,
        FloatNumber,
        StringToken,
        Plus,
        Minus,
        Multiply,
        Divide,
        #...
      
      Location = object
        line : int
        column : int
      
      TokenValue = object
        case kind: TokenKind
        of FloatNumber: floatValue: float64
        of StringToken: stringValue: string
        else: intValue: int64
      
      Token = ref object of RootObj
        text: string
        value: TokenValue
    
    
    Run

But the non-terminal nodes also have a "kind-of", for example 
    
    
    type
      ASTNode = ref object of RootObj
        kind: TokenKind  # could be Plus, Minus, etc.
        startpos: Location
        endpos: Location
       
       # ...
      
      BinaryNode = ref object of ASTNode
        lhs, rhs: ASTNode
    
    
    Run

I'd like to unify `ASTNode` and `Token` so that `Token` inherits from 
`ASTNode`, but the `kind` is already "embedded" in the `TokenValue`. To unify 
the two things, does that mean that storage for `kind` would be duplicated (one 
in the `ASTNode`, one in the `TokenValue`), or is there some way of avoiding 
this by somehow disconnecting the discriminator field from the discriminated 
fields?

Reply via email to