sem pass compiles again
This commit is contained in:
parent
dd35111ff2
commit
050789a8f4
12 changed files with 269 additions and 263 deletions
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
template detectVersion(field, corename) =
|
template detectVersion(field, corename) =
|
||||||
if m.g.field == 0:
|
if m.g.field == 0:
|
||||||
let core = getCompilerProc(corename)
|
let core = getCompilerProc(m.g. corename)
|
||||||
if core == nil or core.kind != skConst:
|
if core == nil or core.kind != skConst:
|
||||||
m.g.field = 1
|
m.g.field = 1
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -45,28 +45,28 @@ const
|
||||||
]
|
]
|
||||||
NimMergeEndMark = "/*\tNIM_merge_END:*/"
|
NimMergeEndMark = "/*\tNIM_merge_END:*/"
|
||||||
|
|
||||||
proc genSectionStart*(fs: TCFileSection): Rope =
|
proc genSectionStart*(fs: TCFileSection; conf: ConfigRef): Rope =
|
||||||
if compilationCachePresent:
|
if compilationCachePresent(conf):
|
||||||
result = rope(tnl)
|
result = rope(tnl)
|
||||||
add(result, "/*\t")
|
add(result, "/*\t")
|
||||||
add(result, CFileSectionNames[fs])
|
add(result, CFileSectionNames[fs])
|
||||||
add(result, ":*/")
|
add(result, ":*/")
|
||||||
add(result, tnl)
|
add(result, tnl)
|
||||||
|
|
||||||
proc genSectionEnd*(fs: TCFileSection): Rope =
|
proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope =
|
||||||
if compilationCachePresent:
|
if compilationCachePresent(conf):
|
||||||
result = rope(NimMergeEndMark & tnl)
|
result = rope(NimMergeEndMark & tnl)
|
||||||
|
|
||||||
proc genSectionStart*(ps: TCProcSection): Rope =
|
proc genSectionStart*(ps: TCProcSection; conf: ConfigRef): Rope =
|
||||||
if compilationCachePresent:
|
if compilationCachePresent(conf):
|
||||||
result = rope(tnl)
|
result = rope(tnl)
|
||||||
add(result, "/*\t")
|
add(result, "/*\t")
|
||||||
add(result, CProcSectionNames[ps])
|
add(result, CProcSectionNames[ps])
|
||||||
add(result, ":*/")
|
add(result, ":*/")
|
||||||
add(result, tnl)
|
add(result, tnl)
|
||||||
|
|
||||||
proc genSectionEnd*(ps: TCProcSection): Rope =
|
proc genSectionEnd*(ps: TCProcSection; conf: ConfigRef): Rope =
|
||||||
if compilationCachePresent:
|
if compilationCachePresent(conf):
|
||||||
result = rope(NimMergeEndMark & tnl)
|
result = rope(NimMergeEndMark & tnl)
|
||||||
|
|
||||||
proc writeTypeCache(a: TypeCache, s: var string) =
|
proc writeTypeCache(a: TypeCache, s: var string) =
|
||||||
|
|
@ -96,7 +96,7 @@ proc writeIntSet(a: IntSet, s: var string) =
|
||||||
s.add('}')
|
s.add('}')
|
||||||
|
|
||||||
proc genMergeInfo*(m: BModule): Rope =
|
proc genMergeInfo*(m: BModule): Rope =
|
||||||
if not compilationCachePresent: return nil
|
if not compilationCachePresent(m.config): return nil
|
||||||
var s = "/*\tNIM_merge_INFO:"
|
var s = "/*\tNIM_merge_INFO:"
|
||||||
s.add(tnl)
|
s.add(tnl)
|
||||||
s.add("typeCache:{")
|
s.add("typeCache:{")
|
||||||
|
|
@ -161,7 +161,7 @@ proc readVerbatimSection(L: var TBaseLexer): Rope =
|
||||||
buf = L.buf
|
buf = L.buf
|
||||||
r.add(tnl)
|
r.add(tnl)
|
||||||
of '\0':
|
of '\0':
|
||||||
internalError("ccgmerge: expected: " & NimMergeEndMark)
|
doAssert(false, "ccgmerge: expected: " & NimMergeEndMark)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if atEndMark(buf, pos):
|
if atEndMark(buf, pos):
|
||||||
|
|
@ -179,7 +179,7 @@ proc readKey(L: var TBaseLexer, result: var string) =
|
||||||
while buf[pos] in IdentChars:
|
while buf[pos] in IdentChars:
|
||||||
result.add(buf[pos])
|
result.add(buf[pos])
|
||||||
inc pos
|
inc pos
|
||||||
if buf[pos] != ':': internalError("ccgmerge: ':' expected")
|
if buf[pos] != ':': doAssert(false, "ccgmerge: ':' expected")
|
||||||
L.bufpos = pos + 1 # skip ':'
|
L.bufpos = pos + 1 # skip ':'
|
||||||
|
|
||||||
proc newFakeType(id: int): PType =
|
proc newFakeType(id: int): PType =
|
||||||
|
|
@ -187,12 +187,12 @@ proc newFakeType(id: int): PType =
|
||||||
result.id = id
|
result.id = id
|
||||||
|
|
||||||
proc readTypeCache(L: var TBaseLexer, result: var TypeCache) =
|
proc readTypeCache(L: var TBaseLexer, result: var TypeCache) =
|
||||||
if ^L.bufpos != '{': internalError("ccgmerge: '{' expected")
|
if ^L.bufpos != '{': doAssert(false, "ccgmerge: '{' expected")
|
||||||
inc L.bufpos
|
inc L.bufpos
|
||||||
while ^L.bufpos != '}':
|
while ^L.bufpos != '}':
|
||||||
skipWhite(L)
|
skipWhite(L)
|
||||||
var key = decodeStr(L.buf, L.bufpos)
|
var key = decodeStr(L.buf, L.bufpos)
|
||||||
if ^L.bufpos != ':': internalError("ccgmerge: ':' expected")
|
if ^L.bufpos != ':': doAssert(false, "ccgmerge: ':' expected")
|
||||||
inc L.bufpos
|
inc L.bufpos
|
||||||
var value = decodeStr(L.buf, L.bufpos)
|
var value = decodeStr(L.buf, L.bufpos)
|
||||||
# XXX implement me
|
# XXX implement me
|
||||||
|
|
@ -201,7 +201,7 @@ proc readTypeCache(L: var TBaseLexer, result: var TypeCache) =
|
||||||
inc L.bufpos
|
inc L.bufpos
|
||||||
|
|
||||||
proc readIntSet(L: var TBaseLexer, result: var IntSet) =
|
proc readIntSet(L: var TBaseLexer, result: var IntSet) =
|
||||||
if ^L.bufpos != '{': internalError("ccgmerge: '{' expected")
|
if ^L.bufpos != '{': doAssert(false, "ccgmerge: '{' expected")
|
||||||
inc L.bufpos
|
inc L.bufpos
|
||||||
while ^L.bufpos != '}':
|
while ^L.bufpos != '}':
|
||||||
skipWhite(L)
|
skipWhite(L)
|
||||||
|
|
@ -225,7 +225,7 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) =
|
||||||
of "labels": m.labels = decodeVInt(L.buf, L.bufpos)
|
of "labels": m.labels = decodeVInt(L.buf, L.bufpos)
|
||||||
of "flags":
|
of "flags":
|
||||||
m.flags = cast[set[CodegenFlag]](decodeVInt(L.buf, L.bufpos) != 0)
|
m.flags = cast[set[CodegenFlag]](decodeVInt(L.buf, L.bufpos) != 0)
|
||||||
else: internalError("ccgmerge: unknown key: " & k)
|
else: doAssert(false, "ccgmerge: unknown key: " & k)
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
when not defined(nimhygiene):
|
||||||
{.pragma: inject.}
|
{.pragma: inject.}
|
||||||
|
|
@ -275,9 +275,9 @@ proc readMergeSections(cfilename: string, m: var TMergeSections) =
|
||||||
if sectionB >= 0 and sectionB <= high(TCProcSection).int:
|
if sectionB >= 0 and sectionB <= high(TCProcSection).int:
|
||||||
m.p[TCProcSection(sectionB)] = verbatim
|
m.p[TCProcSection(sectionB)] = verbatim
|
||||||
else:
|
else:
|
||||||
internalError("ccgmerge: unknown section: " & k)
|
doAssert(false, "ccgmerge: unknown section: " & k)
|
||||||
else:
|
else:
|
||||||
internalError("ccgmerge: '*/' expected")
|
doAssert(false, "ccgmerge: '*/' expected")
|
||||||
|
|
||||||
proc mergeRequired*(m: BModule): bool =
|
proc mergeRequired*(m: BModule): bool =
|
||||||
for i in cfsHeaders..cfsProcs:
|
for i in cfsHeaders..cfsProcs:
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope =
|
||||||
if i >= length or not (frmt[i] in {'0'..'9'}): break
|
if i >= length or not (frmt[i] in {'0'..'9'}): break
|
||||||
num = j
|
num = j
|
||||||
if j > high(args) + 1:
|
if j > high(args) + 1:
|
||||||
internalError("ropes: invalid format string $" & $j)
|
internalError(m.config, "ropes: invalid format string $" & $j)
|
||||||
add(result, args[j-1])
|
add(result, args[j-1])
|
||||||
of 'n':
|
of 'n':
|
||||||
if optLineDir notin gOptions: add(result, rnl)
|
if optLineDir notin gOptions: add(result, rnl)
|
||||||
|
|
@ -123,7 +123,7 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope =
|
||||||
of 'N':
|
of 'N':
|
||||||
add(result, rnl)
|
add(result, rnl)
|
||||||
inc(i)
|
inc(i)
|
||||||
else: internalError("ropes: invalid format string $" & frmt[i])
|
else: internalError(m.config, "ropes: invalid format string $" & frmt[i])
|
||||||
elif frmt[i] == '#' and frmt[i+1] in IdentStartChars:
|
elif frmt[i] == '#' and frmt[i+1] in IdentStartChars:
|
||||||
inc(i)
|
inc(i)
|
||||||
var j = i
|
var j = i
|
||||||
|
|
@ -148,12 +148,10 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope =
|
||||||
template rfmt(m: BModule, fmt: string, args: varargs[Rope]): untyped =
|
template rfmt(m: BModule, fmt: string, args: varargs[Rope]): untyped =
|
||||||
ropecg(m, fmt, args)
|
ropecg(m, fmt, args)
|
||||||
|
|
||||||
var indent = "\t".rope
|
|
||||||
|
|
||||||
proc indentLine(p: BProc, r: Rope): Rope =
|
proc indentLine(p: BProc, r: Rope): Rope =
|
||||||
result = r
|
result = r
|
||||||
for i in countup(0, p.blocks.len-1):
|
for i in countup(0, p.blocks.len-1):
|
||||||
prepend(result, indent)
|
prepend(result, "\t".rope)
|
||||||
|
|
||||||
proc appcg(m: BModule, c: var Rope, frmt: FormatStr,
|
proc appcg(m: BModule, c: var Rope, frmt: FormatStr,
|
||||||
args: varargs[Rope]) =
|
args: varargs[Rope]) =
|
||||||
|
|
@ -214,7 +212,7 @@ proc genLineDir(p: BProc, t: PNode) =
|
||||||
let line = tt.info.safeLineNm
|
let line = tt.info.safeLineNm
|
||||||
|
|
||||||
if optEmbedOrigSrc in gGlobalOptions:
|
if optEmbedOrigSrc in gGlobalOptions:
|
||||||
add(p.s(cpsStmts), ~"//" & tt.info.sourceLine & rnl)
|
add(p.s(cpsStmts), ~"//" & sourceLine(p.config, tt.info) & rnl)
|
||||||
genCLineDir(p.s(cpsStmts), tt.info.toFullPath, line)
|
genCLineDir(p.s(cpsStmts), tt.info.toFullPath, line)
|
||||||
if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
|
if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
|
||||||
(p.prc == nil or sfPure notin p.prc.flags):
|
(p.prc == nil or sfPure notin p.prc.flags):
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,9 @@ type
|
||||||
g*: BModuleList
|
g*: BModuleList
|
||||||
ndi*: NdiFile
|
ndi*: NdiFile
|
||||||
|
|
||||||
|
template config*(m: BModule): ConfigRef = m.g.config
|
||||||
|
template config*(p: BProc): ConfigRef = p.module.g.config
|
||||||
|
|
||||||
proc includeHeader*(this: BModule; header: string) =
|
proc includeHeader*(this: BModule; header: string) =
|
||||||
if not this.headerFiles.contains header:
|
if not this.headerFiles.contains header:
|
||||||
this.headerFiles.add header
|
this.headerFiles.add header
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ errExecutionOfProgramFailed: "execution of an external program failed: '$1'",
|
||||||
errNotOverloadable: ,
|
errNotOverloadable: ,
|
||||||
errInvalidArgForX: "invalid argument for '$1'",
|
errInvalidArgForX: "invalid argument for '$1'",
|
||||||
errStmtHasNoEffect: "statement has no effect",
|
errStmtHasNoEffect: "statement has no effect",
|
||||||
errXExpectsTypeOrValue: "'$1' expects a type or value",
|
,
|
||||||
errXExpectsArrayType: "'$1' expects an array type",
|
errXExpectsArrayType: "'$1' expects an array type",
|
||||||
errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet",
|
errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet",
|
||||||
errExprXAmbiguous: "expression '$1' ambiguous in this context",
|
errExprXAmbiguous: "expression '$1' ambiguous in this context",
|
||||||
|
|
@ -229,19 +229,17 @@ errOverOrUnderflow: ,
|
||||||
errCannotEvalXBecauseIncompletelyDefined: ,
|
errCannotEvalXBecauseIncompletelyDefined: ,
|
||||||
errChrExpectsRange0_255: "'chr' expects an int in the range 0..255",
|
errChrExpectsRange0_255: "'chr' expects an int in the range 0..255",
|
||||||
errDynlibRequiresExportc: "'dynlib' requires 'exportc'",
|
errDynlibRequiresExportc: "'dynlib' requires 'exportc'",
|
||||||
errUndeclaredFieldX: "undeclared field: '$1'",
|
|
||||||
errNilAccess: "attempt to access a nil address",
|
errNilAccess: "attempt to access a nil address",
|
||||||
errIndexOutOfBounds: "index out of bounds",
|
errIndexOutOfBounds: "index out of bounds",
|
||||||
errIndexTypesDoNotMatch: "index types do not match",
|
errIndexTypesDoNotMatch: "index types do not match",
|
||||||
errBracketsInvalidForType: "'[]' operator invalid for this type",
|
errBracketsInvalidForType: "'[]' operator invalid for this type",
|
||||||
errValueOutOfSetBounds: "value out of set bounds",
|
errValueOutOfSetBounds: "value out of set bounds",
|
||||||
errFieldInitTwice: "field initialized twice: '$1'",
|
|
||||||
errFieldNotInit: "field '$1' not initialized",
|
errFieldNotInit: "field '$1' not initialized",
|
||||||
errExprXCannotBeCalled: "expression '$1' cannot be called",
|
errExprXCannotBeCalled: "expression '$1' cannot be called",
|
||||||
errExprHasNoType: "expression has no type",
|
errExprHasNoType: "expression has no type",
|
||||||
errExprXHasNoType: "expression '$1' has no type (or is ambiguous)",
|
errExprXHasNoType:,
|
||||||
errCastNotInSafeMode: "'cast' not allowed in safe mode",
|
errCastNotInSafeMode: "'cast' not allowed in safe mode",
|
||||||
errExprCannotBeCastToX: "expression cannot be cast to $1",
|
errExprCannotBeCastToX: ,
|
||||||
errCommaOrParRiExpected: "',' or ')' expected",
|
errCommaOrParRiExpected: "',' or ')' expected",
|
||||||
errCurlyLeOrParLeExpected: "'{' or '(' expected",
|
errCurlyLeOrParLeExpected: "'{' or '(' expected",
|
||||||
errSectionExpected: "section ('type', 'proc', etc.) expected",
|
errSectionExpected: "section ('type', 'proc', etc.) expected",
|
||||||
|
|
@ -268,10 +266,6 @@ errSizeTooBig: "computing the type's size produced an overflow",
|
||||||
errInheritanceOnlyWithEnums: "inheritance only works with an enum",
|
errInheritanceOnlyWithEnums: "inheritance only works with an enum",
|
||||||
errIllegalRecursionInTypeX:,
|
errIllegalRecursionInTypeX:,
|
||||||
errCannotInstantiateX: "cannot instantiate: '$1'",
|
errCannotInstantiateX: "cannot instantiate: '$1'",
|
||||||
errExprHasNoAddress: "expression has no address",
|
|
||||||
errXStackEscape: "address of '$1' may not escape its stack frame",
|
|
||||||
errVarForOutParamNeededX: "for a 'var' type a variable needs to be passed; but '$1' is immutable",
|
|
||||||
errPureTypeMismatch: "type mismatch",
|
|
||||||
errTypeMismatch: "type mismatch: got <",
|
errTypeMismatch: "type mismatch: got <",
|
||||||
errButExpected: "but expected one of: ",
|
errButExpected: "but expected one of: ",
|
||||||
errButExpectedX: "but expected '$1'",
|
errButExpectedX: "but expected '$1'",
|
||||||
|
|
@ -285,7 +279,7 @@ errImplOfXexpected: ,
|
||||||
|
|
||||||
errIllegalConvFromXtoY: ,
|
errIllegalConvFromXtoY: ,
|
||||||
errCannotBindXTwice: "cannot bind parameter '$1' twice",
|
errCannotBindXTwice: "cannot bind parameter '$1' twice",
|
||||||
errInvalidOrderInArrayConstructor: "invalid order in array constructor",
|
errInvalidOrderInArrayConstructor: ,
|
||||||
errInvalidOrderInEnumX: "invalid order in enum '$1'",
|
errInvalidOrderInEnumX: "invalid order in enum '$1'",
|
||||||
errEnumXHasHoles: "enum '$1' has holes",
|
errEnumXHasHoles: "enum '$1' has holes",
|
||||||
errExceptExpected: "'except' or 'finally' expected",
|
errExceptExpected: "'except' or 'finally' expected",
|
||||||
|
|
@ -310,8 +304,7 @@ errCircumNeedsPointer: "'[]' needs a pointer or reference type",
|
||||||
errInvalidExpression: "invalid expression",
|
errInvalidExpression: "invalid expression",
|
||||||
errInvalidExpressionX: "invalid expression: '$1'",
|
errInvalidExpressionX: "invalid expression: '$1'",
|
||||||
errEnumHasNoValueX: "enum has no value '$1'",
|
errEnumHasNoValueX: "enum has no value '$1'",
|
||||||
errNamedExprExpected: "named expression expected",
|
,
|
||||||
errNamedExprNotAllowed: "named expression not allowed here",
|
|
||||||
errNoCommand: "no command given",
|
errNoCommand: "no command given",
|
||||||
errInvalidCommandX: "invalid command: '$1'",
|
errInvalidCommandX: "invalid command: '$1'",
|
||||||
errXNeedsParamObjectType: ,
|
errXNeedsParamObjectType: ,
|
||||||
|
|
@ -347,7 +340,6 @@ errXcanNeverBeOfThisSubtype: "'$1' can never be of this subtype",
|
||||||
errTooManyIterations: "interpretation requires too many iterations; " &
|
errTooManyIterations: "interpretation requires too many iterations; " &
|
||||||
"if you are sure this is not a bug in your code edit " &
|
"if you are sure this is not a bug in your code edit " &
|
||||||
"compiler/vmdef.MaxLoopIterations and rebuild the compiler",
|
"compiler/vmdef.MaxLoopIterations and rebuild the compiler",
|
||||||
errCannotInterpretNodeX: "cannot evaluate '$1'",
|
|
||||||
errFieldXNotFound: "field '$1' cannot be found",
|
errFieldXNotFound: "field '$1' cannot be found",
|
||||||
errInvalidConversionFromTypeX: "invalid conversion from type '$1'",
|
errInvalidConversionFromTypeX: "invalid conversion from type '$1'",
|
||||||
errAssertionFailed: "assertion failed",
|
errAssertionFailed: "assertion failed",
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import
|
||||||
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread,
|
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread,
|
||||||
modulegraphs
|
modulegraphs
|
||||||
|
|
||||||
|
export createMagic
|
||||||
|
|
||||||
proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt]
|
proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt]
|
||||||
|
|
||||||
proc registerSysType*(g: ModuleGraph; t: PType) =
|
proc registerSysType*(g: ModuleGraph; t: PType) =
|
||||||
|
|
@ -32,9 +34,10 @@ proc getSysSym*(g: ModuleGraph; info: TLineInfo; name: string): PSym =
|
||||||
if result.kind == skStub: loadStub(result)
|
if result.kind == skStub: loadStub(result)
|
||||||
if result.kind == skAlias: result = result.owner
|
if result.kind == skAlias: result = result.owner
|
||||||
|
|
||||||
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
when false:
|
||||||
result = newSym(skProc, getIdent(name), nil, unknownLineInfo())
|
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
||||||
result.magic = m
|
result = newSym(skProc, getIdent(name), nil, unknownLineInfo())
|
||||||
|
result.magic = m
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
let
|
let
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
## - Its dependent module stays the same.
|
## - Its dependent module stays the same.
|
||||||
##
|
##
|
||||||
|
|
||||||
import ast, intsets, tables, options, rod, msgs, hashes
|
import ast, intsets, tables, options, rod, msgs, hashes, idents
|
||||||
|
|
||||||
type
|
type
|
||||||
ModuleGraph* = ref object
|
ModuleGraph* = ref object
|
||||||
|
|
@ -49,6 +49,7 @@ type
|
||||||
compilerprocs*: TStrTable
|
compilerprocs*: TStrTable
|
||||||
exposed*: TStrTable
|
exposed*: TStrTable
|
||||||
intTypeCache*: array[-5..64, PType]
|
intTypeCache*: array[-5..64, PType]
|
||||||
|
opContains*, opNot*: PSym
|
||||||
|
|
||||||
proc hash*(x: FileIndex): Hash {.borrow.}
|
proc hash*(x: FileIndex): Hash {.borrow.}
|
||||||
|
|
||||||
|
|
@ -57,6 +58,10 @@ proc hash*(x: FileIndex): Hash {.borrow.}
|
||||||
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
|
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
|
||||||
result = doStopCompile != nil and doStopCompile()
|
result = doStopCompile != nil and doStopCompile()
|
||||||
|
|
||||||
|
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
||||||
|
result = newSym(skProc, getIdent(name), nil, unknownLineInfo())
|
||||||
|
result.magic = m
|
||||||
|
|
||||||
proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
|
proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
|
||||||
result = ModuleGraph()
|
result = ModuleGraph()
|
||||||
initStrTable(result.packageSyms)
|
initStrTable(result.packageSyms)
|
||||||
|
|
@ -72,6 +77,8 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
|
||||||
result.methods = @[]
|
result.methods = @[]
|
||||||
initStrTable(result.compilerprocs)
|
initStrTable(result.compilerprocs)
|
||||||
initStrTable(result.exposed)
|
initStrTable(result.exposed)
|
||||||
|
result.opNot = createMagic(result, "not", mNot)
|
||||||
|
result.opContains = createMagic(result, "contains", mInSet)
|
||||||
|
|
||||||
proc resetAllModules*(g: ModuleGraph) =
|
proc resetAllModules*(g: ModuleGraph) =
|
||||||
initStrTable(packageSyms)
|
initStrTable(packageSyms)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||||
proc semProcBody(c: PContext, n: PNode): PNode
|
proc semProcBody(c: PContext, n: PNode): PNode
|
||||||
|
|
||||||
proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode
|
proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode
|
||||||
proc changeType(n: PNode, newType: PType, check: bool)
|
proc changeType(c: PContext; n: PNode, newType: PType, check: bool)
|
||||||
|
|
||||||
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode
|
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode
|
||||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
|
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
|
||||||
|
|
@ -86,7 +86,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
|
||||||
else:
|
else:
|
||||||
let x = result.skipConv
|
let x = result.skipConv
|
||||||
if x.kind in {nkPar, nkTupleConstr} and formal.kind != tyExpr:
|
if x.kind in {nkPar, nkTupleConstr} and formal.kind != tyExpr:
|
||||||
changeType(x, formal, check=true)
|
changeType(c, x, formal, check=true)
|
||||||
else:
|
else:
|
||||||
result = skipHiddenSubConv(result)
|
result = skipHiddenSubConv(result)
|
||||||
#result.typ = takeType(formal, arg.typ)
|
#result.typ = takeType(formal, arg.typ)
|
||||||
|
|
@ -476,7 +476,7 @@ proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||||
var prc = c.generics[i].inst.sym
|
var prc = c.generics[i].inst.sym
|
||||||
if prc.kind in {skProc, skFunc, skMethod, skConverter} and prc.magic == mNone:
|
if prc.kind in {skProc, skFunc, skMethod, skConverter} and prc.magic == mNone:
|
||||||
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
||||||
internalError(prc.info, "no code for " & prc.name.s)
|
internalError(c.config, prc.info, "no code for " & prc.name.s)
|
||||||
else:
|
else:
|
||||||
addSon(n, prc.ast)
|
addSon(n, prc.ast)
|
||||||
c.lastGenericIdx = c.generics.len
|
c.lastGenericIdx = c.generics.len
|
||||||
|
|
@ -501,14 +501,14 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
c.importTable = openScope(c)
|
c.importTable = openScope(c)
|
||||||
c.importTable.addSym(module) # a module knows itself
|
c.importTable.addSym(module) # a module knows itself
|
||||||
if sfSystemModule in module.flags:
|
if sfSystemModule in module.flags:
|
||||||
magicsys.systemModule = module # set global variable!
|
graph.systemModule = module
|
||||||
c.topLevelScope = openScope(c)
|
c.topLevelScope = openScope(c)
|
||||||
# don't be verbose unless the module belongs to the main package:
|
# don't be verbose unless the module belongs to the main package:
|
||||||
if module.owner.id == gMainPackageId:
|
if module.owner.id == gMainPackageId:
|
||||||
gNotes = gMainPackageNotes
|
graph.config.notes = graph.config.mainPackageNotes
|
||||||
else:
|
else:
|
||||||
if gMainPackageNotes == {}: gMainPackageNotes = gNotes
|
if graph.config.mainPackageNotes == {}: graph.config.mainPackageNotes = graph.config.notes
|
||||||
gNotes = ForeignPackageNotes
|
graph.config.notes = graph.config.foreignPackageNotes
|
||||||
result = c
|
result = c
|
||||||
|
|
||||||
proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContext =
|
proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContext =
|
||||||
|
|
@ -517,30 +517,30 @@ proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContex
|
||||||
proc replayMethodDefs(graph: ModuleGraph; rd: PRodReader) =
|
proc replayMethodDefs(graph: ModuleGraph; rd: PRodReader) =
|
||||||
for m in items(rd.methods): methodDef(graph, m, true)
|
for m in items(rd.methods): methodDef(graph, m, true)
|
||||||
|
|
||||||
proc isImportSystemStmt(n: PNode): bool =
|
proc isImportSystemStmt(g: ModuleGraph; n: PNode): bool =
|
||||||
if magicsys.systemModule == nil: return false
|
if g.systemModule == nil: return false
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkImportStmt:
|
of nkImportStmt:
|
||||||
for x in n:
|
for x in n:
|
||||||
if x.kind == nkIdent:
|
if x.kind == nkIdent:
|
||||||
let f = checkModuleName(x, false)
|
let f = checkModuleName(g.config, x, false)
|
||||||
if f == magicsys.systemModule.info.fileIndex:
|
if f == g.systemModule.info.fileIndex:
|
||||||
return true
|
return true
|
||||||
of nkImportExceptStmt, nkFromStmt:
|
of nkImportExceptStmt, nkFromStmt:
|
||||||
if n[0].kind == nkIdent:
|
if n[0].kind == nkIdent:
|
||||||
let f = checkModuleName(n[0], false)
|
let f = checkModuleName(g.config, n[0], false)
|
||||||
if f == magicsys.systemModule.info.fileIndex:
|
if f == g.systemModule.info.fileIndex:
|
||||||
return true
|
return true
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
||||||
if n.kind == nkDefer:
|
if n.kind == nkDefer:
|
||||||
localError(c.config, n.info, "defer statement not supported at top level")
|
localError(c.config, n.info, "defer statement not supported at top level")
|
||||||
if c.topStmts == 0 and not isImportSystemStmt(n):
|
if c.topStmts == 0 and not isImportSystemStmt(c.graph, n):
|
||||||
if sfSystemModule notin c.module.flags and
|
if sfSystemModule notin c.module.flags and
|
||||||
n.kind notin {nkEmpty, nkCommentStmt}:
|
n.kind notin {nkEmpty, nkCommentStmt}:
|
||||||
c.importTable.addSym magicsys.systemModule # import the "System" identifier
|
c.importTable.addSym c.graph.systemModule # import the "System" identifier
|
||||||
importAllSymbols(c, magicsys.systemModule)
|
importAllSymbols(c, c.graph.systemModule)
|
||||||
inc c.topStmts
|
inc c.topStmts
|
||||||
else:
|
else:
|
||||||
inc c.topStmts
|
inc c.topStmts
|
||||||
|
|
@ -566,7 +566,7 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
||||||
result = buildEchoStmt(c, result)
|
result = buildEchoStmt(c, result)
|
||||||
if gCmd == cmdIdeTools:
|
if gCmd == cmdIdeTools:
|
||||||
appendToModule(c.module, result)
|
appendToModule(c.module, result)
|
||||||
result = transformStmt(c.module, result)
|
result = transformStmt(c.graph, c.module, result)
|
||||||
|
|
||||||
proc recoverContext(c: PContext) =
|
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
|
||||||
|
|
@ -579,7 +579,7 @@ proc recoverContext(c: PContext) =
|
||||||
proc myProcess(context: PPassContext, n: PNode): PNode =
|
proc myProcess(context: PPassContext, n: PNode): PNode =
|
||||||
var c = PContext(context)
|
var c = PContext(context)
|
||||||
# no need for an expensive 'try' if we stop after the first error anyway:
|
# no need for an expensive 'try' if we stop after the first error anyway:
|
||||||
if msgs.gErrorMax <= 1:
|
if c.config.errorMax <= 1:
|
||||||
result = semStmtAndGenerateGenerics(c, n)
|
result = semStmtAndGenerateGenerics(c, n)
|
||||||
else:
|
else:
|
||||||
let oldContextLen = msgs.getInfoContextLen()
|
let oldContextLen = msgs.getInfoContextLen()
|
||||||
|
|
@ -602,9 +602,9 @@ proc testExamples(c: PContext) =
|
||||||
let inp = toFullPath(c.module.info)
|
let inp = toFullPath(c.module.info)
|
||||||
let outp = inp.changeFileExt"" & "_examples.nim"
|
let outp = inp.changeFileExt"" & "_examples.nim"
|
||||||
renderModule(c.runnableExamples, inp, outp)
|
renderModule(c.runnableExamples, inp, outp)
|
||||||
let backend = if isDefined("js"): "js"
|
let backend = if isDefined(c.config, "js"): "js"
|
||||||
elif isDefined("cpp"): "cpp"
|
elif isDefined(c.config, "cpp"): "cpp"
|
||||||
elif isDefined("objc"): "objc"
|
elif isDefined(c.config, "objc"): "objc"
|
||||||
else: "c"
|
else: "c"
|
||||||
if os.execShellCmd("nim " & backend & " -r " & outp) != 0:
|
if os.execShellCmd("nim " & backend & " -r " & outp) != 0:
|
||||||
quit "[Examples] failed"
|
quit "[Examples] failed"
|
||||||
|
|
@ -618,7 +618,7 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode =
|
||||||
rawCloseScope(c) # imported symbols; don't check for unused ones!
|
rawCloseScope(c) # imported symbols; don't check for unused ones!
|
||||||
result = newNode(nkStmtList)
|
result = newNode(nkStmtList)
|
||||||
if n != nil:
|
if n != nil:
|
||||||
internalError(n.info, "n is not nil") #result := n;
|
internalError(c.config, n.info, "n is not nil") #result := n;
|
||||||
addCodeForGenerics(c, result)
|
addCodeForGenerics(c, result)
|
||||||
if c.module.ast != nil:
|
if c.module.ast != nil:
|
||||||
result.add(c.module.ast)
|
result.add(c.module.ast)
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,24 @@
|
||||||
# this module does the semantic checking for expressions
|
# this module does the semantic checking for expressions
|
||||||
# included from sem.nim
|
# included from sem.nim
|
||||||
|
|
||||||
|
const
|
||||||
|
errExprXHasNoType = "expression '$1' has no type (or is ambiguous)"
|
||||||
|
errXExpectsTypeOrValue = "'$1' expects a type or value"
|
||||||
|
errVarForOutParamNeededX = "for a 'var' type a variable needs to be passed; but '$1' is immutable"
|
||||||
|
errXStackEscape = "address of '$1' may not escape its stack frame"
|
||||||
|
errExprHasNoAddress = "expression has no address; maybe use 'unsafeAddr'"
|
||||||
|
errCannotInterpretNodeX = "cannot evaluate '$1'"
|
||||||
|
errNamedExprExpected = "named expression expected"
|
||||||
|
errNamedExprNotAllowed = "named expression not allowed here"
|
||||||
|
errFieldInitTwice = "field initialized twice: '$1'"
|
||||||
|
errUndeclaredFieldX = "undeclared field: '$1'"
|
||||||
|
|
||||||
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(n.info)
|
||||||
result = evalTemplate(n, s, getCurrOwner(c), efFromHlo in flags)
|
result = evalTemplate(n, s, getCurrOwner(c), c.config, efFromHlo in flags)
|
||||||
if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
|
if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
||||||
|
|
@ -31,12 +43,12 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if result.typ != nil:
|
if result.typ != nil:
|
||||||
# XXX tyGenericInst here?
|
# XXX tyGenericInst here?
|
||||||
if result.typ.kind == tyProc and tfUnresolved in result.typ.flags:
|
if result.typ.kind == tyProc and tfUnresolved in result.typ.flags:
|
||||||
localError(c.config, n.info, errProcHasNoConcreteType, n.renderTree)
|
localError(c.config, n.info, errProcHasNoConcreteType % n.renderTree)
|
||||||
if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
|
if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
|
||||||
elif {efWantStmt, efAllowStmt} * flags != {}:
|
elif {efWantStmt, efAllowStmt} * flags != {}:
|
||||||
result.typ = newTypeS(tyVoid, c)
|
result.typ = newTypeS(tyVoid, c)
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errExprXHasNoType,
|
localError(c.config, n.info, errExprXHasNoType %
|
||||||
renderTree(result, {renderNoComments}))
|
renderTree(result, {renderNoComments}))
|
||||||
result.typ = errorType(c)
|
result.typ = errorType(c)
|
||||||
|
|
||||||
|
|
@ -47,7 +59,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
#raiseRecoverableError("")
|
#raiseRecoverableError("")
|
||||||
result = errorNode(c, n)
|
result = errorNode(c, n)
|
||||||
if result.typ == nil or result.typ == enforceVoidContext:
|
if result.typ == nil or result.typ == enforceVoidContext:
|
||||||
localError(c.config, n.info, errExprXHasNoType,
|
localError(c.config, n.info, errExprXHasNoType %
|
||||||
renderTree(result, {renderNoComments}))
|
renderTree(result, {renderNoComments}))
|
||||||
result.typ = errorType(c)
|
result.typ = errorType(c)
|
||||||
else:
|
else:
|
||||||
|
|
@ -59,14 +71,14 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
# do not produce another redundant error message:
|
# do not produce another redundant error message:
|
||||||
result = errorNode(c, n)
|
result = errorNode(c, n)
|
||||||
if result.typ == nil:
|
if result.typ == nil:
|
||||||
localError(c.config, n.info, errExprXHasNoType,
|
localError(c.config, n.info, errExprXHasNoType %
|
||||||
renderTree(result, {renderNoComments}))
|
renderTree(result, {renderNoComments}))
|
||||||
result.typ = errorType(c)
|
result.typ = errorType(c)
|
||||||
|
|
||||||
proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
result = symChoice(c, n, s, scClosed)
|
result = symChoice(c, n, s, scClosed)
|
||||||
|
|
||||||
proc inlineConst(n: PNode, s: PSym): PNode {.inline.} =
|
proc inlineConst(c: PContext, n: PNode, s: PSym): PNode {.inline.} =
|
||||||
result = copyTree(s.ast)
|
result = copyTree(s.ast)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
localError(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value")
|
localError(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value")
|
||||||
|
|
@ -172,7 +184,7 @@ proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) =
|
||||||
|
|
||||||
proc semConv(c: PContext, n: PNode): PNode =
|
proc semConv(c: PContext, n: PNode): PNode =
|
||||||
if sonsLen(n) != 2:
|
if sonsLen(n) != 2:
|
||||||
localError(c.config, n.info, errConvNeedsOneArg)
|
localError(c.config, n.info, "a type conversion takes exactly one argument")
|
||||||
return n
|
return n
|
||||||
|
|
||||||
result = newNodeI(nkConv, n.info)
|
result = newNodeI(nkConv, n.info)
|
||||||
|
|
@ -219,14 +231,14 @@ proc semConv(c: PContext, n: PNode): PNode =
|
||||||
of convNotLegal:
|
of convNotLegal:
|
||||||
result = fitNode(c, result.typ, result.sons[1], result.info)
|
result = fitNode(c, result.typ, result.sons[1], result.info)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
localError(c.config, n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)%
|
localError(c.config, n.info, "illegal conversion from '$1' to '$2'" %
|
||||||
[op.typ.typeToString, result.typ.typeToString])
|
[op.typ.typeToString, result.typ.typeToString])
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(op) - 1):
|
for i in countup(0, sonsLen(op) - 1):
|
||||||
let it = op.sons[i]
|
let it = op.sons[i]
|
||||||
let status = checkConvertible(c, result.typ, it.typ)
|
let status = checkConvertible(c, result.typ, it.typ)
|
||||||
if status in {convOK, convNotNeedeed}:
|
if status in {convOK, convNotNeedeed}:
|
||||||
markUsed(n.info, it.sym, c.graph.usageSym)
|
markUsed(c.config, n.info, it.sym, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, it.sym)
|
styleCheckUse(n.info, it.sym)
|
||||||
markIndirect(c, it.sym)
|
markIndirect(c, it.sym)
|
||||||
return it
|
return it
|
||||||
|
|
@ -238,12 +250,12 @@ proc semCast(c: PContext, n: PNode): PNode =
|
||||||
let targetType = semTypeNode(c, n.sons[0], nil)
|
let targetType = semTypeNode(c, n.sons[0], nil)
|
||||||
let castedExpr = semExprWithType(c, n.sons[1])
|
let castedExpr = semExprWithType(c, n.sons[1])
|
||||||
if tfHasMeta in targetType.flags:
|
if tfHasMeta in targetType.flags:
|
||||||
localError(c.config, n.sons[0].info, errCastToANonConcreteType, $targetType)
|
localError(c.config, n.sons[0].info, "cannot cast to a non concrete type: '$1'" % $targetType)
|
||||||
if not isCastable(targetType, castedExpr.typ):
|
if not isCastable(targetType, castedExpr.typ):
|
||||||
let tar = $targetType
|
let tar = $targetType
|
||||||
let alt = typeToString(targetType, preferDesc)
|
let alt = typeToString(targetType, preferDesc)
|
||||||
let msg = if tar != alt: tar & "=" & alt else: tar
|
let msg = if tar != alt: tar & "=" & alt else: tar
|
||||||
localError(c.config, n.info, errExprCannotBeCastToX, msg)
|
localError(c.config, n.info, "expression cannot be cast to " & msg)
|
||||||
result = newNodeI(nkCast, n.info)
|
result = newNodeI(nkCast, n.info)
|
||||||
result.typ = targetType
|
result.typ = targetType
|
||||||
addSon(result, copyTree(n.sons[0]))
|
addSon(result, copyTree(n.sons[0]))
|
||||||
|
|
@ -253,13 +265,13 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
const
|
const
|
||||||
opToStr: array[mLow..mHigh, string] = ["low", "high"]
|
opToStr: array[mLow..mHigh, string] = ["low", "high"]
|
||||||
if sonsLen(n) != 2:
|
if sonsLen(n) != 2:
|
||||||
localError(c.config, n.info, errXExpectsTypeOrValue, opToStr[m])
|
localError(c.config, n.info, errXExpectsTypeOrValue % opToStr[m])
|
||||||
else:
|
else:
|
||||||
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
|
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
|
||||||
var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc})
|
var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc})
|
||||||
case typ.kind
|
case typ.kind
|
||||||
of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
|
of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
|
||||||
n.typ = getSysType(tyInt)
|
n.typ = getSysType(c.graph, n.info, tyInt)
|
||||||
of tyArray:
|
of tyArray:
|
||||||
n.typ = typ.sons[0] # indextype
|
n.typ = typ.sons[0] # indextype
|
||||||
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
|
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
|
||||||
|
|
@ -271,20 +283,20 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
# that could easily turn into an infinite recursion in semtypinst
|
# that could easily turn into an infinite recursion in semtypinst
|
||||||
n.typ = makeTypeFromExpr(c, n.copyTree)
|
n.typ = makeTypeFromExpr(c, n.copyTree)
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errInvalidArgForX, opToStr[m])
|
localError(c.config, n.info, "invalid argument for: " & opToStr[m])
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc semSizeof(c: PContext, n: PNode): PNode =
|
proc semSizeof(c: PContext, n: PNode): PNode =
|
||||||
if sonsLen(n) != 2:
|
if sonsLen(n) != 2:
|
||||||
localError(c.config, n.info, errXExpectsTypeOrValue, "sizeof")
|
localError(c.config, n.info, errXExpectsTypeOrValue % "sizeof")
|
||||||
else:
|
else:
|
||||||
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
|
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
|
||||||
#restoreOldStyleType(n.sons[1])
|
#restoreOldStyleType(n.sons[1])
|
||||||
n.typ = getSysType(tyInt)
|
n.typ = getSysType(c.graph, n.info, tyInt)
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
internalAssert n.sonsLen == 3 and
|
internalAssert c.config, n.sonsLen == 3 and
|
||||||
n[1].typ != nil and n[1].typ.kind == tyTypeDesc and
|
n[1].typ != nil and n[1].typ.kind == tyTypeDesc and
|
||||||
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
|
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
|
||||||
|
|
||||||
|
|
@ -315,10 +327,10 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
||||||
proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if sonsLen(n) != 3:
|
if sonsLen(n) != 3:
|
||||||
localError(c.config, n.info, errXExpectsTwoArguments, "is")
|
localError(c.config, n.info, "'is' operator takes 2 arguments")
|
||||||
|
|
||||||
result = n
|
result = n
|
||||||
n.typ = getSysType(tyBool)
|
n.typ = getSysType(c.graph, n.info, tyBool)
|
||||||
|
|
||||||
n.sons[1] = semExprWithType(c, n[1], {efDetermineType, efWantIterator})
|
n.sons[1] = semExprWithType(c, n[1], {efDetermineType, efWantIterator})
|
||||||
if n[2].kind notin {nkStrLit..nkTripleStrLit}:
|
if n[2].kind notin {nkStrLit..nkTripleStrLit}:
|
||||||
|
|
@ -340,8 +352,8 @@ proc semOpAux(c: PContext, n: PNode) =
|
||||||
for i in countup(1, n.sonsLen-1):
|
for i in countup(1, n.sonsLen-1):
|
||||||
var a = n.sons[i]
|
var a = n.sons[i]
|
||||||
if a.kind == nkExprEqExpr and sonsLen(a) == 2:
|
if a.kind == nkExprEqExpr and sonsLen(a) == 2:
|
||||||
var info = a.sons[0].info
|
let info = a.sons[0].info
|
||||||
a.sons[0] = newIdentNode(considerQuotedIdent(a.sons[0], a), info)
|
a.sons[0] = newIdentNode(considerQuotedIdent(c.config, a.sons[0], a), info)
|
||||||
a.sons[1] = semExprWithType(c, a.sons[1], flags)
|
a.sons[1] = semExprWithType(c, a.sons[1], flags)
|
||||||
a.typ = a.sons[1].typ
|
a.typ = a.sons[1].typ
|
||||||
else:
|
else:
|
||||||
|
|
@ -358,34 +370,34 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode =
|
||||||
for i in countup(0, sonsLen(n) - 1): addSon(result, n.sons[i])
|
for i in countup(0, sonsLen(n) - 1): addSon(result, n.sons[i])
|
||||||
result = semExpr(c, result)
|
result = semExpr(c, result)
|
||||||
|
|
||||||
proc changeType(n: PNode, newType: PType, check: bool) =
|
proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCurly, nkBracket:
|
of nkCurly, nkBracket:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
changeType(n.sons[i], elemType(newType), check)
|
changeType(c, n.sons[i], elemType(newType), check)
|
||||||
of nkPar, nkTupleConstr:
|
of nkPar, nkTupleConstr:
|
||||||
let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink})
|
let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
if tup.kind != tyTuple:
|
if tup.kind != tyTuple:
|
||||||
if tup.kind == tyObject: return
|
if tup.kind == tyObject: return
|
||||||
globalError(n.info, "no tuple type for constructor")
|
globalError(c.config, n.info, "no tuple type for constructor")
|
||||||
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
|
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
|
||||||
# named tuple?
|
# named tuple?
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var m = n.sons[i].sons[0]
|
var m = n.sons[i].sons[0]
|
||||||
if m.kind != nkSym:
|
if m.kind != nkSym:
|
||||||
globalError(m.info, "invalid tuple constructor")
|
globalError(c.config, m.info, "invalid tuple constructor")
|
||||||
return
|
return
|
||||||
if tup.n != nil:
|
if tup.n != nil:
|
||||||
var f = getSymFromList(tup.n, m.sym.name)
|
var f = getSymFromList(tup.n, m.sym.name)
|
||||||
if f == nil:
|
if f == nil:
|
||||||
globalError(m.info, "unknown identifier: " & m.sym.name.s)
|
globalError(c.config, m.info, "unknown identifier: " & m.sym.name.s)
|
||||||
return
|
return
|
||||||
changeType(n.sons[i].sons[1], f.typ, check)
|
changeType(c, n.sons[i].sons[1], f.typ, check)
|
||||||
else:
|
else:
|
||||||
changeType(n.sons[i].sons[1], tup.sons[i], check)
|
changeType(c, n.sons[i].sons[1], tup.sons[i], check)
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
changeType(n.sons[i], tup.sons[i], check)
|
changeType(c, n.sons[i], tup.sons[i], check)
|
||||||
when false:
|
when false:
|
||||||
var m = n.sons[i]
|
var m = n.sons[i]
|
||||||
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
|
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
|
||||||
|
|
@ -396,7 +408,7 @@ proc changeType(n: PNode, newType: PType, check: bool) =
|
||||||
if check and n.kind != nkUInt64Lit:
|
if check and n.kind != nkUInt64Lit:
|
||||||
let value = n.intVal
|
let value = n.intVal
|
||||||
if value < firstOrd(newType) or value > lastOrd(newType):
|
if value < firstOrd(newType) or value > lastOrd(newType):
|
||||||
localError(c.config, n.info, errGenerated, "cannot convert " & $value &
|
localError(c.config, n.info, "cannot convert " & $value &
|
||||||
" to " & typeToString(newType))
|
" to " & typeToString(newType))
|
||||||
else: discard
|
else: discard
|
||||||
n.typ = newType
|
n.typ = newType
|
||||||
|
|
@ -421,7 +433,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
else:
|
else:
|
||||||
var x = n.sons[0]
|
var x = n.sons[0]
|
||||||
var lastIndex: BiggestInt = 0
|
var lastIndex: BiggestInt = 0
|
||||||
var indexType = getSysType(tyInt)
|
var indexType = getSysType(c.graph, n.info, tyInt)
|
||||||
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
||||||
var idx = semConstExpr(c, x.sons[0])
|
var idx = semConstExpr(c, x.sons[0])
|
||||||
lastIndex = getOrdValue(idx)
|
lastIndex = getOrdValue(idx)
|
||||||
|
|
@ -438,7 +450,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
var idx = semConstExpr(c, x.sons[0])
|
var idx = semConstExpr(c, x.sons[0])
|
||||||
idx = fitNode(c, indexType, idx, x.info)
|
idx = fitNode(c, indexType, idx, x.info)
|
||||||
if lastIndex+1 != getOrdValue(idx):
|
if lastIndex+1 != getOrdValue(idx):
|
||||||
localError(c.config, x.info, errInvalidOrderInArrayConstructor)
|
localError(c.config, x.info, "invalid order in array constructor")
|
||||||
x = x.sons[1]
|
x = x.sons[1]
|
||||||
|
|
||||||
let xx = semExprWithType(c, x, flags*{efAllowDestructor})
|
let xx = semExprWithType(c, x, flags*{efAllowDestructor})
|
||||||
|
|
@ -462,7 +474,7 @@ proc fixAbstractType(c: PContext, n: PNode) =
|
||||||
{tyNil, tyTuple, tySet} or it[1].isArrayConstr:
|
{tyNil, tyTuple, tySet} or it[1].isArrayConstr:
|
||||||
var s = skipTypes(it.typ, abstractVar)
|
var s = skipTypes(it.typ, abstractVar)
|
||||||
if s.kind != tyExpr:
|
if s.kind != tyExpr:
|
||||||
changeType(it.sons[1], s, check=true)
|
changeType(c, it.sons[1], s, check=true)
|
||||||
n.sons[i] = it.sons[1]
|
n.sons[i] = it.sons[1]
|
||||||
|
|
||||||
proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult =
|
proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult =
|
||||||
|
|
@ -477,7 +489,7 @@ proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
|
||||||
result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
|
result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
|
||||||
addSon(result, n)
|
addSon(result, n)
|
||||||
if isAssignable(c, n) notin {arLValue, arLocalLValue}:
|
if isAssignable(c, n) notin {arLValue, arLocalLValue}:
|
||||||
localError(c.config, n.info, errVarForOutParamNeededX, renderNotLValue(n))
|
localError(c.config, n.info, errVarForOutParamNeededX % renderNotLValue(n))
|
||||||
|
|
||||||
proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
|
proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
|
|
@ -491,7 +503,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
checkSonsLen(n, 2, c.config)
|
checkSonsLen(n, 2, c.config)
|
||||||
if n.sons[1].kind != nkSym:
|
if n.sons[1].kind != nkSym:
|
||||||
internalError(n.info, "analyseIfAddressTaken")
|
internalError(c.config, n.info, "analyseIfAddressTaken")
|
||||||
return
|
return
|
||||||
if skipTypes(n.sons[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
if skipTypes(n.sons[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
||||||
incl(n.sons[1].sym.flags, sfAddrTaken)
|
incl(n.sons[1].sym.flags, sfAddrTaken)
|
||||||
|
|
@ -600,17 +612,17 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||||
var call = newNodeIT(nkCall, n.info, n.typ)
|
var call = newNodeIT(nkCall, n.info, n.typ)
|
||||||
call.add(n.sons[0])
|
call.add(n.sons[0])
|
||||||
for i in 1 ..< n.len:
|
for i in 1 ..< n.len:
|
||||||
let a = getConstExpr(c.module, n.sons[i])
|
let a = getConstExpr(c.module, n.sons[i], c.graph)
|
||||||
if a == nil: return n
|
if a == nil: return n
|
||||||
call.add(a)
|
call.add(a)
|
||||||
#echo "NOW evaluating at compile time: ", call.renderTree
|
#echo "NOW evaluating at compile time: ", call.renderTree
|
||||||
if sfCompileTime in callee.flags:
|
if sfCompileTime in callee.flags:
|
||||||
result = evalStaticExpr(c.module, c.cache, c.graph.config, call, c.p.owner)
|
result = evalStaticExpr(c.module, c.cache, c.graph, call, c.p.owner)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
localError(c.config, n.info, errCannotInterpretNodeX, renderTree(call))
|
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(call))
|
||||||
else: result = fixupTypeAfterEval(c, result, n)
|
else: result = fixupTypeAfterEval(c, result, n)
|
||||||
else:
|
else:
|
||||||
result = evalConstExpr(c.module, c.cache, c.graph.config, call)
|
result = evalConstExpr(c.module, c.cache, c.graph, call)
|
||||||
if result.isNil: result = n
|
if result.isNil: result = n
|
||||||
else: result = fixupTypeAfterEval(c, result, n)
|
else: result = fixupTypeAfterEval(c, result, n)
|
||||||
#if result != n:
|
#if result != n:
|
||||||
|
|
@ -619,9 +631,9 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||||
proc semStaticExpr(c: PContext, n: PNode): PNode =
|
proc semStaticExpr(c: PContext, n: PNode): PNode =
|
||||||
let a = semExpr(c, n.sons[0])
|
let a = semExpr(c, n.sons[0])
|
||||||
if a.findUnresolvedStatic != nil: return a
|
if a.findUnresolvedStatic != nil: return a
|
||||||
result = evalStaticExpr(c.module, c.cache, c.graph.config, a, c.p.owner)
|
result = evalStaticExpr(c.module, c.cache, c.graph, a, c.p.owner)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
localError(c.config, n.info, errCannotInterpretNodeX, renderTree(n))
|
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n))
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
else:
|
else:
|
||||||
result = fixupTypeAfterEval(c, result, a)
|
result = fixupTypeAfterEval(c, result, a)
|
||||||
|
|
@ -641,14 +653,14 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||||
|
|
||||||
if result != nil:
|
if result != nil:
|
||||||
if result.sons[0].kind != nkSym:
|
if result.sons[0].kind != nkSym:
|
||||||
internalError("semOverloadedCallAnalyseEffects")
|
internalError(c.config, "semOverloadedCallAnalyseEffects")
|
||||||
return
|
return
|
||||||
let callee = result.sons[0].sym
|
let callee = result.sons[0].sym
|
||||||
case callee.kind
|
case callee.kind
|
||||||
of skMacro, skTemplate: discard
|
of skMacro, skTemplate: discard
|
||||||
else:
|
else:
|
||||||
if callee.kind == skIterator and callee.id == c.p.owner.id:
|
if callee.kind == skIterator and callee.id == c.p.owner.id:
|
||||||
localError(c.config, n.info, errRecursiveDependencyX, callee.name.s)
|
localError(c.config, n.info, errRecursiveDependencyX % callee.name.s)
|
||||||
# error correction, prevents endless for loop elimination in transf.
|
# error correction, prevents endless for loop elimination in transf.
|
||||||
# See bug #2051:
|
# See bug #2051:
|
||||||
result.sons[0] = newSymNode(errorSym(c, n))
|
result.sons[0] = newSymNode(errorSym(c, n))
|
||||||
|
|
@ -736,7 +748,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
return emptyNode
|
return emptyNode
|
||||||
else:
|
else:
|
||||||
var hasErrorType = false
|
var hasErrorType = false
|
||||||
var msg = msgKindToString(errTypeMismatch)
|
var msg = "type mismatch: got <"
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
if i > 1: add(msg, ", ")
|
if i > 1: add(msg, ", ")
|
||||||
let nt = n.sons[i].typ
|
let nt = n.sons[i].typ
|
||||||
|
|
@ -745,7 +757,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
hasErrorType = true
|
hasErrorType = true
|
||||||
break
|
break
|
||||||
if not hasErrorType:
|
if not hasErrorType:
|
||||||
add(msg, ">\n" & msgKindToString(errButExpected) & "\n" &
|
add(msg, ">\nbut expected one of: \n" &
|
||||||
typeToString(n.sons[0].typ))
|
typeToString(n.sons[0].typ))
|
||||||
localError(c.config, n.info, msg)
|
localError(c.config, n.info, msg)
|
||||||
return errorNode(c, n)
|
return errorNode(c, n)
|
||||||
|
|
@ -790,7 +802,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
proc buildEchoStmt(c: PContext, n: PNode): PNode =
|
proc buildEchoStmt(c: PContext, n: PNode): PNode =
|
||||||
# we MUST not check 'n' for semantics again here! But for now we give up:
|
# we MUST not check 'n' for semantics again here! But for now we give up:
|
||||||
result = newNodeI(nkCall, n.info)
|
result = newNodeI(nkCall, n.info)
|
||||||
var e = strTableGet(magicsys.systemModule.tab, getIdent"echo")
|
var e = strTableGet(c.graph.systemModule.tab, getIdent"echo")
|
||||||
if e != nil:
|
if e != nil:
|
||||||
add(result, newSymNode(e))
|
add(result, newSymNode(e))
|
||||||
else:
|
else:
|
||||||
|
|
@ -857,8 +869,8 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
|
||||||
addSon(check, ast.emptyNode) # make space for access node
|
addSon(check, ast.emptyNode) # make space for access node
|
||||||
s = newNodeIT(nkCurly, n.info, setType)
|
s = newNodeIT(nkCurly, n.info, setType)
|
||||||
for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j]))
|
for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j]))
|
||||||
var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool))
|
var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
||||||
addSon(inExpr, newSymNode(opContains, n.info))
|
addSon(inExpr, newSymNode(c.graph.opContains, n.info))
|
||||||
addSon(inExpr, s)
|
addSon(inExpr, s)
|
||||||
addSon(inExpr, copyTree(r.sons[0]))
|
addSon(inExpr, copyTree(r.sons[0]))
|
||||||
addSon(check, inExpr)
|
addSon(check, inExpr)
|
||||||
|
|
@ -870,12 +882,12 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
|
||||||
if check == nil:
|
if check == nil:
|
||||||
check = newNodeI(nkCheckedFieldExpr, n.info)
|
check = newNodeI(nkCheckedFieldExpr, n.info)
|
||||||
addSon(check, ast.emptyNode) # make space for access node
|
addSon(check, ast.emptyNode) # make space for access node
|
||||||
var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool))
|
var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
||||||
addSon(inExpr, newSymNode(opContains, n.info))
|
addSon(inExpr, newSymNode(c.graph.opContains, n.info))
|
||||||
addSon(inExpr, s)
|
addSon(inExpr, s)
|
||||||
addSon(inExpr, copyTree(r.sons[0]))
|
addSon(inExpr, copyTree(r.sons[0]))
|
||||||
var notExpr = newNodeIT(nkCall, n.info, getSysType(tyBool))
|
var notExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
||||||
addSon(notExpr, newSymNode(opNot, n.info))
|
addSon(notExpr, newSymNode(c.graph.opNot, n.info))
|
||||||
addSon(notExpr, inExpr)
|
addSon(notExpr, inExpr)
|
||||||
addSon(check, notExpr)
|
addSon(check, notExpr)
|
||||||
return
|
return
|
||||||
|
|
@ -937,12 +949,12 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
let s = getGenSym(c, sym)
|
let s = getGenSym(c, sym)
|
||||||
case s.kind
|
case s.kind
|
||||||
of skConst:
|
of skConst:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind
|
case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind
|
||||||
of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
|
of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
|
||||||
tyTuple, tySet, tyUInt..tyUInt64:
|
tyTuple, tySet, tyUInt..tyUInt64:
|
||||||
if s.magic == mNone: result = inlineConst(n, s)
|
if s.magic == mNone: result = inlineConst(c, n, s)
|
||||||
else: result = newSymNode(s, n.info)
|
else: result = newSymNode(s, n.info)
|
||||||
of tyArray, tySequence:
|
of tyArray, tySequence:
|
||||||
# Consider::
|
# Consider::
|
||||||
|
|
@ -955,13 +967,13 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
# It is clear that ``[]`` means two totally different things. Thus, we
|
# It is clear that ``[]`` means two totally different things. Thus, we
|
||||||
# copy `x`'s AST into each context, so that the type fixup phase can
|
# copy `x`'s AST into each context, so that the type fixup phase can
|
||||||
# deal with two different ``[]``.
|
# deal with two different ``[]``.
|
||||||
if s.ast.len == 0: result = inlineConst(n, s)
|
if s.ast.len == 0: result = inlineConst(c, n, s)
|
||||||
else: result = newSymNode(s, n.info)
|
else: result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0:
|
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
|
|
@ -969,13 +981,13 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
|
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
|
||||||
sfCustomPragma in sym.flags:
|
sfCustomPragma in sym.flags:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
result = semTemplateExpr(c, n, s, flags)
|
result = semTemplateExpr(c, n, s, flags)
|
||||||
of skParam:
|
of skParam:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
if s.typ != nil and s.typ.kind == tyStatic and s.typ.n != nil:
|
if s.typ != nil and s.typ.kind == tyStatic and s.typ.n != nil:
|
||||||
# XXX see the hack in sigmatch.nim ...
|
# XXX see the hack in sigmatch.nim ...
|
||||||
|
|
@ -985,19 +997,19 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
# gensym'ed parameters that nevertheless have been forward declared
|
# gensym'ed parameters that nevertheless have been forward declared
|
||||||
# need a special fixup:
|
# need a special fixup:
|
||||||
let realParam = c.p.owner.typ.n[s.position+1]
|
let realParam = c.p.owner.typ.n[s.position+1]
|
||||||
internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
|
internalAssert c.config, realParam.kind == nkSym and realParam.sym.kind == skParam
|
||||||
return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
|
return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
|
||||||
elif c.p.owner.kind == skMacro:
|
elif c.p.owner.kind == skMacro:
|
||||||
# gensym'ed macro parameters need a similar hack (see bug #1944):
|
# gensym'ed macro parameters need a similar hack (see bug #1944):
|
||||||
var u = searchInScopes(c, s.name)
|
var u = searchInScopes(c, s.name)
|
||||||
internalAssert u != nil and u.kind == skParam and u.owner == s.owner
|
internalAssert c.config, u != nil and u.kind == skParam and u.owner == s.owner
|
||||||
return newSymNode(u, n.info)
|
return newSymNode(u, n.info)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
of skVar, skLet, skResult, skForVar:
|
of skVar, skLet, skResult, skForVar:
|
||||||
if s.magic == mNimvm:
|
if s.magic == mNimvm:
|
||||||
localError(c.config, n.info, "illegal context for 'nimvm' magic")
|
localError(c.config, n.info, "illegal context for 'nimvm' magic")
|
||||||
|
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
# We cannot check for access to outer vars for example because it's still
|
# We cannot check for access to outer vars for example because it's still
|
||||||
|
|
@ -1015,7 +1027,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
n.typ = s.typ
|
n.typ = s.typ
|
||||||
return n
|
return n
|
||||||
of skType:
|
of skType:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
if s.typ.kind == tyStatic and s.typ.n != nil:
|
if s.typ.kind == tyStatic and s.typ.n != nil:
|
||||||
return s.typ.n
|
return s.typ.n
|
||||||
|
|
@ -1037,7 +1049,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
if f != nil and fieldVisible(c, f):
|
if f != nil and fieldVisible(c, f):
|
||||||
# is the access to a public field or in the same module or in a friend?
|
# is the access to a public field or in the same module or in a friend?
|
||||||
doAssert f == s
|
doAssert f == s
|
||||||
markUsed(n.info, f, c.graph.usageSym)
|
markUsed(c.config, n.info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, f)
|
styleCheckUse(n.info, f)
|
||||||
result = newNodeIT(nkDotExpr, n.info, f.typ)
|
result = newNodeIT(nkDotExpr, n.info, f.typ)
|
||||||
result.add makeDeref(newSymNode(p.selfSym))
|
result.add makeDeref(newSymNode(p.selfSym))
|
||||||
|
|
@ -1050,11 +1062,11 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
if ty.sons[0] == nil: break
|
if ty.sons[0] == nil: break
|
||||||
ty = skipTypes(ty.sons[0], skipPtrs)
|
ty = skipTypes(ty.sons[0], skipPtrs)
|
||||||
# old code, not sure if it's live code:
|
# old code, not sure if it's live code:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
else:
|
else:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
|
|
||||||
|
|
@ -1076,14 +1088,14 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = symChoice(c, n, s, scClosed)
|
result = symChoice(c, n, s, scClosed)
|
||||||
if result.kind == nkSym: result = semSym(c, n, s, flags)
|
if result.kind == nkSym: result = semSym(c, n, s, flags)
|
||||||
else:
|
else:
|
||||||
markUsed(n.sons[1].info, s, c.graph.usageSym)
|
markUsed(c.config, n.sons[1].info, s, c.graph.usageSym)
|
||||||
result = semSym(c, n, s, flags)
|
result = semSym(c, n, s, flags)
|
||||||
styleCheckUse(n.sons[1].info, s)
|
styleCheckUse(n.sons[1].info, s)
|
||||||
return
|
return
|
||||||
|
|
||||||
n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType})
|
n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType})
|
||||||
#restoreOldStyleType(n.sons[0])
|
#restoreOldStyleType(n.sons[0])
|
||||||
var i = considerQuotedIdent(n.sons[1], n)
|
var i = considerQuotedIdent(c.config, n.sons[1], n)
|
||||||
var ty = n.sons[0].typ
|
var ty = n.sons[0].typ
|
||||||
var f: PSym = nil
|
var f: PSym = nil
|
||||||
result = nil
|
result = nil
|
||||||
|
|
@ -1140,7 +1152,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = newSymNode(f)
|
result = newSymNode(f)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
result.typ = ty
|
result.typ = ty
|
||||||
markUsed(n.info, f, c.graph.usageSym)
|
markUsed(c.config, n.info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, f)
|
styleCheckUse(n.info, f)
|
||||||
return
|
return
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
|
|
@ -1171,7 +1183,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if f != nil:
|
if f != nil:
|
||||||
if fieldVisible(c, f):
|
if fieldVisible(c, f):
|
||||||
# is the access to a public field or in the same module or in a friend?
|
# is the access to a public field or in the same module or in a friend?
|
||||||
markUsed(n.sons[1].info, f, c.graph.usageSym)
|
markUsed(c.config, n.sons[1].info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.sons[1].info, f)
|
styleCheckUse(n.sons[1].info, f)
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(n.sons[0])
|
||||||
n.sons[1] = newSymNode(f) # we now have the correct field
|
n.sons[1] = newSymNode(f) # we now have the correct field
|
||||||
|
|
@ -1185,7 +1197,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
elif ty.kind == tyTuple and ty.n != nil:
|
elif ty.kind == tyTuple and ty.n != nil:
|
||||||
f = getSymFromList(ty.n, i)
|
f = getSymFromList(ty.n, i)
|
||||||
if f != nil:
|
if f != nil:
|
||||||
markUsed(n.sons[1].info, f, c.graph.usageSym)
|
markUsed(c.config, n.sons[1].info, f, c.graph.usageSym)
|
||||||
styleCheckUse(n.sons[1].info, f)
|
styleCheckUse(n.sons[1].info, f)
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(n.sons[0])
|
||||||
n.sons[1] = newSymNode(f)
|
n.sons[1] = newSymNode(f)
|
||||||
|
|
@ -1203,7 +1215,7 @@ proc dotTransformation(c: PContext, n: PNode): PNode =
|
||||||
addSon(result, n.sons[1])
|
addSon(result, n.sons[1])
|
||||||
addSon(result, copyTree(n[0]))
|
addSon(result, copyTree(n[0]))
|
||||||
else:
|
else:
|
||||||
var i = considerQuotedIdent(n.sons[1], n)
|
var i = considerQuotedIdent(c.config, n.sons[1], n)
|
||||||
result = newNodeI(nkDotCall, n.info)
|
result = newNodeI(nkDotCall, n.info)
|
||||||
result.flags.incl nfDotField
|
result.flags.incl nfDotField
|
||||||
addSon(result, newIdentNode(i, n[1].info))
|
addSon(result, newIdentNode(i, n[1].info))
|
||||||
|
|
@ -1254,7 +1266,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
n.sons[i] = semExprWithType(c, n.sons[i],
|
n.sons[i] = semExprWithType(c, n.sons[i],
|
||||||
flags*{efInTypeof, efDetermineType})
|
flags*{efInTypeof, efDetermineType})
|
||||||
var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(tyInt)
|
var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(c.graph, n.info, tyInt)
|
||||||
var arg = indexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1])
|
var arg = indexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1])
|
||||||
if arg != nil:
|
if arg != nil:
|
||||||
n.sons[1] = arg
|
n.sons[1] = arg
|
||||||
|
|
@ -1277,7 +1289,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
{tyInt..tyInt64}:
|
{tyInt..tyInt64}:
|
||||||
var idx = getOrdValue(n.sons[1])
|
var idx = getOrdValue(n.sons[1])
|
||||||
if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)]
|
if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)]
|
||||||
else: localError(c.config, n.info, errInvalidIndexValueForTuple)
|
else: localError(c.config, n.info, "invalid index value for tuple subscript")
|
||||||
result = n
|
result = n
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
|
|
@ -1317,7 +1329,7 @@ proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]"))
|
result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]"))
|
||||||
|
|
||||||
proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
|
proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
|
||||||
var id = considerQuotedIdent(a[1], a)
|
var id = considerQuotedIdent(c.config, a[1], a)
|
||||||
var setterId = newIdentNode(getIdent(id.s & '='), n.info)
|
var setterId = newIdentNode(getIdent(id.s & '='), n.info)
|
||||||
# a[0] is already checked for semantics, that does ``builtinFieldAccess``
|
# a[0] is already checked for semantics, that does ``builtinFieldAccess``
|
||||||
# this is ugly. XXX Semantic checking should use the ``nfSem`` flag for
|
# this is ugly. XXX Semantic checking should use the ``nfSem`` flag for
|
||||||
|
|
@ -1354,7 +1366,7 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
|
||||||
let valid = isAssignable(c, n)
|
let valid = isAssignable(c, n)
|
||||||
if valid != arLValue:
|
if valid != arLValue:
|
||||||
if valid == arLocalLValue:
|
if valid == arLocalLValue:
|
||||||
localError(c.config, n.info, errXStackEscape, renderTree(n, {renderNoComments}))
|
localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments}))
|
||||||
elif not isLent:
|
elif not isLent:
|
||||||
localError(c.config, n.info, errExprHasNoAddress)
|
localError(c.config, n.info, errExprHasNoAddress)
|
||||||
result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ))
|
result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ))
|
||||||
|
|
@ -1426,7 +1438,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
isAssignable(c, a) == arNone) or
|
isAssignable(c, a) == arNone) or
|
||||||
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}:
|
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}:
|
||||||
# Direct assignment to a discriminant is allowed!
|
# Direct assignment to a discriminant is allowed!
|
||||||
localError(c.config, a.info, errXCannotBeAssignedTo,
|
localError(c.config, a.info, errXCannotBeAssignedTo %
|
||||||
renderTree(a, {renderNoComments}))
|
renderTree(a, {renderNoComments}))
|
||||||
else:
|
else:
|
||||||
let
|
let
|
||||||
|
|
@ -1442,12 +1454,12 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass:
|
if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass:
|
||||||
rhsTyp = rhsTyp.lastSon
|
rhsTyp = rhsTyp.lastSon
|
||||||
if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}:
|
if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}:
|
||||||
internalAssert c.p.resultSym != nil
|
internalAssert c.config, c.p.resultSym != nil
|
||||||
lhs.typ = rhsTyp
|
lhs.typ = rhsTyp
|
||||||
c.p.resultSym.typ = rhsTyp
|
c.p.resultSym.typ = rhsTyp
|
||||||
c.p.owner.typ.sons[0] = rhsTyp
|
c.p.owner.typ.sons[0] = rhsTyp
|
||||||
else:
|
else:
|
||||||
typeMismatch(n.info, lhs.typ, rhsTyp)
|
typeMismatch(c.config, n.info, lhs.typ, rhsTyp)
|
||||||
|
|
||||||
n.sons[1] = fitNode(c, le, rhs, n.info)
|
n.sons[1] = fitNode(c, le, rhs, n.info)
|
||||||
if destructor notin c.features:
|
if destructor notin c.features:
|
||||||
|
|
@ -1479,7 +1491,7 @@ proc semReturn(c: PContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errNoReturnTypeDeclared)
|
localError(c.config, n.info, errNoReturnTypeDeclared)
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errXNotAllowedHere, "\'return\'")
|
localError(c.config, n.info, "'return' not allowed here")
|
||||||
|
|
||||||
proc semProcBody(c: PContext, n: PNode): PNode =
|
proc semProcBody(c: PContext, n: PNode): PNode =
|
||||||
openScope(c)
|
openScope(c)
|
||||||
|
|
@ -1551,7 +1563,7 @@ proc semYield(c: PContext, n: PNode): PNode =
|
||||||
if restype != nil:
|
if restype != nil:
|
||||||
if restype.kind != tyExpr:
|
if restype.kind != tyExpr:
|
||||||
n.sons[0] = fitNode(c, restype, n.sons[0], n.info)
|
n.sons[0] = fitNode(c, restype, n.sons[0], n.info)
|
||||||
if n.sons[0].typ == nil: internalError(n.info, "semYield")
|
if n.sons[0].typ == nil: internalError(c.config, n.info, "semYield")
|
||||||
|
|
||||||
if resultTypeIsInferrable(restype):
|
if resultTypeIsInferrable(restype):
|
||||||
let inferred = n.sons[0].typ
|
let inferred = n.sons[0].typ
|
||||||
|
|
@ -1579,19 +1591,19 @@ proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
|
||||||
checkSonsLen(n, 2, c.config)
|
checkSonsLen(n, 2, c.config)
|
||||||
var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope)
|
var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope)
|
||||||
if m != nil and m.kind == skModule:
|
if m != nil and m.kind == skModule:
|
||||||
let ident = considerQuotedIdent(n[1], n)
|
let ident = considerQuotedIdent(c.config, n[1], n)
|
||||||
if m == c.module:
|
if m == c.module:
|
||||||
result = strTableGet(c.topLevelScope.symbols, ident)
|
result = strTableGet(c.topLevelScope.symbols, ident)
|
||||||
else:
|
else:
|
||||||
result = strTableGet(m.tab, ident)
|
result = strTableGet(m.tab, ident)
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
result = lookUpForDefined(c, considerQuotedIdent(n), onlyCurrentScope)
|
result = lookUpForDefined(c, considerQuotedIdent(c.config, n), onlyCurrentScope)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
result = n.sym
|
result = n.sym
|
||||||
of nkOpenSymChoice, nkClosedSymChoice:
|
of nkOpenSymChoice, nkClosedSymChoice:
|
||||||
result = n.sons[0].sym
|
result = n.sons[0].sym
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errIdentifierExpected, renderTree(n))
|
localError(c.config, n.info, "identifier expected, but got: " & renderTree(n))
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =
|
proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =
|
||||||
|
|
@ -1601,12 +1613,12 @@ proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =
|
||||||
if not onlyCurrentScope and considerQuotedIdent(c.config, n[0], n).s == "defined":
|
if not onlyCurrentScope and considerQuotedIdent(c.config, n[0], n).s == "defined":
|
||||||
if n.sons[1].kind != nkIdent:
|
if n.sons[1].kind != nkIdent:
|
||||||
localError(c.config, n.info, "obsolete usage of 'defined', use 'declared' instead")
|
localError(c.config, n.info, "obsolete usage of 'defined', use 'declared' instead")
|
||||||
elif condsyms.isDefined(n.sons[1].ident):
|
elif isDefined(c.config, n.sons[1].ident.s):
|
||||||
result.intVal = 1
|
result.intVal = 1
|
||||||
elif lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil:
|
elif lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil:
|
||||||
result.intVal = 1
|
result.intVal = 1
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
result.typ = getSysType(tyBool)
|
result.typ = getSysType(c.graph, n.info, tyBool)
|
||||||
|
|
||||||
proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym =
|
proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym =
|
||||||
## The argument to the proc should be nkCall(...) or similar
|
## The argument to the proc should be nkCall(...) or similar
|
||||||
|
|
@ -1618,12 +1630,12 @@ proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym =
|
||||||
return errorSym(c, n[0])
|
return errorSym(c, n[0])
|
||||||
|
|
||||||
if expandedSym.kind notin {skMacro, skTemplate}:
|
if expandedSym.kind notin {skMacro, skTemplate}:
|
||||||
localError(c.config, n.info, errXisNoMacroOrTemplate, expandedSym.name.s)
|
localError(c.config, n.info, "'$1' is not a macro or template" % expandedSym.name.s)
|
||||||
return errorSym(c, n[0])
|
return errorSym(c, n[0])
|
||||||
|
|
||||||
result = expandedSym
|
result = expandedSym
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errXisNoMacroOrTemplate, n.renderTree)
|
localError(c.config, n.info, "'$1' is not a macro or template" % n.renderTree)
|
||||||
result = errorSym(c, n)
|
result = errorSym(c, n)
|
||||||
|
|
||||||
proc expectString(c: PContext, n: PNode): string =
|
proc expectString(c: PContext, n: PNode): string =
|
||||||
|
|
@ -1633,10 +1645,6 @@ proc expectString(c: PContext, n: PNode): string =
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errStringLiteralExpected)
|
localError(c.config, n.info, errStringLiteralExpected)
|
||||||
|
|
||||||
proc getMagicSym(magic: TMagic): PSym =
|
|
||||||
result = newSym(skProc, getIdent($magic), systemModule, gCodegenLineInfo)
|
|
||||||
result.magic = magic
|
|
||||||
|
|
||||||
proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym =
|
proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym =
|
||||||
result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info)
|
result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info)
|
||||||
result.flags = {sfGenSym}
|
result.flags = {sfGenSym}
|
||||||
|
|
@ -1649,7 +1657,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode =
|
||||||
if expandedSym.kind == skError: return n
|
if expandedSym.kind == skError: return n
|
||||||
|
|
||||||
macroCall.sons[0] = newSymNode(expandedSym, macroCall.info)
|
macroCall.sons[0] = newSymNode(expandedSym, macroCall.info)
|
||||||
markUsed(n.info, expandedSym, c.graph.usageSym)
|
markUsed(c.config, n.info, expandedSym, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, expandedSym)
|
styleCheckUse(n.info, expandedSym)
|
||||||
|
|
||||||
if isCallExpr(macroCall):
|
if isCallExpr(macroCall):
|
||||||
|
|
@ -1674,7 +1682,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
let info = macroCall.sons[0].info
|
let info = macroCall.sons[0].info
|
||||||
macroCall.sons[0] = newSymNode(cand, info)
|
macroCall.sons[0] = newSymNode(cand, info)
|
||||||
markUsed(info, cand, c.graph.usageSym)
|
markUsed(c.config, info, cand, c.graph.usageSym)
|
||||||
styleCheckUse(info, cand)
|
styleCheckUse(info, cand)
|
||||||
|
|
||||||
# we just perform overloading resolution here:
|
# we just perform overloading resolution here:
|
||||||
|
|
@ -1682,12 +1690,11 @@ proc semExpandToAst(c: PContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, "getAst takes a call, but got " & n.renderTree)
|
localError(c.config, n.info, "getAst takes a call, but got " & n.renderTree)
|
||||||
# Preserve the magic symbol in order to be handled in evals.nim
|
# Preserve the magic symbol in order to be handled in evals.nim
|
||||||
internalAssert n.sons[0].sym.magic == mExpandToAst
|
internalAssert c.config, n.sons[0].sym.magic == mExpandToAst
|
||||||
#n.typ = getSysSym("NimNode").typ # expandedSym.getReturnType
|
#n.typ = getSysSym("NimNode").typ # expandedSym.getReturnType
|
||||||
if n.kind == nkStmtList and n.len == 1: result = n[0]
|
if n.kind == nkStmtList and n.len == 1: result = n[0]
|
||||||
else: result = n
|
else: result = n
|
||||||
result.typ = if getCompilerProc("NimNode") != nil: sysTypeFromName"NimNode"
|
result.typ = sysTypeFromName(c.graph, n.info, "NimNode")
|
||||||
else: sysTypeFromName"PNimrodNode"
|
|
||||||
|
|
||||||
proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym,
|
proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym,
|
||||||
flags: TExprFlags = {}): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
|
|
@ -1697,7 +1704,7 @@ proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym,
|
||||||
else:
|
else:
|
||||||
result = semDirectOp(c, n, flags)
|
result = semDirectOp(c, n, flags)
|
||||||
|
|
||||||
proc processQuotations(n: var PNode, op: string,
|
proc processQuotations(c: PContext; n: var PNode, op: string,
|
||||||
quotes: var seq[PNode],
|
quotes: var seq[PNode],
|
||||||
ids: var seq[PNode]) =
|
ids: var seq[PNode]) =
|
||||||
template returnQuote(q) =
|
template returnQuote(q) =
|
||||||
|
|
@ -1718,10 +1725,10 @@ proc processQuotations(n: var PNode, op: string,
|
||||||
returnQuote n[0]
|
returnQuote n[0]
|
||||||
|
|
||||||
for i in 0 ..< n.safeLen:
|
for i in 0 ..< n.safeLen:
|
||||||
processQuotations(n.sons[i], op, quotes, ids)
|
processQuotations(c, n.sons[i], op, quotes, ids)
|
||||||
|
|
||||||
proc semQuoteAst(c: PContext, n: PNode): PNode =
|
proc semQuoteAst(c: PContext, n: PNode): PNode =
|
||||||
internalAssert n.len == 2 or n.len == 3
|
internalAssert c.config, n.len == 2 or n.len == 3
|
||||||
# We transform the do block into a template with a param for
|
# We transform the do block into a template with a param for
|
||||||
# each interpolation. We'll pass this template to getAst.
|
# each interpolation. We'll pass this template to getAst.
|
||||||
var
|
var
|
||||||
|
|
@ -1736,7 +1743,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
|
||||||
if quotedBlock.kind != nkStmtList:
|
if quotedBlock.kind != nkStmtList:
|
||||||
localError(c.config, n.info, errXExpected, "block")
|
localError(c.config, n.info, errXExpected, "block")
|
||||||
|
|
||||||
processQuotations(quotedBlock, op, quotes, ids)
|
processQuotations(c, quotedBlock, op, quotes, ids)
|
||||||
|
|
||||||
var dummyTemplate = newProcNode(
|
var dummyTemplate = newProcNode(
|
||||||
nkTemplateDef, quotedBlock.info, quotedBlock,
|
nkTemplateDef, quotedBlock.info, quotedBlock,
|
||||||
|
|
@ -1744,27 +1751,27 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
|
||||||
|
|
||||||
if ids.len > 0:
|
if ids.len > 0:
|
||||||
dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info)
|
dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info)
|
||||||
dummyTemplate[paramsPos].add getSysSym("typed").newSymNode # return type
|
dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "typed").newSymNode # return type
|
||||||
ids.add getSysSym("untyped").newSymNode # params type
|
ids.add getSysSym(c.graph, n.info, "untyped").newSymNode # params type
|
||||||
ids.add emptyNode # no default value
|
ids.add emptyNode # no default value
|
||||||
dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids)
|
dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids)
|
||||||
|
|
||||||
var tmpl = semTemplateDef(c, dummyTemplate)
|
var tmpl = semTemplateDef(c, dummyTemplate)
|
||||||
quotes[0] = tmpl[namePos]
|
quotes[0] = tmpl[namePos]
|
||||||
result = newNode(nkCall, n.info, @[
|
result = newNode(nkCall, n.info, @[
|
||||||
getMagicSym(mExpandToAst).newSymNode,
|
createMagic(c.graph, "getAst", mExpandToAst).newSymNode,
|
||||||
newNode(nkCall, n.info, quotes)])
|
newNode(nkCall, n.info, quotes)])
|
||||||
result = semExpandToAst(c, result)
|
result = semExpandToAst(c, result)
|
||||||
|
|
||||||
proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
# watch out, hacks ahead:
|
# watch out, hacks ahead:
|
||||||
let oldErrorCount = msgs.gErrorCounter
|
let oldErrorCount = c.config.errorCounter
|
||||||
let oldErrorMax = msgs.gErrorMax
|
let oldErrorMax = c.config.errorMax
|
||||||
let oldCompilesId = c.compilesContextId
|
let oldCompilesId = c.compilesContextId
|
||||||
inc c.compilesContextIdGenerator
|
inc c.compilesContextIdGenerator
|
||||||
c.compilesContextId = c.compilesContextIdGenerator
|
c.compilesContextId = c.compilesContextIdGenerator
|
||||||
# do not halt after first error:
|
# do not halt after first error:
|
||||||
msgs.gErrorMax = high(int)
|
c.config.errorMax = high(int)
|
||||||
|
|
||||||
# open a scope for temporary symbol inclusions:
|
# open a scope for temporary symbol inclusions:
|
||||||
let oldScope = c.currentScope
|
let oldScope = c.currentScope
|
||||||
|
|
@ -1783,7 +1790,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
var err: string
|
var err: string
|
||||||
try:
|
try:
|
||||||
result = semExpr(c, n, flags)
|
result = semExpr(c, n, flags)
|
||||||
if msgs.gErrorCounter != oldErrorCount: result = nil
|
if c.config.errorCounter != oldErrorCount: result = nil
|
||||||
except ERecoverableError:
|
except ERecoverableError:
|
||||||
discard
|
discard
|
||||||
# undo symbol table changes (as far as it's possible):
|
# undo symbol table changes (as far as it's possible):
|
||||||
|
|
@ -1797,8 +1804,8 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
setLen(c.graph.owners, oldOwnerLen)
|
setLen(c.graph.owners, oldOwnerLen)
|
||||||
c.currentScope = oldScope
|
c.currentScope = oldScope
|
||||||
errorOutputs = oldErrorOutputs
|
errorOutputs = oldErrorOutputs
|
||||||
msgs.gErrorCounter = oldErrorCount
|
c.config.errorCounter = oldErrorCount
|
||||||
msgs.gErrorMax = oldErrorMax
|
c.config.errorMax = oldErrorMax
|
||||||
|
|
||||||
proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# we replace this node by a 'true' or 'false' node:
|
# we replace this node by a 'true' or 'false' node:
|
||||||
|
|
@ -1806,7 +1813,7 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
||||||
result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil))
|
result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil))
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
result.typ = getSysType(tyBool)
|
result.typ = getSysType(c.graph, n.info, tyBool)
|
||||||
|
|
||||||
proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if sonsLen(n) == 3:
|
if sonsLen(n) == 3:
|
||||||
|
|
@ -1821,15 +1828,15 @@ proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
||||||
proc createFlowVar(c: PContext; t: PType; info: TLineInfo): PType =
|
proc createFlowVar(c: PContext; t: PType; info: TLineInfo): PType =
|
||||||
result = newType(tyGenericInvocation, c.module)
|
result = newType(tyGenericInvocation, c.module)
|
||||||
addSonSkipIntLit(result, magicsys.getCompilerProc("FlowVar").typ)
|
addSonSkipIntLit(result, magicsys.getCompilerProc(c.graph, "FlowVar").typ)
|
||||||
addSonSkipIntLit(result, t)
|
addSonSkipIntLit(result, t)
|
||||||
result = instGenericContainer(c, info, result, allowMetaTypes = false)
|
result = instGenericContainer(c, info, result, allowMetaTypes = false)
|
||||||
|
|
||||||
proc instantiateCreateFlowVarCall(c: PContext; t: PType;
|
proc instantiateCreateFlowVarCall(c: PContext; t: PType;
|
||||||
info: TLineInfo): PSym =
|
info: TLineInfo): PSym =
|
||||||
let sym = magicsys.getCompilerProc("nimCreateFlowVar")
|
let sym = magicsys.getCompilerProc(c.graph, "nimCreateFlowVar")
|
||||||
if sym == nil:
|
if sym == nil:
|
||||||
localError(c.config, info, errSystemNeeds, "nimCreateFlowVar")
|
localError(c.config, info, "system needs: nimCreateFlowVar")
|
||||||
var bindings: TIdTable
|
var bindings: TIdTable
|
||||||
initIdTable(bindings)
|
initIdTable(bindings)
|
||||||
bindings.idTablePut(sym.ast[genericParamsPos].sons[0].typ, t)
|
bindings.idTablePut(sym.ast[genericParamsPos].sons[0].typ, t)
|
||||||
|
|
@ -1879,8 +1886,8 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||||
of mQuoteAst: result = semQuoteAst(c, n)
|
of mQuoteAst: result = semQuoteAst(c, n)
|
||||||
of mAstToStr:
|
of mAstToStr:
|
||||||
checkSonsLen(n, 2, c.config)
|
checkSonsLen(n, 2, c.config)
|
||||||
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
|
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, c.graph)
|
||||||
result.typ = getSysType(tyString)
|
result.typ = getSysType(c.graph, n.info, tyString)
|
||||||
of mParallel:
|
of mParallel:
|
||||||
if parallel notin c.features:
|
if parallel notin c.features:
|
||||||
localError(c.config, n.info, "use the {.experimental.} pragma to enable 'parallel'")
|
localError(c.config, n.info, "use the {.experimental.} pragma to enable 'parallel'")
|
||||||
|
|
@ -2072,7 +2079,7 @@ type
|
||||||
TParKind = enum
|
TParKind = enum
|
||||||
paNone, paSingle, paTupleFields, paTuplePositions
|
paNone, paSingle, paTupleFields, paTuplePositions
|
||||||
|
|
||||||
proc checkPar(n: PNode): TParKind =
|
proc checkPar(c: PContext; n: PNode): TParKind =
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
if length == 0:
|
if length == 0:
|
||||||
result = paTuplePositions # ()
|
result = paTuplePositions # ()
|
||||||
|
|
@ -2106,7 +2113,7 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if n.sons[i].sons[0].kind == nkIdent: id = n.sons[i].sons[0].ident
|
if n.sons[i].sons[0].kind == nkIdent: id = n.sons[i].sons[0].ident
|
||||||
else: id = n.sons[i].sons[0].sym.name
|
else: id = n.sons[i].sons[0].sym.name
|
||||||
if containsOrIncl(ids, id.id):
|
if containsOrIncl(ids, id.id):
|
||||||
localError(c.config, n.sons[i].info, errFieldInitTwice, id.s)
|
localError(c.config, n.sons[i].info, errFieldInitTwice % id.s)
|
||||||
n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1],
|
n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1],
|
||||||
flags*{efAllowDestructor})
|
flags*{efAllowDestructor})
|
||||||
var f = newSymS(skField, n.sons[i].sons[0], c)
|
var f = newSymS(skField, n.sons[i].sons[0], c)
|
||||||
|
|
@ -2225,39 +2232,39 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkEmpty, nkNone, nkCommentStmt, nkType:
|
of nkEmpty, nkNone, nkCommentStmt, nkType:
|
||||||
discard
|
discard
|
||||||
of nkNilLit:
|
of nkNilLit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyNil)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyNil)
|
||||||
of nkIntLit:
|
of nkIntLit:
|
||||||
if result.typ == nil: setIntLitType(result)
|
if result.typ == nil: setIntLitType(c.graph, result)
|
||||||
of nkInt8Lit:
|
of nkInt8Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyInt8)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt8)
|
||||||
of nkInt16Lit:
|
of nkInt16Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyInt16)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt16)
|
||||||
of nkInt32Lit:
|
of nkInt32Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyInt32)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt32)
|
||||||
of nkInt64Lit:
|
of nkInt64Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyInt64)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt64)
|
||||||
of nkUIntLit:
|
of nkUIntLit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyUInt)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt)
|
||||||
of nkUInt8Lit:
|
of nkUInt8Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyUInt8)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt8)
|
||||||
of nkUInt16Lit:
|
of nkUInt16Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyUInt16)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt16)
|
||||||
of nkUInt32Lit:
|
of nkUInt32Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyUInt32)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt32)
|
||||||
of nkUInt64Lit:
|
of nkUInt64Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyUInt64)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt64)
|
||||||
#of nkFloatLit:
|
#of nkFloatLit:
|
||||||
# if result.typ == nil: result.typ = getFloatLitType(result)
|
# if result.typ == nil: result.typ = getFloatLitType(result)
|
||||||
of nkFloat32Lit:
|
of nkFloat32Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyFloat32)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat32)
|
||||||
of nkFloat64Lit, nkFloatLit:
|
of nkFloat64Lit, nkFloatLit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyFloat64)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat64)
|
||||||
of nkFloat128Lit:
|
of nkFloat128Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyFloat128)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat128)
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyString)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyString)
|
||||||
of nkCharLit:
|
of nkCharLit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyChar)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyChar)
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
result = semFieldAccess(c, n, flags)
|
result = semFieldAccess(c, n, flags)
|
||||||
if result.kind == nkDotCall:
|
if result.kind == nkDotCall:
|
||||||
|
|
@ -2341,7 +2348,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
var
|
var
|
||||||
expr = n[0]
|
expr = n[0]
|
||||||
pragma = n[1]
|
pragma = n[1]
|
||||||
pragmaName = considerQuotedIdent(pragma[0])
|
pragmaName = considerQuotedIdent(c.config, pragma[0])
|
||||||
flags = flags
|
flags = flags
|
||||||
|
|
||||||
case whichKeyword(pragmaName)
|
case whichKeyword(pragmaName)
|
||||||
|
|
@ -2349,11 +2356,11 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
flags.incl efExplain
|
flags.incl efExplain
|
||||||
else:
|
else:
|
||||||
# what other pragmas are allowed for expressions? `likely`, `unlikely`
|
# what other pragmas are allowed for expressions? `likely`, `unlikely`
|
||||||
invalidPragma(n)
|
invalidPragma(c, n)
|
||||||
|
|
||||||
result = semExpr(c, n[0], flags)
|
result = semExpr(c, n[0], flags)
|
||||||
of nkPar, nkTupleConstr:
|
of nkPar, nkTupleConstr:
|
||||||
case checkPar(n)
|
case checkPar(c, n)
|
||||||
of paNone: result = errorNode(c, n)
|
of paNone: result = errorNode(c, n)
|
||||||
of paTuplePositions:
|
of paTuplePositions:
|
||||||
var tupexp = semTuplePositionsConstr(c, n, flags)
|
var tupexp = semTuplePositionsConstr(c, n, flags)
|
||||||
|
|
@ -2433,19 +2440,19 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
#
|
#
|
||||||
# works:
|
# works:
|
||||||
if c.currentScope.depthLevel > 2 + c.compilesContextId:
|
if c.currentScope.depthLevel > 2 + c.compilesContextId:
|
||||||
localError(c.config, n.info, errXOnlyAtModuleScope, "import")
|
localError(c.config, n.info, errXOnlyAtModuleScope % "import")
|
||||||
result = evalImport(c, n)
|
result = evalImport(c, n)
|
||||||
of nkImportExceptStmt:
|
of nkImportExceptStmt:
|
||||||
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "import")
|
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "import")
|
||||||
result = evalImportExcept(c, n)
|
result = evalImportExcept(c, n)
|
||||||
of nkFromStmt:
|
of nkFromStmt:
|
||||||
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "from")
|
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "from")
|
||||||
result = evalFrom(c, n)
|
result = evalFrom(c, n)
|
||||||
of nkIncludeStmt:
|
of nkIncludeStmt:
|
||||||
#if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "include")
|
#if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "include")
|
||||||
result = evalInclude(c, n)
|
result = evalInclude(c, n)
|
||||||
of nkExportStmt, nkExportExceptStmt:
|
of nkExportStmt, nkExportExceptStmt:
|
||||||
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "export")
|
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "export")
|
||||||
result = semExport(c, n)
|
result = semExport(c, n)
|
||||||
of nkPragmaBlock:
|
of nkPragmaBlock:
|
||||||
result = semPragmaBlock(c, n)
|
result = semPragmaBlock(c, n)
|
||||||
|
|
@ -2454,7 +2461,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkDefer:
|
of nkDefer:
|
||||||
n.sons[0] = semExpr(c, n.sons[0])
|
n.sons[0] = semExpr(c, n.sons[0])
|
||||||
if not n.sons[0].typ.isEmptyType and not implicitlyDiscardable(n.sons[0]):
|
if not n.sons[0].typ.isEmptyType and not implicitlyDiscardable(n.sons[0]):
|
||||||
localError(c.config, n.info, errGenerated, "'defer' takes a 'void' expression")
|
localError(c.config, n.info, "'defer' takes a 'void' expression")
|
||||||
#localError(c.config, n.info, errGenerated, "'defer' not allowed in this context")
|
#localError(c.config, n.info, errGenerated, "'defer' not allowed in this context")
|
||||||
of nkGotoState, nkState:
|
of nkGotoState, nkState:
|
||||||
if n.len != 1 and n.len != 2: illFormedAst(n, c.config)
|
if n.len != 1 and n.len != 2: illFormedAst(n, c.config)
|
||||||
|
|
@ -2462,6 +2469,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
n.sons[i] = semExpr(c, n.sons[i])
|
n.sons[i] = semExpr(c, n.sons[i])
|
||||||
of nkComesFrom: discard "ignore the comes from information for now"
|
of nkComesFrom: discard "ignore the comes from information for now"
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errInvalidExpressionX,
|
localError(c.config, n.info, "invalid expression: " &
|
||||||
renderTree(n, {renderNoComments}))
|
renderTree(n, {renderNoComments}))
|
||||||
if result != nil: incl(result.flags, nfSem)
|
if result != nil: incl(result.flags, nfSem)
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ proc semAsgnOpr(c: PContext; n: PNode): PNode =
|
||||||
|
|
||||||
proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
var r = isPartOf(n[1], n[2])
|
var r = isPartOf(n[1], n[2])
|
||||||
result = newIntNodeT(ord(r), n)
|
result = newIntNodeT(ord(r), n, c.graph)
|
||||||
|
|
||||||
proc expectIntLit(c: PContext, n: PNode): int =
|
proc expectIntLit(c: PContext, n: PNode): int =
|
||||||
let x = c.semConstExpr(c, n)
|
let x = c.semConstExpr(c, n)
|
||||||
|
|
@ -77,11 +77,11 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
||||||
let idx = expectIntLit(c, n.sons[1])
|
let idx = expectIntLit(c, n.sons[1])
|
||||||
let useFullPaths = expectIntLit(c, n.sons[2])
|
let useFullPaths = expectIntLit(c, n.sons[2])
|
||||||
let info = getInfoContext(idx)
|
let info = getInfoContext(idx)
|
||||||
var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
var filename = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString))
|
||||||
filename.strVal = if useFullPaths != 0: info.toFullPath else: info.toFilename
|
filename.strVal = if useFullPaths != 0: info.toFullPath else: info.toFilename
|
||||||
var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt))
|
var line = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt))
|
||||||
line.intVal = toLinenumber(info)
|
line.intVal = toLinenumber(info)
|
||||||
var column = newNodeIT(nkIntLit, n.info, getSysType(tyInt))
|
var column = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt))
|
||||||
column.intVal = toColumn(info)
|
column.intVal = toColumn(info)
|
||||||
result.add(filename)
|
result.add(filename)
|
||||||
result.add(line)
|
result.add(line)
|
||||||
|
|
@ -110,10 +110,10 @@ proc uninstantiate(t: PType): PType =
|
||||||
of tyCompositeTypeClass: uninstantiate t.sons[1]
|
of tyCompositeTypeClass: uninstantiate t.sons[1]
|
||||||
else: t
|
else: t
|
||||||
|
|
||||||
proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym): PNode =
|
||||||
const skippedTypes = {tyTypeDesc, tyAlias, tySink}
|
const skippedTypes = {tyTypeDesc, tyAlias, tySink}
|
||||||
let trait = traitCall[0]
|
let trait = traitCall[0]
|
||||||
internalAssert trait.kind == nkSym
|
internalAssert c.config, trait.kind == nkSym
|
||||||
var operand = operand.skipTypes(skippedTypes)
|
var operand = operand.skipTypes(skippedTypes)
|
||||||
|
|
||||||
template operand2: PType =
|
template operand2: PType =
|
||||||
|
|
@ -151,19 +151,19 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
||||||
let t = operand.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
let t = operand.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
||||||
let complexObj = containsGarbageCollectedRef(t) or
|
let complexObj = containsGarbageCollectedRef(t) or
|
||||||
hasDestructor(t)
|
hasDestructor(t)
|
||||||
result = newIntNodeT(ord(not complexObj), traitCall)
|
result = newIntNodeT(ord(not complexObj), traitCall, c.graph)
|
||||||
else:
|
else:
|
||||||
localError(c.config, traitCall.info, "unknown trait")
|
localError(c.config, traitCall.info, "unknown trait")
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc semTypeTraits(c: PContext, n: PNode): PNode =
|
proc semTypeTraits(c: PContext, n: PNode): PNode =
|
||||||
checkMinSonsLen(n, 2)
|
checkMinSonsLen(n, 2, c.config)
|
||||||
let t = n.sons[1].typ
|
let t = n.sons[1].typ
|
||||||
internalAssert t != nil and t.kind == tyTypeDesc
|
internalAssert c.config, t != nil and t.kind == tyTypeDesc
|
||||||
if t.sonsLen > 0:
|
if t.sonsLen > 0:
|
||||||
# This is either a type known to sem or a typedesc
|
# This is either a type known to sem or a typedesc
|
||||||
# param to a regular proc (again, known at instantiation)
|
# param to a regular proc (again, known at instantiation)
|
||||||
result = evalTypeTrait(n, t, getCurrOwner(c))
|
result = evalTypeTrait(c, n, t, getCurrOwner(c))
|
||||||
else:
|
else:
|
||||||
# a typedesc variable, pass unmodified to evals
|
# a typedesc variable, pass unmodified to evals
|
||||||
result = n
|
result = n
|
||||||
|
|
@ -221,9 +221,9 @@ proc semOf(c: PContext, n: PNode): PNode =
|
||||||
let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc})
|
let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc})
|
||||||
|
|
||||||
if x.kind == tyTypeDesc or y.kind != tyTypeDesc:
|
if x.kind == tyTypeDesc or y.kind != tyTypeDesc:
|
||||||
localError(c.config, n.info, errXExpectsObjectTypes, "of")
|
localError(c.config, n.info, "'of' takes object types")
|
||||||
elif b.kind != tyObject or a.kind != tyObject:
|
elif b.kind != tyObject or a.kind != tyObject:
|
||||||
localError(c.config, n.info, errXExpectsObjectTypes, "of")
|
localError(c.config, n.info, "'of' takes object types")
|
||||||
else:
|
else:
|
||||||
let diff = inheritanceDiff(a, b)
|
let diff = inheritanceDiff(a, b)
|
||||||
# | returns: 0 iff `a` == `b`
|
# | returns: 0 iff `a` == `b`
|
||||||
|
|
@ -232,26 +232,26 @@ proc semOf(c: PContext, n: PNode): PNode =
|
||||||
# | returns: `maxint` iff `a` and `b` are not compatible at all
|
# | returns: `maxint` iff `a` and `b` are not compatible at all
|
||||||
if diff <= 0:
|
if diff <= 0:
|
||||||
# optimize to true:
|
# optimize to true:
|
||||||
message(n.info, hintConditionAlwaysTrue, renderTree(n))
|
message(c.config, n.info, hintConditionAlwaysTrue, renderTree(n))
|
||||||
result = newIntNode(nkIntLit, 1)
|
result = newIntNode(nkIntLit, 1)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
result.typ = getSysType(tyBool)
|
result.typ = getSysType(c.graph, n.info, tyBool)
|
||||||
return result
|
return result
|
||||||
elif diff == high(int):
|
elif diff == high(int):
|
||||||
localError(c.config, n.info, errXcanNeverBeOfThisSubtype, typeToString(a))
|
localError(c.config, n.info, "'$1' cannot be of this subtype" % typeToString(a))
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errXExpectsTwoArguments, "of")
|
localError(c.config, n.info, "'of' takes 2 arguments")
|
||||||
n.typ = getSysType(tyBool)
|
n.typ = getSysType(c.graph, n.info, tyBool)
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||||
flags: TExprFlags): PNode =
|
flags: TExprFlags): PNode =
|
||||||
case n[0].sym.magic
|
case n[0].sym.magic
|
||||||
of mAddr:
|
of mAddr:
|
||||||
checkSonsLen(n, 2)
|
checkSonsLen(n, 2, c.config)
|
||||||
result = semAddr(c, n.sons[1], n[0].sym.name.s == "unsafeAddr")
|
result = semAddr(c, n.sons[1], n[0].sym.name.s == "unsafeAddr")
|
||||||
of mTypeOf:
|
of mTypeOf:
|
||||||
checkSonsLen(n, 2)
|
checkSonsLen(n, 2, c.config)
|
||||||
result = semTypeOf(c, n.sons[1])
|
result = semTypeOf(c, n.sons[1])
|
||||||
of mArrGet: result = semArrGet(c, n, flags)
|
of mArrGet: result = semArrGet(c, n, flags)
|
||||||
of mArrPut: result = semArrPut(c, n, flags)
|
of mArrPut: result = semArrPut(c, n, flags)
|
||||||
|
|
@ -263,8 +263,8 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||||
of mIsPartOf: result = semIsPartOf(c, n, flags)
|
of mIsPartOf: result = semIsPartOf(c, n, flags)
|
||||||
of mTypeTrait: result = semTypeTraits(c, n)
|
of mTypeTrait: result = semTypeTraits(c, n)
|
||||||
of mAstToStr:
|
of mAstToStr:
|
||||||
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
|
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, c.graph)
|
||||||
result.typ = getSysType(tyString)
|
result.typ = getSysType(c.graph, n.info, tyString)
|
||||||
of mInstantiationInfo: result = semInstantiationInfo(c, n)
|
of mInstantiationInfo: result = semInstantiationInfo(c, n)
|
||||||
of mOrd: result = semOrd(c, n)
|
of mOrd: result = semOrd(c, n)
|
||||||
of mOf: result = semOf(c, n)
|
of mOf: result = semOf(c, n)
|
||||||
|
|
|
||||||
|
|
@ -39,32 +39,32 @@ proc mergeInitStatus(existing: var InitStatus, newStatus: InitStatus) =
|
||||||
of initUnknown:
|
of initUnknown:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc invalidObjConstr(n: PNode) =
|
proc invalidObjConstr(c: PContext, n: PNode) =
|
||||||
if n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s[0] == ':':
|
if n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s[0] == ':':
|
||||||
localError(c.config, n.info, "incorrect object construction syntax; use a space after the colon")
|
localError(c.config, n.info, "incorrect object construction syntax; use a space after the colon")
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, "incorrect object construction syntax")
|
localError(c.config, n.info, "incorrect object construction syntax")
|
||||||
|
|
||||||
proc locateFieldInInitExpr(field: PSym, initExpr: PNode): PNode =
|
proc locateFieldInInitExpr(c: PContext, field: PSym, initExpr: PNode): PNode =
|
||||||
# Returns the assignment nkExprColonExpr node or nil
|
# Returns the assignment nkExprColonExpr node or nil
|
||||||
let fieldId = field.name.id
|
let fieldId = field.name.id
|
||||||
for i in 1 ..< initExpr.len:
|
for i in 1 ..< initExpr.len:
|
||||||
let assignment = initExpr[i]
|
let assignment = initExpr[i]
|
||||||
if assignment.kind != nkExprColonExpr:
|
if assignment.kind != nkExprColonExpr:
|
||||||
invalidObjConstr(assignment)
|
invalidObjConstr(c, assignment)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if fieldId == considerQuotedIdent(assignment[0]).id:
|
if fieldId == considerQuotedIdent(c.config, assignment[0]).id:
|
||||||
return assignment
|
return assignment
|
||||||
|
|
||||||
proc semConstrField(c: PContext, flags: TExprFlags,
|
proc semConstrField(c: PContext, flags: TExprFlags,
|
||||||
field: PSym, initExpr: PNode): PNode =
|
field: PSym, initExpr: PNode): PNode =
|
||||||
let assignment = locateFieldInInitExpr(field, initExpr)
|
let assignment = locateFieldInInitExpr(c, field, initExpr)
|
||||||
if assignment != nil:
|
if assignment != nil:
|
||||||
if nfSem in assignment.flags: return assignment[1]
|
if nfSem in assignment.flags: return assignment[1]
|
||||||
if not fieldVisible(c, field):
|
if not fieldVisible(c, field):
|
||||||
localError(c.config, initExpr.info,
|
localError(c.config, initExpr.info,
|
||||||
"the field '$1' is not accessible.", [field.name.s])
|
"the field '$1' is not accessible." % [field.name.s])
|
||||||
return
|
return
|
||||||
|
|
||||||
var initValue = semExprFlagDispatched(c, assignment[1], flags)
|
var initValue = semExprFlagDispatched(c, assignment[1], flags)
|
||||||
|
|
@ -101,25 +101,25 @@ iterator directFieldsInRecList(recList: PNode): PNode =
|
||||||
if recList.kind == nkSym:
|
if recList.kind == nkSym:
|
||||||
yield recList
|
yield recList
|
||||||
else:
|
else:
|
||||||
internalAssert recList.kind == nkRecList
|
doAssert recList.kind == nkRecList
|
||||||
for field in recList:
|
for field in recList:
|
||||||
if field.kind != nkSym: continue
|
if field.kind != nkSym: continue
|
||||||
yield field
|
yield field
|
||||||
|
|
||||||
template quoteStr(s: string): string = "'" & s & "'"
|
template quoteStr(s: string): string = "'" & s & "'"
|
||||||
|
|
||||||
proc fieldsPresentInInitExpr(fieldsRecList, initExpr: PNode): string =
|
proc fieldsPresentInInitExpr(c: PContext, fieldsRecList, initExpr: PNode): string =
|
||||||
result = ""
|
result = ""
|
||||||
for field in directFieldsInRecList(fieldsRecList):
|
for field in directFieldsInRecList(fieldsRecList):
|
||||||
let assignment = locateFieldInInitExpr(field.sym, initExpr)
|
let assignment = locateFieldInInitExpr(c, field.sym, initExpr)
|
||||||
if assignment != nil:
|
if assignment != nil:
|
||||||
if result.len != 0: result.add ", "
|
if result.len != 0: result.add ", "
|
||||||
result.add field.sym.name.s.quoteStr
|
result.add field.sym.name.s.quoteStr
|
||||||
|
|
||||||
proc missingMandatoryFields(fieldsRecList, initExpr: PNode): string =
|
proc missingMandatoryFields(c: PContext, fieldsRecList, initExpr: PNode): string =
|
||||||
for r in directFieldsInRecList(fieldsRecList):
|
for r in directFieldsInRecList(fieldsRecList):
|
||||||
if {tfNotNil, tfNeedsInit} * r.sym.typ.flags != {}:
|
if {tfNotNil, tfNeedsInit} * r.sym.typ.flags != {}:
|
||||||
let assignment = locateFieldInInitExpr(r.sym, initExpr)
|
let assignment = locateFieldInInitExpr(c, r.sym, initExpr)
|
||||||
if assignment == nil:
|
if assignment == nil:
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = r.sym.name.s
|
result = r.sym.name.s
|
||||||
|
|
@ -127,8 +127,8 @@ proc missingMandatoryFields(fieldsRecList, initExpr: PNode): string =
|
||||||
result.add ", "
|
result.add ", "
|
||||||
result.add r.sym.name.s
|
result.add r.sym.name.s
|
||||||
|
|
||||||
proc checkForMissingFields(recList, initExpr: PNode) =
|
proc checkForMissingFields(c: PContext, recList, initExpr: PNode) =
|
||||||
let missing = missingMandatoryFields(recList, initExpr)
|
let missing = missingMandatoryFields(c, recList, initExpr)
|
||||||
if missing != nil:
|
if missing != nil:
|
||||||
localError(c.config, initExpr.info, "fields not initialized: $1.", [missing])
|
localError(c.config, initExpr.info, "fields not initialized: $1.", [missing])
|
||||||
|
|
||||||
|
|
@ -146,14 +146,14 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
||||||
template fieldsPresentInBranch(branchIdx: int): string =
|
template fieldsPresentInBranch(branchIdx: int): string =
|
||||||
let branch = recNode[branchIdx]
|
let branch = recNode[branchIdx]
|
||||||
let fields = branch[branch.len - 1]
|
let fields = branch[branch.len - 1]
|
||||||
fieldsPresentInInitExpr(fields, initExpr)
|
fieldsPresentInInitExpr(c, fields, initExpr)
|
||||||
|
|
||||||
template checkMissingFields(branchNode: PNode) =
|
template checkMissingFields(branchNode: PNode) =
|
||||||
let fields = branchNode[branchNode.len - 1]
|
let fields = branchNode[branchNode.len - 1]
|
||||||
checkForMissingFields(fields, initExpr)
|
checkForMissingFields(c, fields, initExpr)
|
||||||
|
|
||||||
let discriminator = recNode.sons[0];
|
let discriminator = recNode.sons[0]
|
||||||
internalAssert discriminator.kind == nkSym
|
internalAssert c.config, discriminator.kind == nkSym
|
||||||
var selectedBranch = -1
|
var selectedBranch = -1
|
||||||
|
|
||||||
for i in 1 ..< recNode.len:
|
for i in 1 ..< recNode.len:
|
||||||
|
|
@ -165,8 +165,8 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
||||||
let prevFields = fieldsPresentInBranch(selectedBranch)
|
let prevFields = fieldsPresentInBranch(selectedBranch)
|
||||||
let currentFields = fieldsPresentInBranch(i)
|
let currentFields = fieldsPresentInBranch(i)
|
||||||
localError(c.config, initExpr.info,
|
localError(c.config, initExpr.info,
|
||||||
"The fields ($1) and ($2) cannot be initialized together, " &
|
("The fields '$1' and '$2' cannot be initialized together, " &
|
||||||
"because they are from conflicting branches in the case object.",
|
"because they are from conflicting branches in the case object.") %
|
||||||
[prevFields, currentFields])
|
[prevFields, currentFields])
|
||||||
result = initConflict
|
result = initConflict
|
||||||
else:
|
else:
|
||||||
|
|
@ -180,8 +180,8 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
||||||
if discriminatorVal == nil:
|
if discriminatorVal == nil:
|
||||||
let fields = fieldsPresentInBranch(selectedBranch)
|
let fields = fieldsPresentInBranch(selectedBranch)
|
||||||
localError(c.config, initExpr.info,
|
localError(c.config, initExpr.info,
|
||||||
"you must provide a compile-time value for the discriminator '$1' " &
|
("you must provide a compile-time value for the discriminator '$1' " &
|
||||||
"in order to prove that it's safe to initialize $2.",
|
"in order to prove that it's safe to initialize $2.") %
|
||||||
[discriminator.sym.name.s, fields])
|
[discriminator.sym.name.s, fields])
|
||||||
mergeInitStatus(result, initNone)
|
mergeInitStatus(result, initNone)
|
||||||
else:
|
else:
|
||||||
|
|
@ -219,7 +219,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
||||||
# value was given to the discrimator. We can assume that it will be
|
# value was given to the discrimator. We can assume that it will be
|
||||||
# initialized to zero and this will select a particular branch as
|
# initialized to zero and this will select a particular branch as
|
||||||
# a result:
|
# a result:
|
||||||
let matchedBranch = recNode.pickCaseBranch newIntLit(0)
|
let matchedBranch = recNode.pickCaseBranch newIntLit(c.graph, initExpr.info, 0)
|
||||||
checkMissingFields matchedBranch
|
checkMissingFields matchedBranch
|
||||||
else:
|
else:
|
||||||
result = initPartial
|
result = initPartial
|
||||||
|
|
@ -239,20 +239,17 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
||||||
result = if e != nil: initFull else: initNone
|
result = if e != nil: initFull else: initNone
|
||||||
|
|
||||||
else:
|
else:
|
||||||
internalAssert false
|
internalAssert c.config, false
|
||||||
|
|
||||||
proc semConstructType(c: PContext, initExpr: PNode,
|
proc semConstructType(c: PContext, initExpr: PNode,
|
||||||
t: PType, flags: TExprFlags): InitStatus =
|
t: PType, flags: TExprFlags): InitStatus =
|
||||||
var t = t
|
var t = t
|
||||||
result = initUnknown
|
result = initUnknown
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
let status = semConstructFields(c, t.n, initExpr, flags)
|
let status = semConstructFields(c, t.n, initExpr, flags)
|
||||||
mergeInitStatus(result, status)
|
mergeInitStatus(result, status)
|
||||||
|
|
||||||
if status in {initPartial, initNone, initUnknown}:
|
if status in {initPartial, initNone, initUnknown}:
|
||||||
checkForMissingFields t.n, initExpr
|
checkForMissingFields c, t.n, initExpr
|
||||||
|
|
||||||
let base = t.sons[0]
|
let base = t.sons[0]
|
||||||
if base == nil: break
|
if base == nil: break
|
||||||
t = skipTypes(base, skipPtrs)
|
t = skipTypes(base, skipPtrs)
|
||||||
|
|
@ -296,17 +293,16 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
let field = result[i]
|
let field = result[i]
|
||||||
if nfSem notin field.flags:
|
if nfSem notin field.flags:
|
||||||
if field.kind != nkExprColonExpr:
|
if field.kind != nkExprColonExpr:
|
||||||
invalidObjConstr(field)
|
invalidObjConstr(c, field)
|
||||||
continue
|
continue
|
||||||
let id = considerQuotedIdent(field[0])
|
let id = considerQuotedIdent(c.config, field[0])
|
||||||
# This node was not processed. There are two possible reasons:
|
# This node was not processed. There are two possible reasons:
|
||||||
# 1) It was shadowed by a field with the same name on the left
|
# 1) It was shadowed by a field with the same name on the left
|
||||||
for j in 1 ..< i:
|
for j in 1 ..< i:
|
||||||
let prevId = considerQuotedIdent(result[j][0])
|
let prevId = considerQuotedIdent(c.config, result[j][0])
|
||||||
if prevId.id == id.id:
|
if prevId.id == id.id:
|
||||||
localError(c.config, field.info, errFieldInitTwice, id.s)
|
localError(c.config, field.info, errFieldInitTwice % id.s)
|
||||||
return
|
return
|
||||||
# 2) No such field exists in the constructed type
|
# 2) No such field exists in the constructed type
|
||||||
localError(c.config, field.info, errUndeclaredFieldX, id.s)
|
localError(c.config, field.info, errUndeclaredFieldX % id.s)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -338,10 +338,10 @@ proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode =
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
result.typ = typ
|
result.typ = typ
|
||||||
else:
|
else:
|
||||||
changeType(r1, typ, check=true)
|
changeType(c, r1, typ, check=true)
|
||||||
result = r1
|
result = r1
|
||||||
elif not sameType(result.typ, typ):
|
elif not sameType(result.typ, typ):
|
||||||
changeType(result, typ, check=false)
|
changeType(c, result, typ, check=false)
|
||||||
|
|
||||||
proc findShadowedVar(c: PContext, v: PSym): PSym =
|
proc findShadowedVar(c: PContext, v: PSym): PSym =
|
||||||
for scope in walkScopes(c.currentScope.parent):
|
for scope in walkScopes(c.currentScope.parent):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue