get rid of ImportTablePos and ModuleTablePos
This commit is contained in:
parent
3d1c6de638
commit
7a2b1a7520
9 changed files with 76 additions and 76 deletions
|
|
@ -13,10 +13,6 @@ import
|
||||||
msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists,
|
msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists,
|
||||||
intsets, idgen
|
intsets, idgen
|
||||||
|
|
||||||
const
|
|
||||||
ImportTablePos* = 0 # imported symbols are at level 0
|
|
||||||
ModuleTablePos* = 1 # module's top level symbols are at level 1
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TCallingConvention* = enum
|
TCallingConvention* = enum
|
||||||
ccDefault, # proc has no explicit calling convention
|
ccDefault, # proc has no explicit calling convention
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||||
# This does not handle stubs, because otherwise loading on demand would be
|
# This does not handle stubs, because otherwise loading on demand would be
|
||||||
# pointless in practice. So importing stubs is fine here!
|
# pointless in practice. So importing stubs is fine here!
|
||||||
# check if we have already a symbol of the same name:
|
# 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 check != nil and check.id != s.id:
|
||||||
if s.kind notin OverloadableSyms:
|
if s.kind notin OverloadableSyms:
|
||||||
# s and check need to be qualified:
|
# s and check need to be qualified:
|
||||||
|
|
@ -56,7 +56,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||||
Incl(c.AmbiguousSymbols, check.id)
|
Incl(c.AmbiguousSymbols, check.id)
|
||||||
# thanks to 'export' feature, it could be we import the same symbol from
|
# thanks to 'export' feature, it could be we import the same symbol from
|
||||||
# multiple sources, so we need to call 'StrTableAdd' here:
|
# multiple sources, so we need to call 'StrTableAdd' here:
|
||||||
StrTableAdd(c.tab.stack[importTablePos], s)
|
StrTableAdd(c.importTable.symbols, s)
|
||||||
if s.kind == skType:
|
if s.kind == skType:
|
||||||
var etyp = s.typ
|
var etyp = s.typ
|
||||||
if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags:
|
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
|
# have been put into the symbol table
|
||||||
# BUGFIX: but only iff they are the same symbols!
|
# BUGFIX: but only iff they are the same symbols!
|
||||||
var it: TIdentIter
|
var it: TIdentIter
|
||||||
check = InitIdentIter(it, c.tab.stack[importTablePos], e.name)
|
check = InitIdentIter(it, c.importTable.symbols, e.name)
|
||||||
while check != nil:
|
while check != nil:
|
||||||
if check.id == e.id:
|
if check.id == e.id:
|
||||||
e = nil
|
e = nil
|
||||||
break
|
break
|
||||||
check = NextIdentIter(it, c.tab.stack[importTablePos])
|
check = NextIdentIter(it, c.importTable.symbols)
|
||||||
if e != nil:
|
if e != nil:
|
||||||
rawImportSymbol(c, e)
|
rawImportSymbol(c, e)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import
|
||||||
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
|
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
|
||||||
renderer, wordrecg, idgen
|
renderer, wordrecg, idgen
|
||||||
|
|
||||||
|
proc ensureNoMissingOrUnusedSymbols(scope: PScope)
|
||||||
|
|
||||||
proc considerAcc*(n: PNode): PIdent =
|
proc considerAcc*(n: PNode): PIdent =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent: result = n.ident
|
of nkIdent: result = n.ident
|
||||||
|
|
@ -33,6 +35,47 @@ proc considerAcc*(n: PNode): PIdent =
|
||||||
else:
|
else:
|
||||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
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 =
|
proc errorSym*(c: PContext, n: PNode): PSym =
|
||||||
## creates an error symbol to avoid cascading errors (for IDE support)
|
## creates an error symbol to avoid cascading errors (for IDE support)
|
||||||
var m = n
|
var m = n
|
||||||
|
|
@ -63,7 +106,7 @@ proc getSymRepr*(s: PSym): string =
|
||||||
case s.kind
|
case s.kind
|
||||||
of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s)
|
of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s)
|
||||||
else: result = s.name.s
|
else: result = s.name.s
|
||||||
|
|
||||||
proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
|
proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
|
||||||
# check if all symbols have been used and defined:
|
# check if all symbols have been used and defined:
|
||||||
var it: TTabIter
|
var it: TTabIter
|
||||||
|
|
@ -85,19 +128,16 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
|
||||||
proc WrongRedefinition*(info: TLineInfo, s: string) =
|
proc WrongRedefinition*(info: TLineInfo, s: string) =
|
||||||
if gCmd != cmdInteractive:
|
if gCmd != cmdInteractive:
|
||||||
localError(info, errAttemptToRedefine, s)
|
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) =
|
proc addDecl*(c: PContext, sym: PSym) =
|
||||||
if c.currentScope.addUnique(sym) == Failure:
|
if c.currentScope.addUniqueSym(sym) == Failure:
|
||||||
WrongRedefinition(sym.info, sym.Name.s)
|
WrongRedefinition(sym.info, sym.Name.s)
|
||||||
|
|
||||||
proc addPrelimDecl*(c: PContext, sym: PSym) =
|
proc addPrelimDecl*(c: PContext, sym: PSym) =
|
||||||
discard c.currentScope.addUnique(sym)
|
discard c.currentScope.addUniqueSym(sym)
|
||||||
|
|
||||||
proc addDeclAt*(scope: PScope, sym: PSym) =
|
proc addDeclAt*(scope: PScope, sym: PSym) =
|
||||||
if scope.addUnique(sym) == Failure:
|
if scope.addUniqueSym(sym) == Failure:
|
||||||
WrongRedefinition(sym.info, sym.Name.s)
|
WrongRedefinition(sym.info, sym.Name.s)
|
||||||
|
|
||||||
proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
|
proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
|
||||||
|
|
@ -183,7 +223,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||||
ident = considerAcc(n.sons[1])
|
ident = considerAcc(n.sons[1])
|
||||||
if ident != nil:
|
if ident != nil:
|
||||||
if m == c.module:
|
if m == c.module:
|
||||||
result = StrTableGet(c.tab.stack[ModuleTablePos], ident)
|
result = StrTableGet(c.topLevelScope.symbols, ident)
|
||||||
else:
|
else:
|
||||||
result = StrTableGet(m.tab, ident)
|
result = StrTableGet(m.tab, ident)
|
||||||
if result == nil and checkUndeclared in flags:
|
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 ident != nil:
|
||||||
if o.m == c.module:
|
if o.m == c.module:
|
||||||
# a module may access its private members:
|
# 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
|
o.mode = oimSelfModule
|
||||||
else:
|
else:
|
||||||
result = InitIdentIter(o.it, o.m.tab, ident)
|
result = InitIdentIter(o.it, o.m.tab, ident)
|
||||||
|
|
@ -239,52 +279,11 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||||
else: nil
|
else: nil
|
||||||
if result != nil and result.kind == skStub: loadStub(result)
|
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 =
|
proc lastOverloadScope*(o: TOverloadIter): int =
|
||||||
case o.mode
|
case o.mode
|
||||||
of oimNoQualifier: result = o.stackPtr
|
of oimNoQualifier: result = o.stackPtr
|
||||||
of oimSelfModule: result = ModuleTablePos
|
of oimSelfModule: result = 1
|
||||||
of oimOtherModule: result = ImportTablePos
|
of oimOtherModule: result = 0
|
||||||
else: result = -1
|
else: result = -1
|
||||||
|
|
||||||
proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
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:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
of oimSelfModule:
|
of oimSelfModule:
|
||||||
result = nextIdentIter(o.it, c.tab.stack[ModuleTablePos])
|
result = nextIdentIter(o.it, c.topLevelScope.symbols)
|
||||||
of oimOtherModule:
|
of oimOtherModule:
|
||||||
result = nextIdentIter(o.it, o.m.tab)
|
result = nextIdentIter(o.it, o.m.tab)
|
||||||
of oimSymChoice:
|
of oimSymChoice:
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ proc registerSysType*(t: PType)
|
||||||
proc getSysType*(kind: TTypeKind): PType
|
proc getSysType*(kind: TTypeKind): PType
|
||||||
proc getCompilerProc*(name: string): PSym
|
proc getCompilerProc*(name: string): PSym
|
||||||
proc registerCompilerProc*(s: PSym)
|
proc registerCompilerProc*(s: PSym)
|
||||||
proc InitSystem*(tab: var TSymTab)
|
|
||||||
proc FinishSystem*(tab: TStrTable)
|
proc FinishSystem*(tab: TStrTable)
|
||||||
proc getSysSym*(name: string): PSym
|
proc getSysSym*(name: string): PSym
|
||||||
# implementation
|
# implementation
|
||||||
|
|
@ -154,7 +153,6 @@ proc getCompilerProc(name: string): PSym =
|
||||||
proc registerCompilerProc(s: PSym) =
|
proc registerCompilerProc(s: PSym) =
|
||||||
strTableAdd(compilerprocs, s)
|
strTableAdd(compilerprocs, s)
|
||||||
|
|
||||||
proc InitSystem(tab: var TSymTab) = nil
|
|
||||||
proc FinishSystem(tab: TStrTable) = nil
|
proc FinishSystem(tab: TStrTable) = nil
|
||||||
|
|
||||||
initStrTable(compilerprocs)
|
initStrTable(compilerprocs)
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ proc RecoverContext(c: PContext) =
|
||||||
# clean up in case of a semantic error: We clean up the stacks, etc. This is
|
# 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
|
# faster than wrapping every stack operation in a 'try finally' block and
|
||||||
# requires far less code.
|
# requires far less code.
|
||||||
while c.tab.tos-1 > ModuleTablePos: rawCloseScope(c.tab)
|
c.currentScope = c.topLevelScope
|
||||||
while getCurrOwner().kind != skModule: popOwner()
|
while getCurrOwner().kind != skModule: popOwner()
|
||||||
while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next
|
while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1222,7 +1222,7 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
|
||||||
if (n.sons[1].kind == nkIdent):
|
if (n.sons[1].kind == nkIdent):
|
||||||
var ident = n.sons[1].ident
|
var ident = n.sons[1].ident
|
||||||
if m == c.module:
|
if m == c.module:
|
||||||
result = StrTableGet(c.tab.stack[ModuleTablePos], ident)
|
result = StrTableGet(c.topLevelScope.symbols, ident)
|
||||||
else:
|
else:
|
||||||
result = StrTableGet(m.tab, ident)
|
result = StrTableGet(m.tab, ident)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,9 @@ proc semLocals(c: PContext, n: PNode): PNode =
|
||||||
result = newNodeIT(nkPar, n.info, tupleType)
|
result = newNodeIT(nkPar, n.info, tupleType)
|
||||||
tupleType.n = newNodeI(nkRecList, n.info)
|
tupleType.n = newNodeI(nkRecList, n.info)
|
||||||
# for now we skip openarrays ...
|
# for now we skip openarrays ...
|
||||||
for i in countdown(c.tab.tos-1, ModuleTablePos+1):
|
for scope in walkScopes(c.currentScope):
|
||||||
for it in items(c.tab.stack[i]):
|
if scope == c.topLevelScope: break
|
||||||
|
for it in items(scope.symbols):
|
||||||
# XXX parameters' owners are wrong for generics; this caused some pain
|
# XXX parameters' owners are wrong for generics; this caused some pain
|
||||||
# for closures too; we should finally fix it.
|
# for closures too; we should finally fix it.
|
||||||
#if it.owner != c.p.owner: return result
|
#if it.owner != c.p.owner: return result
|
||||||
|
|
|
||||||
|
|
@ -289,8 +289,9 @@ proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode =
|
||||||
changeType(result, typ, check=false)
|
changeType(result, typ, check=false)
|
||||||
|
|
||||||
proc findShadowedVar(c: PContext, v: PSym): PSym =
|
proc findShadowedVar(c: PContext, v: PSym): PSym =
|
||||||
for i in countdown(c.tab.tos - 2, ModuleTablePos+1):
|
for scope in walkScopes(c.currentScope.parent):
|
||||||
let shadowed = StrTableGet(c.tab.stack[i], v.name)
|
if scope == c.topLevelScope: break
|
||||||
|
let shadowed = StrTableGet(scope.symbols, v.name)
|
||||||
if shadowed != nil and shadowed.kind in skLocalVars:
|
if shadowed != nil and shadowed.kind in skLocalVars:
|
||||||
return shadowed
|
return shadowed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,11 +64,13 @@ when not defined(nimhygiene):
|
||||||
{.pragma: inject.}
|
{.pragma: inject.}
|
||||||
|
|
||||||
template wholeSymTab(cond, section: expr) {.immediate.} =
|
template wholeSymTab(cond, section: expr) {.immediate.} =
|
||||||
for i in countdown(c.tab.tos-1, 0):
|
var isLocal = true
|
||||||
for item in items(c.tab.stack[i]):
|
for scope in walkScopes(c):
|
||||||
|
if scope == c.topLevelScope: isLocal = false
|
||||||
|
for item in items(scope.symbols):
|
||||||
let it {.inject.} = item
|
let it {.inject.} = item
|
||||||
if cond:
|
if cond:
|
||||||
SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, section))
|
SuggestWriteln(SymToStr(it, isLocal = isLocal, section))
|
||||||
inc outputs
|
inc outputs
|
||||||
|
|
||||||
proc suggestSymList(c: PContext, list: PNode, outputs: var int) =
|
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) =
|
proc suggestEverything(c: PContext, n: PNode, outputs: var int) =
|
||||||
# do not produce too many symbols:
|
# do not produce too many symbols:
|
||||||
for i in countdown(c.tab.tos-1, 1):
|
var isLocal = true
|
||||||
for it in items(c.tab.stack[i]):
|
for scope in walkScopes(c):
|
||||||
|
if scope == c.topLevelScope: isLocal = false
|
||||||
|
for it in items(scope.symbols):
|
||||||
if filterSym(it):
|
if filterSym(it):
|
||||||
SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, sectionSuggest))
|
SuggestWriteln(SymToStr(it, isLocal = isLocal, sectionSuggest))
|
||||||
inc outputs
|
inc outputs
|
||||||
|
if scope == c.topLevelScope: break
|
||||||
|
|
||||||
proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
|
proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
|
||||||
# special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but
|
# 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.kind == nkSym and n.sym.kind == skModule:
|
||||||
if n.sym == c.module:
|
if n.sym == c.module:
|
||||||
# all symbols accessible, because we are in the current 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):
|
if filterSym(it):
|
||||||
SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest))
|
SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest))
|
||||||
inc outputs
|
inc outputs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue