diff options
-rw-r--r-- | compiler/lookups.nim | 64 | ||||
-rw-r--r-- | compiler/sem.nim | 1 | ||||
-rw-r--r-- | compiler/semdata.nim | 2 |
3 files changed, 39 insertions, 28 deletions
diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 36f5a00b9..cd0608357 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -45,11 +45,15 @@ proc addUniqueSym*(scope: PScope, s: PSym): TResult = result = Success proc openScope*(c: PContext): PScope {.discardable.} = - c.currentScope = PScope(parent: c.currentScope, symbols: newStrTable()) - result = c.currentScope + inc c.scopeDepth + result = PScope(parent: c.currentScope, + symbols: newStrTable(), + depthLevel: c.scopeDepth) + c.currentScope = result proc rawCloseScope*(c: PContext) = c.currentScope = c.currentScope.parent + dec c.scopeDepth proc closeScope*(c: PContext) = ensureNoMissingOrUnusedSymbols(c.currentScope) @@ -96,10 +100,11 @@ type oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, oimSymChoice, oimSymChoiceLocalLookup TOverloadIter*{.final.} = object - stackPtr*: int it*: TIdentIter m*: PSym mode*: TOverloadIterMode + symChoiceIndex*: int + scope*: PScope inSymChoice: TIntSet proc getSymRepr*(s: PSym): string = @@ -241,12 +246,15 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerAcc(n) - o.stackPtr = c.tab.tos + o.scope = c.currentScope o.mode = oimNoQualifier - while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], ident) + while true: + result = InitIdentIter(o.it, o.scope.symbols, ident) + if result != nil: + break + else: + o.scope = o.scope.parent + if o.scope == nil: break of nkSym: result = n.sym o.mode = oimDone @@ -273,7 +281,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = of nkClosedSymChoice, nkOpenSymChoice: o.mode = oimSymChoice result = n.sons[0].sym - o.stackPtr = 1 + o.symChoiceIndex = 1 o.inSymChoice = initIntSet() Incl(o.inSymChoice, result.id) else: nil @@ -281,7 +289,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = proc lastOverloadScope*(o: TOverloadIter): int = case o.mode - of oimNoQualifier: result = o.stackPtr + of oimNoQualifier: result = o.scope.depthLevel of oimSelfModule: result = 1 of oimOtherModule: result = 0 else: result = -1 @@ -291,12 +299,12 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = of oimDone: result = nil of oimNoQualifier: - if o.stackPtr >= 0: - result = nextIdentIter(o.it, c.tab.stack[o.stackPtr]) - while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], o.it.name) + if o.scope != nil: + result = nextIdentIter(o.it, o.scope.symbols) + while result == nil: + o.scope = o.scope.parent + if o.scope == nil: break + result = InitIdentIter(o.it, o.scope.symbols, o.it.name) # BUGFIX: o.it.name <-> n.ident else: result = nil @@ -305,27 +313,27 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = of oimOtherModule: result = nextIdentIter(o.it, o.m.tab) of oimSymChoice: - if o.stackPtr < sonsLen(n): - result = n.sons[o.stackPtr].sym + if o.symChoiceIndex < sonsLen(n): + result = n.sons[o.symChoiceIndex].sym Incl(o.inSymChoice, result.id) - inc(o.stackPtr) + inc o.symChoiceIndex elif n.kind == nkOpenSymChoice: # try 'local' symbols too for Koenig's lookup: o.mode = oimSymChoiceLocalLookup - o.stackPtr = c.tab.tos-1 - result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], + o.scope = c.currentScope + result = FirstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], + o.scope = o.scope.parent + if o.scope == nil: break + result = FirstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) of oimSymChoiceLocalLookup: - result = nextIdentExcluding(o.it, c.tab.stack[o.stackPtr], o.inSymChoice) + result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice) while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], + o.scope = o.scope.parent + if o.scope == nil: break + result = FirstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) if result != nil and result.kind == skStub: loadStub(result) diff --git a/compiler/sem.nim b/compiler/sem.nim index ff5e3d540..21ba64a85 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -282,6 +282,7 @@ proc RecoverContext(c: PContext) = # faster than wrapping every stack operation in a 'try finally' block and # requires far less code. c.currentScope = c.topLevelScope + c.scopeDepth = 2 # importTable and top-level scope while getCurrOwner().kind != skModule: popOwner() while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 390e3825d..41979fd1c 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -46,6 +46,7 @@ type TExprFlags* = set[TExprFlag] TScope* = object + depthLevel*: int symbols*: TStrTable parent*: PScope @@ -57,6 +58,7 @@ type currentScope*: PScope # current scope importTable*: PScope # scope for all imported symbols topLevelScope*: PScope # scope for all top-level symbols + scopeDepth*: int # number of open scopes p*: PProcCon # procedure context friendModule*: PSym # current friend module; may access private data; # this is used so that generic instantiations |