mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-06 04:57:49 +00:00
allowing definitions of procs and templates to be overridden in local scopes
This commit is contained in:
@@ -164,7 +164,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||
result = nil
|
||||
if result != nil and result.kind == skStub: loadStub(result)
|
||||
|
||||
proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||
proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||
case n.kind
|
||||
of nkIdent, nkAccQuoted:
|
||||
var ident = considerAcc(n)
|
||||
@@ -174,7 +174,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||
dec(o.stackPtr)
|
||||
if o.stackPtr < 0: break
|
||||
result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], ident)
|
||||
of nkSym:
|
||||
of nkSym:
|
||||
result = n.sym
|
||||
o.mode = oimDone
|
||||
of nkDotExpr:
|
||||
@@ -204,6 +204,13 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||
Incl(o.inSymChoice, result.id)
|
||||
else: nil
|
||||
if result != nil and result.kind == skStub: loadStub(result)
|
||||
|
||||
proc lastOverloadScope*(o: TOverloadIter): int =
|
||||
case o.mode
|
||||
of oimNoQualifier: result = o.stackPtr
|
||||
of oimSelfModule: result = ModuleTablePos
|
||||
of oimOtherModule: result = ImportTablePos
|
||||
else: result = -1
|
||||
|
||||
proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||
case o.mode
|
||||
|
||||
@@ -36,14 +36,15 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||
template best: expr = result
|
||||
#Message(n.info, warnUser, renderTree(n))
|
||||
var sym = initOverloadIter(o, c, f)
|
||||
var symScope = o.lastOverloadScope
|
||||
|
||||
if sym == nil: return
|
||||
initCandidate(best, sym, initialBinding)
|
||||
initCandidate(alt, sym, initialBinding)
|
||||
if sym == nil: return
|
||||
initCandidate(best, sym, initialBinding, symScope)
|
||||
initCandidate(alt, sym, initialBinding, symScope)
|
||||
|
||||
while sym != nil:
|
||||
if sym.kind in filter:
|
||||
initCandidate(z, sym, initialBinding)
|
||||
initCandidate(z, sym, initialBinding, o.lastOverloadScope)
|
||||
z.calleeSym = sym
|
||||
matches(c, n, orig, z)
|
||||
if z.state == csMatch:
|
||||
|
||||
@@ -27,6 +27,7 @@ type
|
||||
state*: TCandidateState
|
||||
callee*: PType # may not be nil!
|
||||
calleeSym*: PSym # may be nil
|
||||
calleeScope: int # may be -1 for unknown scope
|
||||
call*: PNode # modified call
|
||||
bindings*: TIdTable # maps types to types
|
||||
baseTypeMatch: bool # needed for conversions from T to openarray[T]
|
||||
@@ -60,9 +61,10 @@ proc put(t: var TIdTable, key, val: PType) {.inline.} =
|
||||
IdentEq(val.sym.name, "TTable"):
|
||||
assert false
|
||||
|
||||
proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode) =
|
||||
proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode, calleeScope = -1) =
|
||||
initCandidateAux(c, callee.typ)
|
||||
c.calleeSym = callee
|
||||
c.calleeScope = calleeScope
|
||||
initIdTable(c.bindings)
|
||||
if binding != nil:
|
||||
var typeParams = callee.ast[genericParamsPos]
|
||||
@@ -94,6 +96,9 @@ proc cmpCandidates*(a, b: TCandidate): int =
|
||||
result = a.intConvMatches - b.intConvMatches
|
||||
if result != 0: return
|
||||
result = a.convMatches - b.convMatches
|
||||
if result != 0: return
|
||||
if (a.calleeScope != -1) and (b.calleeScope != -1):
|
||||
result = a.calleeScope - b.calleeScope
|
||||
|
||||
proc writeMatches(c: TCandidate) =
|
||||
Writeln(stdout, "exact matches: " & $c.exactMatches)
|
||||
|
||||
Reference in New Issue
Block a user