[bugfix] VM: finally do inheritance properly
This commit is contained in:
parent
6d125da93f
commit
7606efc0bf
2 changed files with 36 additions and 21 deletions
|
|
@ -1719,19 +1719,24 @@ proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
else:
|
else:
|
||||||
genArrAccess2(c, n, dest, opcLdArr, flags)
|
genArrAccess2(c, n, dest, opcLdArr, flags)
|
||||||
|
|
||||||
proc getNullValueAux(obj: PNode, result: PNode; conf: ConfigRef) =
|
proc getNullValueAux(t: PType; obj: PNode, result: PNode; conf: ConfigRef; currPosition: var int) =
|
||||||
|
if t != nil and t.len > 0 and t.sons[0] != nil:
|
||||||
|
let b = skipTypes(t.sons[0], skipPtrs)
|
||||||
|
getNullValueAux(b, b.n, result, conf, currPosition)
|
||||||
case obj.kind
|
case obj.kind
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
for i in 0 ..< sonsLen(obj): getNullValueAux(obj.sons[i], result, conf)
|
for i in 0 ..< sonsLen(obj): getNullValueAux(nil, obj.sons[i], result, conf, currPosition)
|
||||||
of nkRecCase:
|
of nkRecCase:
|
||||||
getNullValueAux(obj.sons[0], result, conf)
|
getNullValueAux(nil, obj.sons[0], result, conf, currPosition)
|
||||||
for i in 1 ..< sonsLen(obj):
|
for i in 1 ..< sonsLen(obj):
|
||||||
getNullValueAux(lastSon(obj.sons[i]), result, conf)
|
getNullValueAux(nil, lastSon(obj.sons[i]), result, conf, currPosition)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
let field = newNodeI(nkExprColonExpr, result.info)
|
let field = newNodeI(nkExprColonExpr, result.info)
|
||||||
field.add(obj)
|
field.add(obj)
|
||||||
field.add(getNullValue(obj.sym.typ, result.info, conf))
|
field.add(getNullValue(obj.sym.typ, result.info, conf))
|
||||||
addSon(result, field)
|
addSon(result, field)
|
||||||
|
doAssert obj.sym.position == currPosition
|
||||||
|
inc currPosition
|
||||||
else: globalError(conf, result.info, "cannot create null element for: " & $obj)
|
else: globalError(conf, result.info, "cannot create null element for: " & $obj)
|
||||||
|
|
||||||
proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
|
proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
|
||||||
|
|
@ -1759,13 +1764,9 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
|
||||||
of tyObject:
|
of tyObject:
|
||||||
result = newNodeIT(nkObjConstr, info, t)
|
result = newNodeIT(nkObjConstr, info, t)
|
||||||
result.add(newNodeIT(nkEmpty, info, t))
|
result.add(newNodeIT(nkEmpty, info, t))
|
||||||
# initialize inherited fields:
|
# initialize inherited fields, and all in the correct order:
|
||||||
var base = t.sons[0]
|
var currPosition = 0
|
||||||
while base != nil:
|
getNullValueAux(t, t.n, result, conf, currPosition)
|
||||||
let b = skipTypes(base, skipPtrs)
|
|
||||||
getNullValueAux(b.n, result, conf)
|
|
||||||
base = b.sons[0]
|
|
||||||
getNullValueAux(t.n, result, conf)
|
|
||||||
of tyArray:
|
of tyArray:
|
||||||
result = newNodeIT(nkBracket, info, t)
|
result = newNodeIT(nkBracket, info, t)
|
||||||
for i in 0 ..< int(lengthOrd(conf, t)):
|
for i in 0 ..< int(lengthOrd(conf, t)):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
nimout: '''Hello fred , managed by sally
|
nimout: '''Hello fred, managed by sally
|
||||||
Hello sally , managed by bob'''
|
Hello sally, managed by bob
|
||||||
|
0'''
|
||||||
"""
|
"""
|
||||||
# bug #3973
|
# bug #3973
|
||||||
|
|
||||||
|
|
@ -10,20 +11,20 @@ type
|
||||||
ecCode2
|
ecCode2
|
||||||
|
|
||||||
Person* = object of RootObj
|
Person* = object of RootObj
|
||||||
name* : string
|
name*: string
|
||||||
last_name*: string
|
last_name*: string
|
||||||
|
|
||||||
Employee* = object of Person
|
Employee* = object of Person
|
||||||
empl_code* : EmployeeCode
|
empl_code*: EmployeeCode
|
||||||
mgr_name* : string
|
mgr_name*: string
|
||||||
|
|
||||||
proc test() =
|
proc test() =
|
||||||
var
|
var
|
||||||
empl1 = Employee(name: "fred", last_name: "smith", mgr_name: "sally", empl_code: ecCode1)
|
empl1 = Employee(name: "fred", last_name: "smith", mgr_name: "sally", empl_code: ecCode1)
|
||||||
empl2 = Employee(name: "sally", last_name: "jones", mgr_name: "bob", empl_code: ecCode2)
|
empl2 = Employee(name: "sally", last_name: "jones", mgr_name: "bob", empl_code: ecCode2)
|
||||||
|
|
||||||
echo "Hello ", empl1.name, " , managed by ", empl1.mgr_name
|
echo "Hello ", empl1.name, ", managed by ", empl1.mgr_name
|
||||||
echo "Hello ", empl2.name, " , managed by ", empl2.mgr_name
|
echo "Hello ", empl2.name, ", managed by ", empl2.mgr_name
|
||||||
|
|
||||||
static:
|
static:
|
||||||
test()
|
test()
|
||||||
|
|
@ -50,13 +51,13 @@ template check_templ(n: Base, k: MyKind) =
|
||||||
if k == kA: doAssert(n of A) else: doAssert(not (n of A))
|
if k == kA: doAssert(n of A) else: doAssert(not (n of A))
|
||||||
if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B))
|
if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B))
|
||||||
if k == kC: doAssert(n of C) else: doAssert(not (n of C))
|
if k == kC: doAssert(n of C) else: doAssert(not (n of C))
|
||||||
doAssert(n of Base)
|
doAssert(n of Base)
|
||||||
|
|
||||||
proc check_proc(n: Base, k: MyKind) =
|
proc check_proc(n: Base, k: MyKind) =
|
||||||
if k == kA: doAssert(n of A) else: doAssert(not (n of A))
|
if k == kA: doAssert(n of A) else: doAssert(not (n of A))
|
||||||
if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B))
|
if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B))
|
||||||
if k == kC: doAssert(n of C) else: doAssert(not (n of C))
|
if k == kC: doAssert(n of C) else: doAssert(not (n of C))
|
||||||
doAssert(n of Base)
|
doAssert(n of Base)
|
||||||
|
|
||||||
static:
|
static:
|
||||||
let aa = new(A)
|
let aa = new(A)
|
||||||
|
|
@ -68,7 +69,7 @@ static:
|
||||||
let cc = new(C)
|
let cc = new(C)
|
||||||
check_templ(cc, kC)
|
check_templ(cc, kC)
|
||||||
check_proc(cc, kC)
|
check_proc(cc, kC)
|
||||||
|
|
||||||
let aa = new(A)
|
let aa = new(A)
|
||||||
check_templ(aa, kA)
|
check_templ(aa, kA)
|
||||||
check_proc(aa, kA)
|
check_proc(aa, kA)
|
||||||
|
|
@ -78,3 +79,16 @@ check_proc(bb, kB)
|
||||||
let cc = new(C)
|
let cc = new(C)
|
||||||
check_templ(cc, kC)
|
check_templ(cc, kC)
|
||||||
check_proc(cc, kC)
|
check_proc(cc, kC)
|
||||||
|
|
||||||
|
type
|
||||||
|
BBar = object of RootObj
|
||||||
|
bbarField: set[char]
|
||||||
|
xbarField: string
|
||||||
|
d, e: int
|
||||||
|
FooBar = object of BBar
|
||||||
|
a: int
|
||||||
|
b: string
|
||||||
|
|
||||||
|
static:
|
||||||
|
var fb: FooBar
|
||||||
|
echo fb.a
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue