Fix defining a constructor proc inside class (#45)

This commit is contained in:
konqoro 2016-11-13 17:48:54 +02:00 • committed by Flaviu Tamas
commit 775e950be5

View file

@ -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
``` ```