Are there any way? Thanks!
{.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:untyped,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
type S = object
x:int
classProc(S):
proc f() =
echo self.x
var s = S(x:2021)
s.f()
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()
Thanks! I am reading the code. Is the following code example of member proc?
https://github.com/beef331/constructor/blob/master/tests/objtest.nim