As much as I dislike the emulating of classes in Nim here is usable version for 
only `object` types. 
    
    
    {.experimental.}
    import macros
    
    proc convertToMemberProc( procDefNode:NimNode, className:string ) =
      var formalParamsNode = procDefNode[3]
      formalParamsNode.expectKind( nnkFormalParams )
      var selfIdentNode = newIdentDefs( ident("self"), ident(className))
      formalParamsNode.insert( 1, selfIdentNode )
    
    type TraverseOp = enum Continue, Break, SkipChild, SkipSibling, Finished
    
    proc traverse(n: NimNode; action:proc(n:NimNode;parents:ref 
seq[NimNode]):TraverseOp; parents:ref seq[NimNode] = nil ):TraverseOp 
{.discardable.} =
      var parents = parents
      if parents == nil:
        parents.new
        parents.newseq( 0 )
      parents.add( n )
      
      for it in n.children:
        case action( it, parents )
        of Continue: discard
        of Break: return Break
        of SkipSibling: return SkipSibling
        of SkipChild: continue
        else: assert false
        
        case traverse( it, action, parents )
        of Break: return Break
        else: discard
      return Finished
    
    
    macro classproc(className: typed,stmtList:untyped):untyped=
      var classNameStr = `$`(className)
      stmtList.traverse do (n:NimNode;parents:ref seq[NimNode]) -> TraverseOp:
        case n.kind
        of nnkProcDef, nnkMethodDef, nnkIteratorDef:
          n.convertToMemberProc( classNameStr )
        else: discard
      result = stmtList
      echo className.getImpl()[2][2].treeRepr
      for def in classname.getImpl()[2][2]:
        for ident in def[0..^3]:
          result.insert 0, quote do:
            template `ident`(): untyped = self.`ident`
      
      
      echo result.repr
    
    
    type S = object
      x:int
    
    classProc(S):
      proc f() =
        echo x
      
      var s = S(x:2021)
      s.f()
    
    
    Run

Reply via email to