summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/importer.nim8
-rw-r--r--compiler/lookups.nim105
-rw-r--r--compiler/magicsys.nim2
-rw-r--r--compiler/sem.nim2
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semmagic.nim5
-rw-r--r--compiler/semstmts.nim5
-rw-r--r--compiler/suggest.nim19
9 files changed, 76 insertions, 76 deletions
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