lookups compiles again

This commit is contained in:
Andreas Rumpf 2018-05-10 15:05:05 +02:00
commit e1a921ce4f
3 changed files with 80 additions and 81 deletions

View file

@ -188,7 +188,7 @@ errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlin
errInvalidNumberOfYieldExpr: "invalid number of 'yield' expressions", errInvalidNumberOfYieldExpr: "invalid number of 'yield' expressions",
errCannotReturnExpr: "current routine cannot return an expression", errCannotReturnExpr: "current routine cannot return an expression",
errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type", errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type",
errAttemptToRedefine: "redefinition of '$1'", errAttemptToRedefine: ,
errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma", errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma",
errStmtExpected: "statement expected", errStmtExpected: "statement expected",
errInvalidLabel: "'$1' is no label", errInvalidLabel: "'$1' is no label",
@ -283,7 +283,7 @@ errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters",
errXCannotBePassedToProcVar: "'$1' cannot be passed to a procvar", errXCannotBePassedToProcVar: "'$1' cannot be passed to a procvar",
errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1", errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1",
errImplOfXNotAllowed: "implementation of '$1' is not allowed", errImplOfXNotAllowed: "implementation of '$1' is not allowed",
errImplOfXexpected: "implementation of '$1' expected", errImplOfXexpected: ,
errNoSymbolToBorrowFromFound: "no symbol to borrow from found", errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
errDiscardValueX: "value of type '$1' has to be discarded", errDiscardValueX: "value of type '$1' has to be discarded",
errInvalidDiscard: "statement returns no value that can be discarded", errInvalidDiscard: "statement returns no value that can be discarded",

View file

@ -11,23 +11,23 @@
import import
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread, intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
renderer, wordrecg, idgen, nimfix.prettybase renderer, wordrecg, idgen, nimfix.prettybase, configuration, strutils
proc ensureNoMissingOrUnusedSymbols(scope: PScope) proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
proc noidentError(n, origin: PNode) = proc noidentError(conf: ConfigRef; n, origin: PNode) =
var m = "" var m = ""
if origin != nil: if origin != nil:
m.add "in expression '" & origin.renderTree & "': " m.add "in expression '" & origin.renderTree & "': "
m.add "identifier expected, but found '" & n.renderTree & "'" m.add "identifier expected, but found '" & n.renderTree & "'"
localError(n.info, m) localError(conf, n.info, m)
proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent = proc considerQuotedIdent*(conf: ConfigRef; n: PNode, origin: PNode = nil): PIdent =
## Retrieve a PIdent from a PNode, taking into account accent nodes. ## Retrieve a PIdent from a PNode, taking into account accent nodes.
## ``origin`` can be nil. If it is not nil, it is used for a better ## ``origin`` can be nil. If it is not nil, it is used for a better
## error message. ## error message.
template handleError(n, origin: PNode) = template handleError(n, origin: PNode) =
noidentError(n, origin) noidentError(conf, n, origin)
result = getIdent"<Error>" result = getIdent"<Error>"
case n.kind case n.kind
@ -36,7 +36,7 @@ proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent =
of nkAccQuoted: of nkAccQuoted:
case n.len case n.len
of 0: handleError(n, origin) of 0: handleError(n, origin)
of 1: result = considerQuotedIdent(n.sons[0], origin) of 1: result = considerQuotedIdent(conf, n.sons[0], origin)
else: else:
var id = "" var id = ""
for i in 0..<n.len: for i in 0..<n.len:
@ -71,7 +71,7 @@ proc rawCloseScope*(c: PContext) =
c.currentScope = c.currentScope.parent c.currentScope = c.currentScope.parent
proc closeScope*(c: PContext) = proc closeScope*(c: PContext) =
ensureNoMissingOrUnusedSymbols(c.currentScope) ensureNoMissingOrUnusedSymbols(c, c.currentScope)
rawCloseScope(c) rawCloseScope(c)
iterator walkScopes*(scope: PScope): PScope = iterator walkScopes*(scope: PScope): PScope =
@ -80,7 +80,7 @@ iterator walkScopes*(scope: PScope): PScope =
yield current yield current
current = current.parent current = current.parent
proc skipAlias*(s: PSym; n: PNode): PSym = proc skipAlias*(s: PSym; n: PNode; conf: ConfigRef): PSym =
if s == nil or s.kind != skAlias: if s == nil or s.kind != skAlias:
result = s result = s
else: else:
@ -88,7 +88,7 @@ proc skipAlias*(s: PSym; n: PNode): PSym =
if gCmd == cmdPretty: if gCmd == cmdPretty:
prettybase.replaceDeprecated(n.info, s, result) prettybase.replaceDeprecated(n.info, s, result)
else: else:
message(n.info, warnDeprecated, "use " & result.name.s & " instead; " & message(conf, n.info, warnDeprecated, "use " & result.name.s & " instead; " &
s.name.s) s.name.s)
proc localSearchInScope*(c: PContext, s: PIdent): PSym = proc localSearchInScope*(c: PContext, s: PIdent): PSym =
@ -125,7 +125,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
# ensure that 'considerQuotedIdent' can't fail: # ensure that 'considerQuotedIdent' can't fail:
if m.kind == nkDotExpr: m = m.sons[1] if m.kind == nkDotExpr: m = m.sons[1]
let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}: let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}:
considerQuotedIdent(m) considerQuotedIdent(c.config, m)
else: else:
getIdent("err:" & renderTree(m)) getIdent("err:" & renderTree(m))
result = newSym(skError, ident, getCurrOwner(c), n.info) result = newSym(skError, ident, getCurrOwner(c), n.info)
@ -154,7 +154,7 @@ proc getSymRepr*(s: PSym): string =
else: else:
result = s.name.s result = s.name.s
proc ensureNoMissingOrUnusedSymbols(scope: PScope) = proc ensureNoMissingOrUnusedSymbols(c: PContext; 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
var s = initTabIter(it, scope.symbols) var s = initTabIter(it, scope.symbols)
@ -164,54 +164,53 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
# too many 'implementation of X' errors are annoying # too many 'implementation of X' errors are annoying
# and slow 'suggest' down: # and slow 'suggest' down:
if missingImpls == 0: if missingImpls == 0:
localError(s.info, errImplOfXexpected, getSymRepr(s)) localError(c.config, s.info, "implementation of '$1' expected" % getSymRepr(s))
inc missingImpls inc missingImpls
elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options: elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options:
# BUGFIX: check options in s!
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
# XXX: implicit type params are currently skTypes # XXX: implicit type params are currently skTypes
# maybe they can be made skGenericParam as well. # maybe they can be made skGenericParam as well.
if s.typ != nil and tfImplicitTypeParam notin s.typ.flags and if s.typ != nil and tfImplicitTypeParam notin s.typ.flags and
s.typ.kind != tyGenericParam: s.typ.kind != tyGenericParam:
message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) message(c.config, s.info, hintXDeclaredButNotUsed, getSymRepr(s))
s = nextIter(it, scope.symbols) s = nextIter(it, scope.symbols)
proc wrongRedefinition*(info: TLineInfo, s: string) = proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string) =
if gCmd != cmdInteractive: if gCmd != cmdInteractive:
localError(info, errAttemptToRedefine, s) localError(c.config, info, "redefinition of '$1'" % s)
proc addDecl*(c: PContext, sym: PSym, info: TLineInfo) = proc addDecl*(c: PContext, sym: PSym, info: TLineInfo) =
if not c.currentScope.addUniqueSym(sym): if not c.currentScope.addUniqueSym(sym):
wrongRedefinition(info, sym.name.s) wrongRedefinition(c, info, sym.name.s)
proc addDecl*(c: PContext, sym: PSym) = proc addDecl*(c: PContext, sym: PSym) =
if not c.currentScope.addUniqueSym(sym): if not c.currentScope.addUniqueSym(sym):
wrongRedefinition(sym.info, sym.name.s) wrongRedefinition(c, sym.info, sym.name.s)
proc addPrelimDecl*(c: PContext, sym: PSym) = proc addPrelimDecl*(c: PContext, sym: PSym) =
discard c.currentScope.addUniqueSym(sym) discard c.currentScope.addUniqueSym(sym)
proc addDeclAt*(scope: PScope, sym: PSym) = proc addDeclAt*(c: PContext; scope: PScope, sym: PSym) =
if not scope.addUniqueSym(sym): if not scope.addUniqueSym(sym):
wrongRedefinition(sym.info, sym.name.s) wrongRedefinition(c, sym.info, sym.name.s)
proc addInterfaceDeclAux(c: PContext, sym: PSym) = proc addInterfaceDeclAux(c: PContext, sym: PSym) =
if sfExported in sym.flags: if sfExported in sym.flags:
# add to interface: # add to interface:
if c.module != nil: strTableAdd(c.module.tab, sym) if c.module != nil: strTableAdd(c.module.tab, sym)
else: internalError(sym.info, "addInterfaceDeclAux") else: internalError(c.config, sym.info, "addInterfaceDeclAux")
proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) = proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) =
addDeclAt(scope, sym) addDeclAt(c, scope, sym)
addInterfaceDeclAux(c, sym) addInterfaceDeclAux(c, sym)
proc addOverloadableSymAt*(scope: PScope, fn: PSym) = proc addOverloadableSymAt*(c: PContext; scope: PScope, fn: PSym) =
if fn.kind notin OverloadableSyms: if fn.kind notin OverloadableSyms:
internalError(fn.info, "addOverloadableSymAt") internalError(c.config, fn.info, "addOverloadableSymAt")
return return
let check = strTableGet(scope.symbols, fn.name) let check = strTableGet(scope.symbols, fn.name)
if check != nil and check.kind notin OverloadableSyms: if check != nil and check.kind notin OverloadableSyms:
wrongRedefinition(fn.info, fn.name.s) wrongRedefinition(c, fn.info, fn.name.s)
else: else:
scope.addSym(fn) scope.addSym(fn)
@ -222,12 +221,10 @@ proc addInterfaceDecl*(c: PContext, sym: PSym) =
proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) = proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
# it adds the symbol to the interface if appropriate # it adds the symbol to the interface if appropriate
addOverloadableSymAt(scope, sym) addOverloadableSymAt(c, scope, sym)
addInterfaceDeclAux(c, sym) addInterfaceDeclAux(c, sym)
when defined(nimfix): when defined(nimfix):
import strutils
# when we cannot find the identifier, retry with a changed identifer: # when we cannot find the identifier, retry with a changed identifer:
proc altSpelling(x: PIdent): PIdent = proc altSpelling(x: PIdent): PIdent =
case x.s[0] case x.s[0]
@ -255,7 +252,7 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
err.add candidate.owner.name.s & "." & candidate.name.s err.add candidate.owner.name.s & "." & candidate.name.s
candidate = nextIdentIter(ti, c.importTable.symbols) candidate = nextIdentIter(ti, c.importTable.symbols)
inc i inc i
localError(info, errGenerated, err) localError(c.config, info, errGenerated, err)
proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) = proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
var err = "undeclared identifier: '" & name & "'" var err = "undeclared identifier: '" & name & "'"
@ -264,13 +261,13 @@ proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
err.add c.recursiveDep err.add c.recursiveDep
# prevent excessive errors for 'nim check' # prevent excessive errors for 'nim check'
c.recursiveDep = nil c.recursiveDep = nil
localError(info, errGenerated, err) localError(c.config, info, errGenerated, err)
proc lookUp*(c: PContext, n: PNode): PSym = proc lookUp*(c: PContext, n: PNode): PSym =
# Looks up a symbol. Generates an error in case of nil. # Looks up a symbol. Generates an error in case of nil.
case n.kind case n.kind
of nkIdent: of nkIdent:
result = searchInScopes(c, n.ident).skipAlias(n) result = searchInScopes(c, n.ident).skipAlias(n, c.config)
if result == nil: if result == nil:
fixSpelling(n, n.ident, searchInScopes) fixSpelling(n, n.ident, searchInScopes)
errorUndeclaredIdentifier(c, n.info, n.ident.s) errorUndeclaredIdentifier(c, n.info, n.ident.s)
@ -278,14 +275,14 @@ proc lookUp*(c: PContext, n: PNode): PSym =
of nkSym: of nkSym:
result = n.sym result = n.sym
of nkAccQuoted: of nkAccQuoted:
var ident = considerQuotedIdent(n) var ident = considerQuotedIdent(c.config, n)
result = searchInScopes(c, ident).skipAlias(n) result = searchInScopes(c, ident).skipAlias(n, c.config)
if result == nil: if result == nil:
fixSpelling(n, ident, searchInScopes) fixSpelling(n, ident, searchInScopes)
errorUndeclaredIdentifier(c, n.info, ident.s) errorUndeclaredIdentifier(c, n.info, ident.s)
result = errorSym(c, n) result = errorSym(c, n)
else: else:
internalError(n.info, "lookUp") internalError(c.config, n.info, "lookUp")
return return
if contains(c.ambiguousSymbols, result.id): if contains(c.ambiguousSymbols, result.id):
errorUseQualifier(c, n.info, result) errorUseQualifier(c, n.info, result)
@ -299,11 +296,11 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
const allExceptModule = {low(TSymKind)..high(TSymKind)}-{skModule,skPackage} const allExceptModule = {low(TSymKind)..high(TSymKind)}-{skModule,skPackage}
case n.kind case n.kind
of nkIdent, nkAccQuoted: of nkIdent, nkAccQuoted:
var ident = considerQuotedIdent(n) var ident = considerQuotedIdent(c.config, n)
if checkModule in flags: if checkModule in flags:
result = searchInScopes(c, ident).skipAlias(n) result = searchInScopes(c, ident).skipAlias(n, c.config)
else: else:
result = searchInScopes(c, ident, allExceptModule).skipAlias(n) result = searchInScopes(c, ident, allExceptModule).skipAlias(n, c.config)
if result == nil and checkPureEnumFields in flags: if result == nil and checkPureEnumFields in flags:
result = strTableGet(c.pureEnumFields, ident) result = strTableGet(c.pureEnumFields, ident)
if result == nil and checkUndeclared in flags: if result == nil and checkUndeclared in flags:
@ -325,12 +322,12 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
if n.sons[1].kind == nkIdent: if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted: elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(n.sons[1]) ident = considerQuotedIdent(c.config, n.sons[1])
if ident != nil: if ident != nil:
if m == c.module: if m == c.module:
result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n) result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n, c.config)
else: else:
result = strTableGet(m.tab, ident).skipAlias(n) result = strTableGet(m.tab, ident).skipAlias(n, c.config)
if result == nil and checkUndeclared in flags: if result == nil and checkUndeclared in flags:
fixSpelling(n.sons[1], ident, searchInScopes) fixSpelling(n.sons[1], ident, searchInScopes)
errorUndeclaredIdentifier(c, n.sons[1].info, ident.s) errorUndeclaredIdentifier(c, n.sons[1].info, ident.s)
@ -339,7 +336,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
result = n.sons[1].sym result = n.sons[1].sym
elif checkUndeclared in flags and elif checkUndeclared in flags and
n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}: n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
localError(n.sons[1].info, errIdentifierExpected, localError(c.config, n.sons[1].info, "identifier expected, but got: " &
renderTree(n.sons[1])) renderTree(n.sons[1]))
result = errorSym(c, n.sons[1]) result = errorSym(c, n.sons[1])
else: else:
@ -349,11 +346,11 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
case n.kind case n.kind
of nkIdent, nkAccQuoted: of nkIdent, nkAccQuoted:
var ident = considerQuotedIdent(n) var ident = considerQuotedIdent(c.config, n)
o.scope = c.currentScope o.scope = c.currentScope
o.mode = oimNoQualifier o.mode = oimNoQualifier
while true: while true:
result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n) result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n, c.config)
if result != nil: if result != nil:
break break
else: else:
@ -370,17 +367,17 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
if n.sons[1].kind == nkIdent: if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted: elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(n.sons[1], n) ident = considerQuotedIdent(c.config, n.sons[1], n)
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.topLevelScope.symbols, result = initIdentIter(o.it, c.topLevelScope.symbols,
ident).skipAlias(n) ident).skipAlias(n, c.config)
o.mode = oimSelfModule o.mode = oimSelfModule
else: else:
result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n) result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n, c.config)
else: else:
noidentError(n.sons[1], n) noidentError(c.config, n.sons[1], n)
result = errorSym(c, n.sons[1]) result = errorSym(c, n.sons[1])
of nkClosedSymChoice, nkOpenSymChoice: of nkClosedSymChoice, nkOpenSymChoice:
o.mode = oimSymChoice o.mode = oimSymChoice
@ -408,18 +405,18 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
result = nil result = nil
of oimNoQualifier: of oimNoQualifier:
if o.scope != nil: if o.scope != nil:
result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n) result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n, c.config)
while result == nil: while result == nil:
o.scope = o.scope.parent o.scope = o.scope.parent
if o.scope == nil: break if o.scope == nil: break
result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n) result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n, c.config)
# BUGFIX: o.it.name <-> n.ident # BUGFIX: o.it.name <-> n.ident
else: else:
result = nil result = nil
of oimSelfModule: of oimSelfModule:
result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n) result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n, c.config)
of oimOtherModule: of oimOtherModule:
result = nextIdentIter(o.it, o.m.tab).skipAlias(n) result = nextIdentIter(o.it, o.m.tab).skipAlias(n, c.config)
of oimSymChoice: of oimSymChoice:
if o.symChoiceIndex < sonsLen(n): if o.symChoiceIndex < sonsLen(n):
result = n.sons[o.symChoiceIndex].sym result = n.sons[o.symChoiceIndex].sym
@ -430,19 +427,19 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.mode = oimSymChoiceLocalLookup o.mode = oimSymChoiceLocalLookup
o.scope = c.currentScope o.scope = c.currentScope
result = firstIdentExcluding(o.it, o.scope.symbols, result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n) n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
while result == nil: while result == nil:
o.scope = o.scope.parent o.scope = o.scope.parent
if o.scope == nil: break if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols, result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n) n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
of oimSymChoiceLocalLookup: of oimSymChoiceLocalLookup:
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n) result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n, c.config)
while result == nil: while result == nil:
o.scope = o.scope.parent o.scope = o.scope.parent
if o.scope == nil: break if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols, result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n) n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
if result != nil and result.kind == skStub: loadStub(result) if result != nil and result.kind == skStub: loadStub(result)

View file

@ -14,7 +14,7 @@ import
wordrecg, wordrecg,
ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math, ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
magicsys, nversion, nimsets, parser, times, passes, rodread, vmdef, magicsys, nversion, nimsets, parser, times, passes, rodread, vmdef,
modulegraphs modulegraphs, configuration
type type
TOptionEntry* = object # entries to put on a stack for pragma parsing TOptionEntry* = object # entries to put on a stack for pragma parsing
@ -139,6 +139,8 @@ type
# would otherwise fail. # would otherwise fail.
runnableExamples*: PNode runnableExamples*: PNode
template config*(c: PContext): ConfigRef = c.graph.config
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
result.genericSym = s result.genericSym = s
result.inst = inst result.inst = inst
@ -164,7 +166,7 @@ proc pushOwner*(c: PContext; owner: PSym) =
proc popOwner*(c: PContext) = proc popOwner*(c: PContext) =
var length = len(c.graph.owners) var length = len(c.graph.owners)
if length > 0: setLen(c.graph.owners, length - 1) if length > 0: setLen(c.graph.owners, length - 1)
else: internalError("popOwner") else: internalError(c.config, "popOwner")
proc lastOptionEntry*(c: PContext): POptionEntry = proc lastOptionEntry*(c: PContext): POptionEntry =
result = c.optionStack[^1] result = c.optionStack[^1]
@ -200,19 +202,19 @@ proc considerGenSyms*(c: PContext; n: PNode) =
for i in 0..<n.safeLen: for i in 0..<n.safeLen:
considerGenSyms(c, n.sons[i]) considerGenSyms(c, n.sons[i])
proc newOptionEntry*(): POptionEntry = proc newOptionEntry*(conf: ConfigRef): POptionEntry =
new(result) new(result)
result.options = gOptions result.options = gOptions
result.defaultCC = ccDefault result.defaultCC = ccDefault
result.dynlib = nil result.dynlib = nil
result.notes = gNotes result.notes = conf.notes
proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext = proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext =
new(result) new(result)
result.ambiguousSymbols = initIntSet() result.ambiguousSymbols = initIntSet()
result.optionStack = @[] result.optionStack = @[]
result.libs = @[] result.libs = @[]
result.optionStack.add(newOptionEntry()) result.optionStack.add(newOptionEntry(graph.config))
result.module = module result.module = module
result.friendModules = @[module] result.friendModules = @[module]
result.converters = @[] result.converters = @[]
@ -255,7 +257,7 @@ proc newTypeS*(kind: TTypeKind, c: PContext): PType =
proc makePtrType*(c: PContext, baseType: PType): PType = proc makePtrType*(c: PContext, baseType: PType): PType =
result = newTypeS(tyPtr, c) result = newTypeS(tyPtr, c)
addSonSkipIntLit(result, baseType.assertNotNil) addSonSkipIntLit(result, baseType)
proc makeTypeWithModifier*(c: PContext, proc makeTypeWithModifier*(c: PContext,
modifier: TTypeKind, modifier: TTypeKind,
@ -266,21 +268,21 @@ proc makeTypeWithModifier*(c: PContext,
result = baseType result = baseType
else: else:
result = newTypeS(modifier, c) result = newTypeS(modifier, c)
addSonSkipIntLit(result, baseType.assertNotNil) addSonSkipIntLit(result, baseType)
proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType = proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
if baseType.kind == kind: if baseType.kind == kind:
result = baseType result = baseType
else: else:
result = newTypeS(kind, c) result = newTypeS(kind, c)
addSonSkipIntLit(result, baseType.assertNotNil) addSonSkipIntLit(result, baseType)
proc makeTypeDesc*(c: PContext, typ: PType): PType = proc makeTypeDesc*(c: PContext, typ: PType): PType =
if typ.kind == tyTypeDesc: if typ.kind == tyTypeDesc:
result = typ result = typ
else: else:
result = newTypeS(tyTypeDesc, c) result = newTypeS(tyTypeDesc, c)
result.addSonSkipIntLit(typ.assertNotNil) result.addSonSkipIntLit(typ)
proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
let typedesc = makeTypeDesc(c, typ) let typedesc = makeTypeDesc(c, typ)
@ -339,21 +341,20 @@ proc makeNotType*(c: PContext, t1: PType): PType =
result.flags.incl(t1.flags * {tfHasStatic}) result.flags.incl(t1.flags * {tfHasStatic})
result.flags.incl tfHasMeta result.flags.incl tfHasMeta
proc nMinusOne*(n: PNode): PNode = proc nMinusOne(c: PContext; n: PNode): PNode =
result = newNode(nkCall, n.info, @[ result = newNode(nkCall, n.info, @[
newSymNode(getSysMagic("pred", mPred)), newSymNode(getSysMagic(c.graph, n.info, "pred", mPred)), n])
n])
# Remember to fix the procs below this one when you make changes! # Remember to fix the procs below this one when you make changes!
proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType = proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
let intType = getSysType(tyInt) let intType = getSysType(c.graph, n.info, tyInt)
result = newTypeS(tyRange, c) result = newTypeS(tyRange, c)
result.sons = @[intType] result.sons = @[intType]
if n.typ != nil and n.typ.n == nil: if n.typ != nil and n.typ.n == nil:
result.flags.incl tfUnresolved result.flags.incl tfUnresolved
result.n = newNode(nkRange, n.info, @[ result.n = newNode(nkRange, n.info, @[
newIntTypeNode(nkIntLit, 0, intType), newIntTypeNode(nkIntLit, 0, intType),
makeStaticExpr(c, n.nMinusOne)]) makeStaticExpr(c, nMinusOne(c, n))])
template rangeHasUnresolvedStatic*(t: PType): bool = template rangeHasUnresolvedStatic*(t: PType): bool =
tfUnresolved in t.flags tfUnresolved in t.flags
@ -372,7 +373,8 @@ proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) =
dest.size = - 1 dest.size = - 1
proc makeRangeType*(c: PContext; first, last: BiggestInt; proc makeRangeType*(c: PContext; first, last: BiggestInt;
info: TLineInfo; intType = getSysType(tyInt)): PType = info: TLineInfo; intType: PType = nil): PType =
let intType = if intType != nil: intType else: getSysType(c.graph, info, tyInt)
var n = newNodeI(nkRange, info) var n = newNodeI(nkRange, info)
addSon(n, newIntTypeNode(nkIntLit, first, intType)) addSon(n, newIntTypeNode(nkIntLit, first, intType))
addSon(n, newIntTypeNode(nkIntLit, last, intType)) addSon(n, newIntTypeNode(nkIntLit, last, intType))
@ -385,17 +387,17 @@ proc markIndirect*(c: PContext, s: PSym) {.inline.} =
incl(s.flags, sfAddrTaken) incl(s.flags, sfAddrTaken)
# XXX add to 'c' for global analysis # XXX add to 'c' for global analysis
proc illFormedAst*(n: PNode) = proc illFormedAst*(n: PNode; conf: ConfigRef) =
globalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) globalError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc illFormedAstLocal*(n: PNode) = proc illFormedAstLocal*(n: PNode; conf: ConfigRef) =
localError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) localError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc checkSonsLen*(n: PNode, length: int) = proc checkSonsLen*(n: PNode, length: int; conf: ConfigRef) =
if sonsLen(n) != length: illFormedAst(n) if sonsLen(n) != length: illFormedAst(n, conf)
proc checkMinSonsLen*(n: PNode, length: int) = proc checkMinSonsLen*(n: PNode, length: int; conf: ConfigRef) =
if sonsLen(n) < length: illFormedAst(n) if sonsLen(n) < length: illFormedAst(n, conf)
proc isTopLevel*(c: PContext): bool {.inline.} = proc isTopLevel*(c: PContext): bool {.inline.} =
result = c.currentScope.depthLevel <= 2 result = c.currentScope.depthLevel <= 2