Merge branch 'araq-better-pure-enums' into araq-better-codegen
This commit is contained in:
commit
dcfafb3289
6 changed files with 27 additions and 7 deletions
|
|
@ -60,6 +60,11 @@ proc checkModuleName*(n: PNode; doLocalError=true): int32 =
|
||||||
else:
|
else:
|
||||||
result = fullPath.fileInfoIdx
|
result = fullPath.fileInfoIdx
|
||||||
|
|
||||||
|
proc importPureEnumField*(c: PContext; s: PSym) =
|
||||||
|
var check = strTableGet(c.importTable.symbols, s.name)
|
||||||
|
if check == nil:
|
||||||
|
strTableAdd(c.pureEnumFields, s)
|
||||||
|
|
||||||
proc rawImportSymbol(c: PContext, s: PSym) =
|
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!
|
||||||
|
|
@ -75,7 +80,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||||
strTableAdd(c.importTable.symbols, 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}:
|
||||||
for j in countup(0, sonsLen(etyp.n) - 1):
|
for j in countup(0, sonsLen(etyp.n) - 1):
|
||||||
var e = etyp.n.sons[j].sym
|
var e = etyp.n.sons[j].sym
|
||||||
if e.kind != skEnumField:
|
if e.kind != skEnumField:
|
||||||
|
|
@ -91,7 +96,10 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||||
break
|
break
|
||||||
check = nextIdentIter(it, c.importTable.symbols)
|
check = nextIdentIter(it, c.importTable.symbols)
|
||||||
if e != nil:
|
if e != nil:
|
||||||
rawImportSymbol(c, e)
|
if sfPure notin s.flags:
|
||||||
|
rawImportSymbol(c, e)
|
||||||
|
else:
|
||||||
|
importPureEnumField(c, e)
|
||||||
else:
|
else:
|
||||||
# rodgen assures that converters and patterns are no stubs
|
# rodgen assures that converters and patterns are no stubs
|
||||||
if s.kind == skConverter: addConverter(c, s)
|
if s.kind == skConverter: addConverter(c, s)
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ proc lookUp*(c: PContext, n: PNode): PSym =
|
||||||
|
|
||||||
type
|
type
|
||||||
TLookupFlag* = enum
|
TLookupFlag* = enum
|
||||||
checkAmbiguity, checkUndeclared, checkModule
|
checkAmbiguity, checkUndeclared, checkModule, checkPureEnumFields
|
||||||
|
|
||||||
proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
|
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}
|
||||||
|
|
@ -297,6 +297,8 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
|
||||||
result = searchInScopes(c, ident).skipAlias(n)
|
result = searchInScopes(c, ident).skipAlias(n)
|
||||||
else:
|
else:
|
||||||
result = searchInScopes(c, ident, allExceptModule).skipAlias(n)
|
result = searchInScopes(c, ident, allExceptModule).skipAlias(n)
|
||||||
|
if result == nil and checkPureEnumFields in flags:
|
||||||
|
result = strTableGet(c.pureEnumFields, ident)
|
||||||
if result == nil and checkUndeclared in flags:
|
if result == nil and checkUndeclared in flags:
|
||||||
fixSpelling(n, ident, searchInScopes)
|
fixSpelling(n, ident, searchInScopes)
|
||||||
errorUndeclaredIdentifier(c, n.info, ident.s)
|
errorUndeclaredIdentifier(c, n.info, ident.s)
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ type
|
||||||
semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable,
|
semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable,
|
||||||
info: TLineInfo): PSym
|
info: TLineInfo): PSym
|
||||||
includedFiles*: IntSet # used to detect recursive include files
|
includedFiles*: IntSet # used to detect recursive include files
|
||||||
|
pureEnumFields*: TStrTable # pure enum fields that can be used unambiguously
|
||||||
userPragmas*: TStrTable
|
userPragmas*: TStrTable
|
||||||
evalContext*: PEvalContext
|
evalContext*: PEvalContext
|
||||||
unknownIdents*: IntSet # ids of all unknown identifiers to prevent
|
unknownIdents*: IntSet # ids of all unknown identifiers to prevent
|
||||||
|
|
@ -210,6 +211,7 @@ proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext
|
||||||
result.converters = @[]
|
result.converters = @[]
|
||||||
result.patterns = @[]
|
result.patterns = @[]
|
||||||
result.includedFiles = initIntSet()
|
result.includedFiles = initIntSet()
|
||||||
|
initStrTable(result.pureEnumFields)
|
||||||
initStrTable(result.userPragmas)
|
initStrTable(result.userPragmas)
|
||||||
result.generics = @[]
|
result.generics = @[]
|
||||||
result.unknownIdents = initIntSet()
|
result.unknownIdents = initIntSet()
|
||||||
|
|
|
||||||
|
|
@ -2115,8 +2115,10 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if nfSem in n.flags: return
|
if nfSem in n.flags: return
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
let checks = if efNoEvaluateGeneric in flags: {checkUndeclared}
|
let checks = if efNoEvaluateGeneric in flags:
|
||||||
else: {checkUndeclared, checkModule, checkAmbiguity}
|
{checkUndeclared, checkPureEnumFields}
|
||||||
|
else:
|
||||||
|
{checkUndeclared, checkModule, checkAmbiguity, checkPureEnumFields}
|
||||||
var s = qualifiedLookUp(c, n, checks)
|
var s = qualifiedLookUp(c, n, checks)
|
||||||
if c.matchedConcept == nil: semCaptureSym(s, c.p.owner)
|
if c.matchedConcept == nil: semCaptureSym(s, c.p.owner)
|
||||||
result = semSym(c, n, s, flags)
|
result = semSym(c, n, s, flags)
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,10 @@ proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||||
result = n
|
result = n
|
||||||
let ident = considerQuotedIdent(n)
|
let ident = considerQuotedIdent(n)
|
||||||
var s = searchInScopes(c, ident).skipAlias(n)
|
var s = searchInScopes(c, ident).skipAlias(n)
|
||||||
|
if s == nil:
|
||||||
|
s = strTableGet(c.pureEnumFields, ident)
|
||||||
|
if s != nil and contains(c.ambiguousSymbols, s.id):
|
||||||
|
s = nil
|
||||||
if s == nil:
|
if s == nil:
|
||||||
if ident.id notin ctx.toMixin and withinMixin notin flags:
|
if ident.id notin ctx.toMixin and withinMixin notin flags:
|
||||||
errorUndeclaredIdentifier(c, n.info, ident.s)
|
errorUndeclaredIdentifier(c, n.info, ident.s)
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if not isPure: strTableAdd(c.module.tab, e)
|
if not isPure: strTableAdd(c.module.tab, e)
|
||||||
addSon(result.n, newSymNode(e))
|
addSon(result.n, newSymNode(e))
|
||||||
styleCheckDef(e)
|
styleCheckDef(e)
|
||||||
if sfGenSym notin e.flags and not isPure: addDecl(c, e)
|
if sfGenSym notin e.flags:
|
||||||
|
if not isPure: addDecl(c, e)
|
||||||
|
else: importPureEnumField(c, e)
|
||||||
if isPure and strTableIncl(symbols, e):
|
if isPure and strTableIncl(symbols, e):
|
||||||
wrongRedefinition(e.info, e.name.s)
|
wrongRedefinition(e.info, e.name.s)
|
||||||
inc(counter)
|
inc(counter)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue