diff options
author | Zahary Karadjov <zahary@gmail.com> | 2013-05-12 00:49:00 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2013-05-12 00:49:00 +0300 |
commit | 3d1c6de63853dc141b919dc853ade4380a478206 (patch) | |
tree | c5c851baa695dbe332db58db347e55248e021dd1 | |
parent | 9a6f47ae69ff3730cc33092c52b3e42187446ccb (diff) | |
download | Nim-3d1c6de63853dc141b919dc853ade4380a478206.tar.gz |
get rid of the SymTab* procs in astalgo
-rw-r--r-- | compiler/astalgo.nim | 74 | ||||
-rw-r--r-- | compiler/lookups.nim | 79 | ||||
-rw-r--r-- | compiler/pragmas.nim | 2 | ||||
-rw-r--r-- | compiler/sem.nim | 8 | ||||
-rw-r--r-- | compiler/semdata.nim | 29 | ||||
-rw-r--r-- | compiler/semdestruct.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 10 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 4 | ||||
-rw-r--r-- | compiler/semstmts.nim | 8 | ||||
-rw-r--r-- | compiler/semtempl.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 6 |
11 files changed, 91 insertions, 133 deletions
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 |