From 9a6f47ae69ff3730cc33092c52b3e42187446ccb Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sat, 11 May 2013 23:45:20 +0300 Subject: switch to a linked list of scopes --- compiler/sem.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'compiler/sem.nim') diff --git a/compiler/sem.nim b/compiler/sem.nim index 92b25b1ba..8036dc913 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -247,7 +247,7 @@ proc myOpen(module: PSym): PPassContext = c.semTypeNode = semTypeNode pushProcCon(c, module) pushOwner(c.module) - openScope(c.tab) # scope for imported symbols + openScope(c) # scope for imported symbols SymTabAdd(c.tab, module) # a module knows itself if sfSystemModule in module.flags: magicsys.SystemModule = module # set global variable! @@ -255,7 +255,7 @@ proc myOpen(module: PSym): PPassContext = else: SymTabAdd(c.tab, magicsys.SystemModule) # import the "System" identifier importAllSymbols(c, magicsys.SystemModule) - openScope(c.tab) # scope for the module's symbols + closeScope(c) # scope for the module's symbols result = c proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = @@ -310,8 +310,8 @@ proc checkThreads(c: PContext) = proc myClose(context: PPassContext, n: PNode): PNode = var c = PContext(context) - closeScope(c.tab) # close module's scope - rawCloseScope(c.tab) # imported symbols; don't check for unused ones! + closeScope(c) # close module's scope + rawCloseScope(c) # imported symbols; don't check for unused ones! result = newNode(nkStmtList) if n != nil: InternalError(n.info, "n is not nil") #result := n; -- cgit 1.4.1-2-gfad0 From 3d1c6de63853dc141b919dc853ade4380a478206 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sun, 12 May 2013 00:49:00 +0300 Subject: get rid of the SymTab* procs in astalgo --- compiler/astalgo.nim | 74 --------------------------------------------- compiler/lookups.nim | 79 ++++++++++++++++++++++++++++++++++++------------ compiler/pragmas.nim | 2 +- compiler/sem.nim | 8 ++--- compiler/semdata.nim | 29 ++++++------------ compiler/semdestruct.nim | 2 +- compiler/semexprs.nim | 10 +++--- compiler/semgnrc.nim | 4 +-- compiler/semstmts.nim | 8 ++--- compiler/semtempl.nim | 2 +- compiler/semtypes.nim | 6 ++-- 11 files changed, 91 insertions(+), 133 deletions(-) (limited to 'compiler/sem.nim') diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 16dd196b4..fd6774e7a 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -72,39 +72,6 @@ type proc InitIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym proc NextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym -# -------------- symbol table ---------------------------------------------- -# Each TParser object (which represents a module being compiled) has its own -# symbol table. A symbol table is organized as a stack of str tables. The -# stack represents the different scopes. -# Stack pointer: -# 0 imported symbols from other modules -# 1 module level -# 2 proc level -# 3 nested statements -# ... -# -type - TScope = object - symbols*: TStrTable - parent*: PScope - - PScope = ref TScope - - TSymTab*{.final.} = object - tos*: Natural # top of stack - stack*: seq[PScope] - - -proc InitSymTab*(tab: var TSymTab) -proc DeinitSymTab*(tab: var TSymTab) -proc SymTabGet*(tab: TSymTab, s: PIdent): PSym -proc SymTabGet*(tab: TSymTab, s: PIdent, filter: TSymKinds): PSym -proc SymTabLocalGet*(tab: TSymTab, s: PIdent): PSym -proc SymTabAdd*(tab: var TSymTab, e: PSym) -proc SymTabAddAt*(tab: var TSymTab, e: PSym, at: Natural) -proc SymTabAddUnique*(tab: var TSymTab, e: PSym): TResult -proc SymTabAddUniqueAt*(tab: var TSymTab, e: PSym, at: Natural): TResult - # these are for debugging only: They are not really deprecated, but I want # the warning so that release versions do not contain debugging statements: proc debug*(n: PSym) {.deprecated.} @@ -710,44 +677,7 @@ proc NextIter(ti: var TTabIter, tab: TStrTable): PSym = result = tab.data[ti.h] Inc(ti.h) # ... and increment by one always if result != nil: break - -proc InitSymTab(tab: var TSymTab) = - tab.tos = 0 - tab.stack = EmptySeq - -proc DeinitSymTab(tab: var TSymTab) = - tab.stack = nil - -proc SymTabLocalGet(tab: TSymTab, s: PIdent): PSym = - result = StrTableGet(tab.stack[tab.tos - 1], s) - -proc SymTabGet(tab: TSymTab, s: PIdent): PSym = - for i in countdown(tab.tos - 1, 0): - result = StrTableGet(tab.stack[i], s) - if result != nil: return - result = nil -proc SymTabGet*(tab: TSymTab, s: PIdent, filter: TSymKinds): PSym = - for i in countdown(tab.tos - 1, 0): - result = StrTableGet(tab.stack[i], s) - if result != nil and result.kind in filter: return - result = nil - -proc SymTabAddAt(tab: var TSymTab, e: PSym, at: Natural) = - StrTableAdd(tab.stack[at], e) - -proc SymTabAdd(tab: var TSymTab, e: PSym) = - StrTableAdd(tab.stack[tab.tos - 1], e) - -proc SymTabAddUniqueAt(tab: var TSymTab, e: PSym, at: Natural): TResult = - if StrTableIncl(tab.stack[at], e): - result = Failure - else: - result = Success - -proc SymTabAddUnique(tab: var TSymTab, e: PSym): TResult = - result = SymTabAddUniqueAt(tab, e, tab.tos - 1) - iterator items*(tab: TStrTable): PSym = var it: TTabIter var s = InitTabIter(it, tab) @@ -755,10 +685,6 @@ iterator items*(tab: TStrTable): PSym = yield s s = NextIter(it, tab) -iterator items*(tab: TSymTab): PSym = - for i in countdown(tab.tos-1, 0): - for it in items(tab.stack[i]): yield it - proc hasEmptySlot(data: TIdPairSeq): bool = for h in countup(0, high(data)): if data[h].key == nil: diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 801d21dd4..cfed6e518 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -46,7 +46,7 @@ proc errorSym*(c: PContext, n: PNode): PSym = result.typ = errorType(c) incl(result.flags, sfDiscardable) # pretend it's imported from some unknown module to prevent cascading errors: - SymTabAddAt(c.tab, result, ast.ImportTablePos) + c.importTable.addSym(result) type TOverloadIterMode* = enum @@ -63,8 +63,8 @@ proc getSymRepr*(s: PSym): string = case s.kind of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s) else: result = s.name.s - -proc ensureNoMissingOrUnusedSymbols*(scope: PScope) = + +proc ensureNoMissingOrUnusedSymbols(scope: PScope) = # check if all symbols have been used and defined: var it: TTabIter var s = InitTabIter(it, scope.symbols) @@ -89,15 +89,15 @@ proc WrongRedefinition*(info: TLineInfo, s: string) = proc AddSym*(t: var TStrTable, n: PSym) = if StrTableIncl(t, n): WrongRedefinition(n.info, n.name.s) -proc addDecl*(c: PContext, sym: PSym) = - if SymTabAddUnique(c.tab, sym) == Failure: +proc addDecl*(c: PContext, sym: PSym) = + if c.currentScope.addUnique(sym) == Failure: WrongRedefinition(sym.info, sym.Name.s) proc addPrelimDecl*(c: PContext, sym: PSym) = - discard SymTabAddUnique(c.tab, sym) + discard c.currentScope.addUnique(sym) -proc addDeclAt*(c: PContext, sym: PSym, at: Natural) = - if SymTabAddUniqueAt(c.tab, sym, at) == Failure: +proc addDeclAt*(scope: PScope, sym: PSym) = + if scope.addUnique(sym) == Failure: WrongRedefinition(sym.info, sym.Name.s) proc AddInterfaceDeclAux(c: PContext, sym: PSym) = @@ -106,35 +106,35 @@ proc AddInterfaceDeclAux(c: PContext, sym: PSym) = if c.module != nil: StrTableAdd(c.module.tab, sym) else: InternalError(sym.info, "AddInterfaceDeclAux") -proc addInterfaceDeclAt*(c: PContext, sym: PSym, at: Natural) = - addDeclAt(c, sym, at) +proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) = + addDeclAt(scope, sym) AddInterfaceDeclAux(c, sym) - -proc addOverloadableSymAt*(c: PContext, fn: PSym, at: Natural) = + +proc addOverloadableSymAt*(scope: PScope, fn: PSym) = if fn.kind notin OverloadableSyms: InternalError(fn.info, "addOverloadableSymAt") return - var check = StrTableGet(c.tab.stack[at], fn.name) + var check = StrTableGet(scope.symbols, fn.name) if check != nil and check.Kind notin OverloadableSyms: WrongRedefinition(fn.info, fn.Name.s) else: - SymTabAddAt(c.tab, fn, at) + scope.addSym(fn) proc addInterfaceDecl*(c: PContext, sym: PSym) = # it adds the symbol to the interface if appropriate addDecl(c, sym) AddInterfaceDeclAux(c, sym) -proc addInterfaceOverloadableSymAt*(c: PContext, sym: PSym, at: int) = +proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) = # it adds the symbol to the interface if appropriate - addOverloadableSymAt(c, sym, at) + addOverloadableSymAt(scope, sym) AddInterfaceDeclAux(c, sym) proc lookUp*(c: PContext, n: PNode): PSym = # Looks up a symbol. Generates an error in case of nil. case n.kind of nkIdent: - result = SymtabGet(c.Tab, n.ident) + result = searchInScopes(c, n.ident) if result == nil: LocalError(n.info, errUndeclaredIdentifier, n.ident.s) result = errorSym(c, n) @@ -142,7 +142,7 @@ proc lookUp*(c: PContext, n: PNode): PSym = result = n.sym of nkAccQuoted: var ident = considerAcc(n) - result = SymtabGet(c.Tab, ident) + result = searchInScopes(c, ident) if result == nil: LocalError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) @@ -161,7 +161,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerAcc(n) - result = SymtabGet(c.Tab, ident) + result = searchInScopes(c, ident) if result == nil and checkUndeclared in flags: LocalError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) @@ -239,6 +239,47 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = else: nil if result != nil and result.kind == skStub: loadStub(result) +proc openScope*(c: PContext): PScope {.discardable.} = + c.currentScope = PScope(parent: c.currentScope, symbols: newStrTable()) + result = c.currentScope + +proc rawCloseScope*(c: PContext) = + c.currentScope = c.currentScope.parent + +proc closeScope*(c: PContext) = + ensureNoMissingOrUnusedSymbols(c.currentScope) + rawCloseScope(c) + +template addSym*(scope: PScope, s: PSym) = + StrTableAdd(scope.symbols, s) + +proc addUniqueSym*(scope: PScope, s: PSym): TResult = + if StrTableIncl(scope.symbols, s): + result = Failure + else: + result = Success + +iterator walkScopes*(scope: PScope): PScope = + var current = scope + while current != nil: + yield current + current = current.parent + +proc localSearchInScope*(c: PContext, s: PIdent): PSym = + result = StrTableGet(c.currentScope.symbols, s) + +proc searchInScopes*(c: PContext, s: PIdent): PSym = + for scope in walkScopes(c.currentScope): + result = StrTableGet(scope.symbols, s) + if result != nil: return + result = nil + +proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = + for scope in walkScopes(c.currentScope): + result = StrTableGet(scope.symbols, s) + if result != nil and result.kind in filter: return + result = nil + proc lastOverloadScope*(o: TOverloadIter): int = case o.mode of oimNoQualifier: result = o.stackPtr diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index ba761739a..e623acd06 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -409,7 +409,7 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode = if c < 0: sub = substr(str, b + 1) else: sub = substr(str, b + 1, c - 1) if sub != "": - var e = SymtabGet(con.tab, getIdent(sub)) + var e = searchInScopes(con, getIdent(sub)) if e != nil: if e.kind == skStub: loadStub(e) addSon(result, newSymNode(e)) diff --git a/compiler/sem.nim b/compiler/sem.nim index 8036dc913..bc6d2c9b6 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -247,15 +247,15 @@ proc myOpen(module: PSym): PPassContext = c.semTypeNode = semTypeNode pushProcCon(c, module) pushOwner(c.module) - openScope(c) # scope for imported symbols - SymTabAdd(c.tab, module) # a module knows itself + c.importTable = openScope(c) + c.importTable.addSym(module) # a module knows itself if sfSystemModule in module.flags: magicsys.SystemModule = module # set global variable! InitSystem(c.tab) # currently does nothing else: - SymTabAdd(c.tab, magicsys.SystemModule) # import the "System" identifier + c.importTable.addSym magicsys.SystemModule # import the "System" identifier importAllSymbols(c, magicsys.SystemModule) - closeScope(c) # scope for the module's symbols + c.topLevelScope = openScope(c) result = c proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 8deb3799c..390e3825d 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -45,10 +45,18 @@ type efAllowDestructor TExprFlags* = set[TExprFlag] + TScope* = object + symbols*: TStrTable + parent*: PScope + + PScope* = ref TScope + PContext* = ref TContext TContext* = object of TPassContext # a context represents a module module*: PSym # the module sym belonging to the context - currentScope*: PScope + currentScope*: PScope # current scope + importTable*: PScope # scope for all imported symbols + topLevelScope*: PScope # scope for all top-level symbols p*: PProcCon # procedure context friendModule*: PSym # current friend module; may access private data; # this is used so that generic instantiations @@ -56,7 +64,6 @@ type InstCounter*: int # to prevent endless instantiations threadEntries*: TSymSeq # list of thread entries to check - tab*: TSymTab # each module has its own symbol table AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot # store this info in the syms themselves!) InGenericContext*: int # > 0 if we are in a generic type @@ -83,8 +90,7 @@ type # naming it multiple times generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile lastGenericIdx*: int # used for the generics stack - - + proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = result.genericSym = s result.inst = inst @@ -112,20 +118,6 @@ proc PopOwner*() var gOwners*: seq[PSym] = @[] -proc openScope*(c: PContext) = - c.currentScope = PScope(parent: c.currentScope, symbols: newStrTable()) - c.tab.stack.add(c.currentScope) - inc c.tab.stack.tos - -proc rawCloseScope*(c: PContext) = - c.currentScope = c.currentScope.parent - c.tab.stack.setLen(c.tab.stack.len - 1) - dec c.tab.stack.tos - -proc closeScope*(c: PContext) = - ensureNoMissingOrUnusedSymbols(c.currentScope) - rawExitScope(c) - proc getCurrOwner(): PSym = # owner stack (used for initializing the # owner field of syms) @@ -166,7 +158,6 @@ proc newOptionEntry(): POptionEntry = proc newContext(module: PSym): PContext = new(result) - InitSymTab(result.tab) result.AmbiguousSymbols = initIntset() initLinkedList(result.optionStack) initLinkedList(result.libs) diff --git a/compiler/semdestruct.nim b/compiler/semdestruct.nim index 2383ac649..797d8895e 100644 --- a/compiler/semdestruct.nim +++ b/compiler/semdestruct.nim @@ -120,7 +120,7 @@ proc instantiateDestructor(c: PContext, typ: PType): bool = of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs: if instantiateDestructor(c, t.sons[0]): if rangeDestructorProc == nil: - rangeDestructorProc = SymtabGet(c.tab, getIdent"nimDestroyRange") + rangeDestructorProc = searchInScopes(c, getIdent"nimDestroyRange") t.destructor = rangeDestructorProc return true else: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d15243342..8188722c6 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -328,9 +328,9 @@ proc semOpAux(c: PContext, n: PNode) = proc overloadedCallOpr(c: PContext, n: PNode): PNode = # quick check if there is *any* () operator overloaded: var par = getIdent("()") - if SymtabGet(c.Tab, par) == nil: + if searchInScopes(c, par) == nil: result = nil - else: + else: result = newNodeI(nkCall, n.info) addSon(result, newIdentNode(par, n.info)) for i in countup(0, sonsLen(n) - 1): addSon(result, n.sons[i]) @@ -937,7 +937,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = addSon(result, copyTree(n[0])) else: var i = considerAcc(n.sons[1]) - var f = SymTabGet(c.tab, i) + var f = searchInScopes(c, i) # if f != nil and f.kind == skStub: loadStub(f) # ``loadStub`` is not correct here as we don't care for ``f`` really if f != nil: @@ -1205,9 +1205,9 @@ proc SemYield(c: PContext, n: PNode): PNode = proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym = if onlyCurrentScope: - result = SymtabLocalGet(c.tab, i) + result = localSearchInScope(c, i) else: - result = SymtabGet(c.Tab, i) # no need for stub loading + result = searchInScopes(c, i) # no need for stub loading proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = case n.kind diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 7e51f3f17..3d54ed417 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -82,7 +82,7 @@ proc Lookup(c: PContext, n: PNode, flags: TSemGenericFlags, ctx: var TIntSet): PNode = result = n let ident = considerAcc(n) - var s = SymtabGet(c.Tab, ident) + var s = searchInScopes(c, ident) if s == nil: if ident.id notin ctx and withinMixin notin flags: localError(n.info, errUndeclaredIdentifier, ident.s) @@ -281,7 +281,7 @@ proc semGenericStmt(c: PContext, n: PNode, of nkEnumFieldDef: a = n.sons[i].sons[0] of nkIdent: a = n.sons[i] else: illFormedAst(n) - addDeclAt(c, newSymS(skUnknown, getIdentNode(a.sons[i]), c), c.tab.tos-1) + addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[i]), c)) of nkObjectTy, nkTupleTy: nil of nkFormalParams: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index bf7fdefcd..0998f45a5 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -800,7 +800,7 @@ proc lookupMacro(c: PContext, n: PNode): PSym = result = n.sym if result.kind notin {skMacro, skTemplate}: result = nil else: - result = SymtabGet(c.Tab, considerAcc(n), {skMacro, skTemplate}) + result = searchInScopes(c, considerAcc(n), {skMacro, skTemplate}) proc semProcAnnotation(c: PContext, prc: PNode): PNode = var n = prc.sons[pragmasPos] @@ -894,6 +894,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, n.sons[namePos] = newSymNode(s) s.ast = n pushOwner(s) + var outerScope = c.currentScope openScope(c) var gp: PNode if n.sons[genericParamsPos].kind != nkEmpty: @@ -922,12 +923,11 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if proto == nil: s.typ.callConv = lastOptionEntry(c).defaultCC # add it here, so that recursive procs are possible: - # -2 because we have a scope open for parameters if sfGenSym in s.flags: nil elif kind in OverloadableSyms: - addInterfaceOverloadableSymAt(c, s, c.tab.tos - 2) + addInterfaceOverloadableSymAt(c, outerScope, s) else: - addInterfaceDeclAt(c, s, c.tab.tos - 2) + addInterfaceDeclAt(c, outerScope, s) if n.sons[pragmasPos].kind != nkEmpty: pragma(c, s, n.sons[pragmasPos], validPragmas) else: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 234ef5d2c..7f6b85631 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -413,7 +413,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = let curScope = c.tab.tos - 1 var proto = SearchForProc(c, s, curScope) if proto == nil: - addInterfaceOverloadableSymAt(c, s, curScope) + addInterfaceOverloadableSymAt(c, c.currentScope, s) else: SymTabReplace(c.tab.stack[curScope], proto, s) if n.sons[patternPos].kind != nkEmpty: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 8e5a239dd..2c526f676 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -79,7 +79,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = incl(e.flags, sfExported) if not isPure: StrTableAdd(c.module.tab, e) addSon(result.n, newSymNode(e)) - if sfGenSym notin e.flags and not isPure: addDeclAt(c, e, c.tab.tos - 1) + if sfGenSym notin e.flags and not isPure: addDecl(c, e) inc(counter) proc semSet(c: PContext, n: PNode, prev: PType): PType = @@ -616,7 +616,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if genericParams == nil: # genericParams is nil when the proc is being instantiated # the resolved type will be in scope then - let s = SymtabGet(c.tab, paramTypId) + let s = searchInScopes(c, paramTypId) # tests/run/tinterf triggers this: if s != nil: result = s.typ else: @@ -749,7 +749,7 @@ proc semGenericParamInInvokation(c: PContext, n: PNode): PType = when false: if n.kind == nkSym: # for generics we need to lookup the type var again: - var s = SymtabGet(c.Tab, n.sym.name) + var s = searchInScopes(c, n.sym.name) if s != nil: if s.kind == skType and s.typ != nil: var t = n.sym.typ -- cgit 1.4.1-2-gfad0 From 7a2b1a7520bb80cbef88ad9c3dc843cbe512a588 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sun, 12 May 2013 01:20:40 +0300 Subject: get rid of ImportTablePos and ModuleTablePos --- compiler/ast.nim | 4 -- compiler/importer.nim | 8 ++-- compiler/lookups.nim | 105 +++++++++++++++++++++++++------------------------- compiler/magicsys.nim | 2 - compiler/sem.nim | 2 +- compiler/semexprs.nim | 2 +- compiler/semmagic.nim | 5 ++- compiler/semstmts.nim | 5 ++- compiler/suggest.nim | 19 +++++---- 9 files changed, 76 insertions(+), 76 deletions(-) (limited to 'compiler/sem.nim') diff --git a/compiler/ast.nim b/compiler/ast.nim index 36439a34d..6187ef63c 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -13,10 +13,6 @@ import msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists, intsets, idgen -const - ImportTablePos* = 0 # imported symbols are at level 0 - ModuleTablePos* = 1 # module's top level symbols are at level 1 - type TCallingConvention* = enum ccDefault, # proc has no explicit calling convention diff --git a/compiler/importer.nim b/compiler/importer.nim index d274b4693..ebb848ea7 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -48,7 +48,7 @@ proc rawImportSymbol(c: PContext, s: PSym) = # This does not handle stubs, because otherwise loading on demand would be # pointless in practice. So importing stubs is fine here! # check if we have already a symbol of the same name: - var check = StrTableGet(c.tab.stack[importTablePos], s.name) + var check = StrTableGet(c.importTable.symbols, s.name) if check != nil and check.id != s.id: if s.kind notin OverloadableSyms: # s and check need to be qualified: @@ -56,7 +56,7 @@ proc rawImportSymbol(c: PContext, s: PSym) = Incl(c.AmbiguousSymbols, check.id) # thanks to 'export' feature, it could be we import the same symbol from # multiple sources, so we need to call 'StrTableAdd' here: - StrTableAdd(c.tab.stack[importTablePos], s) + StrTableAdd(c.importTable.symbols, s) if s.kind == skType: var etyp = s.typ if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags: @@ -68,12 +68,12 @@ proc rawImportSymbol(c: PContext, s: PSym) = # have been put into the symbol table # BUGFIX: but only iff they are the same symbols! var it: TIdentIter - check = InitIdentIter(it, c.tab.stack[importTablePos], e.name) + check = InitIdentIter(it, c.importTable.symbols, e.name) while check != nil: if check.id == e.id: e = nil break - check = NextIdentIter(it, c.tab.stack[importTablePos]) + check = NextIdentIter(it, c.importTable.symbols) if e != nil: rawImportSymbol(c, e) else: diff --git a/compiler/lookups.nim b/compiler/lookups.nim index cfed6e518..36f5a00b9 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -13,6 +13,8 @@ import intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread, renderer, wordrecg, idgen +proc ensureNoMissingOrUnusedSymbols(scope: PScope) + proc considerAcc*(n: PNode): PIdent = case n.kind of nkIdent: result = n.ident @@ -33,6 +35,47 @@ proc considerAcc*(n: PNode): PIdent = else: GlobalError(n.info, errIdentifierExpected, renderTree(n)) +template addSym*(scope: PScope, s: PSym) = + StrTableAdd(scope.symbols, s) + +proc addUniqueSym*(scope: PScope, s: PSym): TResult = + if StrTableIncl(scope.symbols, s): + result = Failure + else: + result = Success + +proc openScope*(c: PContext): PScope {.discardable.} = + c.currentScope = PScope(parent: c.currentScope, symbols: newStrTable()) + result = c.currentScope + +proc rawCloseScope*(c: PContext) = + c.currentScope = c.currentScope.parent + +proc closeScope*(c: PContext) = + ensureNoMissingOrUnusedSymbols(c.currentScope) + rawCloseScope(c) + +iterator walkScopes*(scope: PScope): PScope = + var current = scope + while current != nil: + yield current + current = current.parent + +proc localSearchInScope*(c: PContext, s: PIdent): PSym = + result = StrTableGet(c.currentScope.symbols, s) + +proc searchInScopes*(c: PContext, s: PIdent): PSym = + for scope in walkScopes(c.currentScope): + result = StrTableGet(scope.symbols, s) + if result != nil: return + result = nil + +proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = + for scope in walkScopes(c.currentScope): + result = StrTableGet(scope.symbols, s) + if result != nil and result.kind in filter: return + result = nil + proc errorSym*(c: PContext, n: PNode): PSym = ## creates an error symbol to avoid cascading errors (for IDE support) var m = n @@ -63,7 +106,7 @@ proc getSymRepr*(s: PSym): string = case s.kind of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s) else: result = s.name.s - + proc ensureNoMissingOrUnusedSymbols(scope: PScope) = # check if all symbols have been used and defined: var it: TTabIter @@ -85,19 +128,16 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) = proc WrongRedefinition*(info: TLineInfo, s: string) = if gCmd != cmdInteractive: localError(info, errAttemptToRedefine, s) - -proc AddSym*(t: var TStrTable, n: PSym) = - if StrTableIncl(t, n): WrongRedefinition(n.info, n.name.s) proc addDecl*(c: PContext, sym: PSym) = - if c.currentScope.addUnique(sym) == Failure: + if c.currentScope.addUniqueSym(sym) == Failure: WrongRedefinition(sym.info, sym.Name.s) proc addPrelimDecl*(c: PContext, sym: PSym) = - discard c.currentScope.addUnique(sym) + discard c.currentScope.addUniqueSym(sym) proc addDeclAt*(scope: PScope, sym: PSym) = - if scope.addUnique(sym) == Failure: + if scope.addUniqueSym(sym) == Failure: WrongRedefinition(sym.info, sym.Name.s) proc AddInterfaceDeclAux(c: PContext, sym: PSym) = @@ -183,7 +223,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = ident = considerAcc(n.sons[1]) if ident != nil: if m == c.module: - result = StrTableGet(c.tab.stack[ModuleTablePos], ident) + result = StrTableGet(c.topLevelScope.symbols, ident) else: result = StrTableGet(m.tab, ident) if result == nil and checkUndeclared in flags: @@ -222,7 +262,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = if ident != nil: if o.m == c.module: # a module may access its private members: - result = InitIdentIter(o.it, c.tab.stack[ModuleTablePos], ident) + result = InitIdentIter(o.it, c.topLevelScope.symbols, ident) o.mode = oimSelfModule else: result = InitIdentIter(o.it, o.m.tab, ident) @@ -239,52 +279,11 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = else: nil if result != nil and result.kind == skStub: loadStub(result) -proc openScope*(c: PContext): PScope {.discardable.} = - c.currentScope = PScope(parent: c.currentScope, symbols: newStrTable()) - result = c.currentScope - -proc rawCloseScope*(c: PContext) = - c.currentScope = c.currentScope.parent - -proc closeScope*(c: PContext) = - ensureNoMissingOrUnusedSymbols(c.currentScope) - rawCloseScope(c) - -template addSym*(scope: PScope, s: PSym) = - StrTableAdd(scope.symbols, s) - -proc addUniqueSym*(scope: PScope, s: PSym): TResult = - if StrTableIncl(scope.symbols, s): - result = Failure - else: - result = Success - -iterator walkScopes*(scope: PScope): PScope = - var current = scope - while current != nil: - yield current - current = current.parent - -proc localSearchInScope*(c: PContext, s: PIdent): PSym = - result = StrTableGet(c.currentScope.symbols, s) - -proc searchInScopes*(c: PContext, s: PIdent): PSym = - for scope in walkScopes(c.currentScope): - result = StrTableGet(scope.symbols, s) - if result != nil: return - result = nil - -proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = - for scope in walkScopes(c.currentScope): - result = StrTableGet(scope.symbols, s) - if result != nil and result.kind in filter: return - result = nil - proc lastOverloadScope*(o: TOverloadIter): int = case o.mode of oimNoQualifier: result = o.stackPtr - of oimSelfModule: result = ModuleTablePos - of oimOtherModule: result = ImportTablePos + of oimSelfModule: result = 1 + of oimOtherModule: result = 0 else: result = -1 proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = @@ -302,7 +301,7 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = else: result = nil of oimSelfModule: - result = nextIdentIter(o.it, c.tab.stack[ModuleTablePos]) + result = nextIdentIter(o.it, c.topLevelScope.symbols) of oimOtherModule: result = nextIdentIter(o.it, o.m.tab) of oimSymChoice: diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index 005ee3ae3..352b6ca04 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -19,7 +19,6 @@ proc registerSysType*(t: PType) proc getSysType*(kind: TTypeKind): PType proc getCompilerProc*(name: string): PSym proc registerCompilerProc*(s: PSym) -proc InitSystem*(tab: var TSymTab) proc FinishSystem*(tab: TStrTable) proc getSysSym*(name: string): PSym # implementation @@ -154,7 +153,6 @@ proc getCompilerProc(name: string): PSym = proc registerCompilerProc(s: PSym) = strTableAdd(compilerprocs, s) -proc InitSystem(tab: var TSymTab) = nil proc FinishSystem(tab: TStrTable) = nil initStrTable(compilerprocs) diff --git a/compiler/sem.nim b/compiler/sem.nim index bc6d2c9b6..ff5e3d540 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -281,7 +281,7 @@ proc RecoverContext(c: PContext) = # clean up in case of a semantic error: We clean up the stacks, etc. This is # faster than wrapping every stack operation in a 'try finally' block and # requires far less code. - while c.tab.tos-1 > ModuleTablePos: rawCloseScope(c.tab) + c.currentScope = c.topLevelScope while getCurrOwner().kind != skModule: popOwner() while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 8188722c6..8977fd93d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1222,7 +1222,7 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = if (n.sons[1].kind == nkIdent): var ident = n.sons[1].ident if m == c.module: - result = StrTableGet(c.tab.stack[ModuleTablePos], ident) + result = StrTableGet(c.topLevelScope.symbols, ident) else: result = StrTableGet(m.tab, ident) else: diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 058964fc8..41c379133 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -80,8 +80,9 @@ proc semLocals(c: PContext, n: PNode): PNode = result = newNodeIT(nkPar, n.info, tupleType) tupleType.n = newNodeI(nkRecList, n.info) # for now we skip openarrays ... - for i in countdown(c.tab.tos-1, ModuleTablePos+1): - for it in items(c.tab.stack[i]): + for scope in walkScopes(c.currentScope): + if scope == c.topLevelScope: break + for it in items(scope.symbols): # XXX parameters' owners are wrong for generics; this caused some pain # for closures too; we should finally fix it. #if it.owner != c.p.owner: return result diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 0998f45a5..fc98ff703 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -289,8 +289,9 @@ proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode = changeType(result, typ, check=false) proc findShadowedVar(c: PContext, v: PSym): PSym = - for i in countdown(c.tab.tos - 2, ModuleTablePos+1): - let shadowed = StrTableGet(c.tab.stack[i], v.name) + for scope in walkScopes(c.currentScope.parent): + if scope == c.topLevelScope: break + let shadowed = StrTableGet(scope.symbols, v.name) if shadowed != nil and shadowed.kind in skLocalVars: return shadowed diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 18e6dbddf..8e6d6b6fa 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -64,11 +64,13 @@ when not defined(nimhygiene): {.pragma: inject.} template wholeSymTab(cond, section: expr) {.immediate.} = - for i in countdown(c.tab.tos-1, 0): - for item in items(c.tab.stack[i]): + var isLocal = true + for scope in walkScopes(c): + if scope == c.topLevelScope: isLocal = false + for item in items(scope.symbols): let it {.inject.} = item if cond: - SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, section)) + SuggestWriteln(SymToStr(it, isLocal = isLocal, section)) inc outputs proc suggestSymList(c: PContext, list: PNode, outputs: var int) = @@ -123,11 +125,14 @@ proc suggestOperations(c: PContext, n: PNode, typ: PType, outputs: var int) = proc suggestEverything(c: PContext, n: PNode, outputs: var int) = # do not produce too many symbols: - for i in countdown(c.tab.tos-1, 1): - for it in items(c.tab.stack[i]): + var isLocal = true + for scope in walkScopes(c): + if scope == c.topLevelScope: isLocal = false + for it in items(scope.symbols): if filterSym(it): - SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, sectionSuggest)) + SuggestWriteln(SymToStr(it, isLocal = isLocal, sectionSuggest)) inc outputs + if scope == c.topLevelScope: break proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = # special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but @@ -138,7 +143,7 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = if n.kind == nkSym and n.sym.kind == skModule: if n.sym == c.module: # all symbols accessible, because we are in the current module: - for it in items(c.tab.stack[ModuleTablePos]): + for it in items(c.topLevelScope.symbols): if filterSym(it): SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest)) inc outputs -- cgit 1.4.1-2-gfad0 From af081f995e41f052c63ad5468fbf00bb860de474 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sun, 12 May 2013 02:01:16 +0300 Subject: get rid of TOverloadIter.stackPtr --- compiler/lookups.nim | 64 +++++++++++++++++++++++++++++----------------------- compiler/sem.nim | 1 + compiler/semdata.nim | 2 ++ 3 files changed, 39 insertions(+), 28 deletions(-) (limited to 'compiler/sem.nim') 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 -- cgit 1.4.1-2-gfad0 From f317807a895e020b9398c2d7f0b6253dc3abbea9 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sun, 12 May 2013 02:19:17 +0300 Subject: final fixes giving us a working compiler --- compiler/pragmas.nim | 2 +- compiler/procfind.nim | 16 ++++++++-------- compiler/sem.nim | 3 +-- compiler/semcall.nim | 2 +- compiler/semexprs.nim | 4 ++-- compiler/semstmts.nim | 5 ++--- compiler/semtempl.nim | 5 ++--- compiler/suggest.nim | 4 ++-- 8 files changed, 19 insertions(+), 22 deletions(-) (limited to 'compiler/sem.nim') diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index e623acd06..937d9c9eb 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -12,7 +12,7 @@ import os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer, wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees, - rodread, types + rodread, types, lookups const FirstCallConv* = wNimcall diff --git a/compiler/procfind.nim b/compiler/procfind.nim index 2db6247e1..e41567816 100644 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -30,11 +30,11 @@ proc equalGenericParams(procA, procB: PNode): bool = if not ExprStructuralEquivalent(a.ast, b.ast): return result = true -proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = +proc SearchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are exactly # the same the sym in the symbol table is returned, else nil. var it: TIdentIter - result = initIdentIter(it, c.tab.stack[tos], fn.Name) + result = initIdentIter(it, scope.symbols, 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 @@ -48,7 +48,7 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = fn.ast.sons[paramsPos]) and equalGenericParams(genR, genF): return - result = NextIdentIter(it, c.tab.stack[tos]) + result = NextIdentIter(it, scope.symbols) else: while result != nil: if result.Kind == fn.kind and not isGenericRoutine(result): @@ -60,7 +60,7 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = return of paramsNotEqual: nil - result = NextIdentIter(it, c.tab.stack[tos]) + result = NextIdentIter(it, scope.symbols) when false: proc paramsFitBorrow(child, parent: PNode): bool = @@ -76,16 +76,16 @@ when false: dcEqOrDistinctOf): return result = true - proc SearchForBorrowProc*(c: PContext, fn: PSym, tos: int): PSym = + proc SearchForBorrowProc*(c: PContext, startScope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are suitable # for borrowing the sym in the symbol table is returned, else nil. var it: TIdentIter - for scope in countdown(tos, 0): - result = initIdentIter(it, c.tab.stack[scope], fn.Name) + for scope in walkScopes(startScope): + result = initIdentIter(it, scope.symbols, fn.Name) while result != nil: # watchout! result must not be the same as fn! if (result.Kind == fn.kind) and (result.id != fn.id): if equalGenericParams(result.ast.sons[genericParamsPos], fn.ast.sons[genericParamsPos]): if paramsFitBorrow(fn.typ.n, result.typ.n): return - result = NextIdentIter(it, c.tab.stack[scope]) + result = NextIdentIter(it, scope.symbols) diff --git a/compiler/sem.nim b/compiler/sem.nim index 21ba64a85..70e7d8673 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -99,7 +99,7 @@ proc commonType*(x, y: PType): PType = result.addSonSkipIntLit(r) proc isTopLevel(c: PContext): bool {.inline.} = - result = c.tab.tos <= 2 + result = c.scopeDepth <= 2 proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = result = newSym(kind, considerAcc(n), getCurrOwner(), n.info) @@ -251,7 +251,6 @@ proc myOpen(module: PSym): PPassContext = c.importTable.addSym(module) # a module knows itself if sfSystemModule in module.flags: magicsys.SystemModule = module # set global variable! - InitSystem(c.tab) # currently does nothing else: c.importTable.addSym magicsys.SystemModule # import the "System" identifier importAllSymbols(c, magicsys.SystemModule) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index be41299ad..2f058ad0b 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -198,7 +198,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = else: result = explicitGenericInstError(n) -proc SearchForBorrowProc(c: PContext, fn: PSym, tos: int): PSym = +proc SearchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are suitable # for borrowing the sym in the symbol table is returned, else nil. # New approach: generate fn(x, y, z) where x, y, z have the proper types diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 8977fd93d..4bae934a5 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1374,7 +1374,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = msgs.gErrorMax = high(int) # open a scope for temporary symbol inclusions: - let oldTos = c.tab.tos + let oldTos = c.scopeDepth openScope(c) let oldOwnerLen = len(gOwners) let oldGenerics = c.generics @@ -1398,7 +1398,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = c.p = oldProcCon msgs.setInfoContextLen(oldContextLen) setlen(gOwners, oldOwnerLen) - while c.tab.tos > oldTos: rawCloseScope(c) + while c.scopeDepth > oldTos: rawCloseScope(c) dec c.InCompilesContext dec msgs.gSilence msgs.gErrorCounter = oldErrorCount diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index fc98ff703..b16dbde58 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -773,7 +773,7 @@ proc addParams(c: PContext, n: PNode, kind: TSymKind) = proc semBorrow(c: PContext, n: PNode, s: PSym) = # search for the correct alias: - var b = SearchForBorrowProc(c, s, c.tab.tos - 2) + var b = SearchForBorrowProc(c, c.currentScope.parent, s) if b != nil: # store the alias: n.sons[bodyPos] = newSymNode(b) @@ -919,8 +919,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, n.sons[patternPos] = semPattern(c, n.sons[patternPos]) if s.kind == skIterator: s.typ.flags.incl(tfIterator) - var proto = SearchForProc(c, s, c.tab.tos-2) # -2 because we have a scope - # open for parameters + var proto = SearchForProc(c, outerScope, s) if proto == nil: s.typ.callConv = lastOptionEntry(c).defaultCC # add it here, so that recursive procs are possible: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 7f6b85631..0405ba9d1 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -410,12 +410,11 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = result = n if n.sons[bodyPos].kind == nkEmpty: LocalError(n.info, errImplOfXexpected, s.name.s) - let curScope = c.tab.tos - 1 - var proto = SearchForProc(c, s, curScope) + var proto = SearchForProc(c, c.currentScope, s) if proto == nil: addInterfaceOverloadableSymAt(c, c.currentScope, s) else: - SymTabReplace(c.tab.stack[curScope], proto, s) + SymTabReplace(c.currentScope.symbols, proto, s) if n.sons[patternPos].kind != nkEmpty: c.patterns.add(s) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 8e6d6b6fa..a5a7fcd66 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -65,7 +65,7 @@ when not defined(nimhygiene): template wholeSymTab(cond, section: expr) {.immediate.} = var isLocal = true - for scope in walkScopes(c): + for scope in walkScopes(c.currentScope): if scope == c.topLevelScope: isLocal = false for item in items(scope.symbols): let it {.inject.} = item @@ -126,7 +126,7 @@ proc suggestOperations(c: PContext, n: PNode, typ: PType, outputs: var int) = proc suggestEverything(c: PContext, n: PNode, outputs: var int) = # do not produce too many symbols: var isLocal = true - for scope in walkScopes(c): + for scope in walkScopes(c.currentScope): if scope == c.topLevelScope: isLocal = false for it in items(scope.symbols): if filterSym(it): -- cgit 1.4.1-2-gfad0