fixes #304
This commit is contained in:
parent
65319ba22d
commit
0761b449ed
3 changed files with 50 additions and 25 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -14,10 +14,6 @@ import
|
||||||
ast, astalgo, msgs, semdata, types, trees
|
ast, astalgo, msgs, semdata, types, trees
|
||||||
|
|
||||||
proc equalGenericParams(procA, procB: PNode): bool =
|
proc equalGenericParams(procA, procB: PNode): bool =
|
||||||
var a, b: PSym
|
|
||||||
result = procA == procB
|
|
||||||
if result: return
|
|
||||||
if (procA == nil) or (procB == nil): return
|
|
||||||
if sonsLen(procA) != sonsLen(procB): return
|
if sonsLen(procA) != sonsLen(procB): return
|
||||||
for i in countup(0, sonsLen(procA) - 1):
|
for i in countup(0, sonsLen(procA) - 1):
|
||||||
if procA.sons[i].kind != nkSym:
|
if procA.sons[i].kind != nkSym:
|
||||||
|
|
@ -26,11 +22,11 @@ proc equalGenericParams(procA, procB: PNode): bool =
|
||||||
if procB.sons[i].kind != nkSym:
|
if procB.sons[i].kind != nkSym:
|
||||||
InternalError(procB.info, "equalGenericParams")
|
InternalError(procB.info, "equalGenericParams")
|
||||||
return
|
return
|
||||||
a = procA.sons[i].sym
|
let a = procA.sons[i].sym
|
||||||
b = procB.sons[i].sym
|
let b = procB.sons[i].sym
|
||||||
if (a.name.id != b.name.id) or
|
if a.name.id != b.name.id or
|
||||||
not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return
|
not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return
|
||||||
if (a.ast != nil) and (b.ast != nil):
|
if a.ast != nil and b.ast != nil:
|
||||||
if not ExprStructuralEquivalent(a.ast, b.ast): return
|
if not ExprStructuralEquivalent(a.ast, b.ast): return
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
|
@ -39,10 +35,23 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym =
|
||||||
# the same the sym in the symbol table is returned, else nil.
|
# the same the sym in the symbol table is returned, else nil.
|
||||||
var it: TIdentIter
|
var it: TIdentIter
|
||||||
result = initIdentIter(it, c.tab.stack[tos], fn.Name)
|
result = initIdentIter(it, c.tab.stack[tos], fn.Name)
|
||||||
|
if isGenericRoutine(fn):
|
||||||
|
# we simply check the AST; this is imprecise but nearly the best what
|
||||||
|
# can be done; this doesn't work either though as type constraints are
|
||||||
|
# not kept in the AST ..
|
||||||
while result != nil:
|
while result != nil:
|
||||||
if (result.Kind == fn.kind):
|
if result.Kind == fn.kind and isGenericRoutine(result):
|
||||||
if equalGenericParams(result.ast.sons[genericParamsPos],
|
let genR = result.ast.sons[genericParamsPos]
|
||||||
fn.ast.sons[genericParamsPos]):
|
let genF = fn.ast.sons[genericParamsPos]
|
||||||
|
if ExprStructuralEquivalent(genR, genF) and
|
||||||
|
ExprStructuralEquivalent(result.ast.sons[paramsPos],
|
||||||
|
fn.ast.sons[paramsPos]) and
|
||||||
|
equalGenericParams(genR, genF):
|
||||||
|
return
|
||||||
|
result = NextIdentIter(it, c.tab.stack[tos])
|
||||||
|
else:
|
||||||
|
while result != nil:
|
||||||
|
if result.Kind == fn.kind and not isGenericRoutine(result):
|
||||||
case equalParams(result.typ.n, fn.typ.n)
|
case equalParams(result.typ.n, fn.typ.n)
|
||||||
of paramsEqual:
|
of paramsEqual:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,11 @@ template t() = echo(foo)
|
||||||
|
|
||||||
var foo = 12
|
var foo = 12
|
||||||
t()
|
t()
|
||||||
|
|
||||||
|
|
||||||
|
template test_in(a, b, c: expr): bool {.immediate, dirty.} =
|
||||||
|
var result {.gensym.}: bool = false
|
||||||
|
false
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
assert test_in(ret2, "test", str_val)
|
||||||
|
|
|
||||||
|
|
@ -25,3 +25,11 @@ var x = stdin.readline.split.map(parseInt).max
|
||||||
echo x, " is the maximum!"
|
echo x, " is the maximum!"
|
||||||
echo "another number: ", takeParseInt(parseInt)
|
echo "another number: ", takeParseInt(parseInt)
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TFoo[a,b] = object
|
||||||
|
lorem: a
|
||||||
|
ipsum: b
|
||||||
|
|
||||||
|
proc bar[a,b](f: TFoo[a,b], x: a) = echo(x, " ", f.lorem, f.ipsum)
|
||||||
|
proc bar[a,b](f: TFoo[a,b], x: b) = echo(x, " ", f.lorem, f.ipsum)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue