Fix defining a constructor proc inside class (#45)
This commit is contained in:
parent
0d0aaa7e29
commit
775e950be5
1 changed files with 31 additions and 6 deletions
|
|
@ -55,7 +55,7 @@ macro class*(head, body: untyped): untyped =
|
||||||
# --------------------
|
# --------------------
|
||||||
# Ident !"Animal"
|
# Ident !"Animal"
|
||||||
typeName = head
|
typeName = head
|
||||||
baseName = ident("RootObj")
|
baseName = newIdentNode("RootObj")
|
||||||
|
|
||||||
elif head.kind == nnkInfix and $head[0] == "of":
|
elif head.kind == nnkInfix and $head[0] == "of":
|
||||||
# `head` is expression `typeName of baseClass`
|
# `head` is expression `typeName of baseClass`
|
||||||
|
|
@ -137,16 +137,20 @@ macro class*(head, body: untyped): untyped =
|
||||||
# var declarations will be turned into object fields
|
# var declarations will be turned into object fields
|
||||||
var recList = newNimNode(nnkRecList)
|
var recList = newNimNode(nnkRecList)
|
||||||
|
|
||||||
|
# expected name of constructor
|
||||||
|
let ctorName = newIdentNode("new" & $typeName)
|
||||||
|
|
||||||
# Iterate over the statements, adding `this: T`
|
# Iterate over the statements, adding `this: T`
|
||||||
# to the parameters of functions
|
# to the parameters of functions, unless the
|
||||||
|
# function is a constructor
|
||||||
for node in body.children:
|
for node in body.children:
|
||||||
case node.kind:
|
case node.kind:
|
||||||
|
|
||||||
of nnkMethodDef, nnkProcDef:
|
of nnkMethodDef, nnkProcDef:
|
||||||
|
# make sure it is not the constructor
|
||||||
|
if node.name.basename != ctorName:
|
||||||
# inject `this: T` into the arguments
|
# inject `this: T` into the arguments
|
||||||
let p = copyNimTree(node.params)
|
node.params.insert(1, newIdentDefs(ident("this"), typeName))
|
||||||
p.insert(1, newIdentDefs(ident("this"), typeName))
|
|
||||||
node.params = p
|
|
||||||
result.add(node)
|
result.add(node)
|
||||||
|
|
||||||
of nnkVarSection:
|
of nnkVarSection:
|
||||||
|
|
@ -190,6 +194,16 @@ macro class*(head, body: untyped): untyped =
|
||||||
#
|
#
|
||||||
# method age_human_yrs(this: Animal): int {.base.} =
|
# method age_human_yrs(this: Animal): int {.base.} =
|
||||||
# this.age
|
# this.age
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
# type
|
||||||
|
# Rabbit = ref object of Animal
|
||||||
|
#
|
||||||
|
# proc newRabbit(name: string; age: int): Rabbit =
|
||||||
|
# result = Rabbit(name: name, age: age)
|
||||||
|
#
|
||||||
|
# method vocalize(this: Rabbit): string =
|
||||||
|
# "meep"
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
|
|
||||||
|
|
@ -206,6 +220,11 @@ class Dog of Animal:
|
||||||
class Cat of Animal:
|
class Cat of Animal:
|
||||||
method vocalize: string = "meow"
|
method vocalize: string = "meow"
|
||||||
|
|
||||||
|
class Rabbit of Animal:
|
||||||
|
proc newRabbit(name: string, age: int): Rabbit =
|
||||||
|
result = Rabbit(name: name, age: age)
|
||||||
|
method vocalize: string = "meep"
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
|
|
||||||
var animals: seq[Animal] = @[]
|
var animals: seq[Animal] = @[]
|
||||||
|
|
@ -215,6 +234,10 @@ animals.add(Cat(name: "Mitten", age: 10))
|
||||||
for a in animals:
|
for a in animals:
|
||||||
echo a.vocalize()
|
echo a.vocalize()
|
||||||
echo a.age_human_yrs()
|
echo a.age_human_yrs()
|
||||||
|
|
||||||
|
let r = newRabbit("Fluffy", 3)
|
||||||
|
echo r.vocalize()
|
||||||
|
echo r.age_human_yrs()
|
||||||
```
|
```
|
||||||
``` console
|
``` console
|
||||||
$ nim c -r oopmacro.nim
|
$ nim c -r oopmacro.nim
|
||||||
|
|
@ -222,4 +245,6 @@ woof
|
||||||
70
|
70
|
||||||
meow
|
meow
|
||||||
10
|
10
|
||||||
|
meep
|
||||||
|
3
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue