mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-20 06:20:38 +00:00
big refactoring: magicsys compiles again
This commit is contained in:
@@ -27,7 +27,7 @@ type
|
||||
emit, conc, toStr: string
|
||||
curly, bracket, par: int
|
||||
pendingExprLine: bool
|
||||
|
||||
config: ConfigRef
|
||||
|
||||
const
|
||||
PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '.', '_'}
|
||||
@@ -90,7 +90,7 @@ proc parseLine(p: var TTmplParser) =
|
||||
dec(p.indent, 2)
|
||||
else:
|
||||
p.info.col = int16(j)
|
||||
localError(p.info, errXNotAllowedHere, "end")
|
||||
localError(p.config, p.info, "'end' does not close a control flow construct")
|
||||
llStreamWrite(p.outp, spaces(p.indent))
|
||||
llStreamWrite(p.outp, "#end")
|
||||
of "if", "when", "try", "while", "for", "block", "case", "proc", "iterator",
|
||||
@@ -175,7 +175,7 @@ proc parseLine(p: var TTmplParser) =
|
||||
llStreamWrite(p.outp, p.x[j])
|
||||
inc(j)
|
||||
if curly > 0:
|
||||
localError(p.info, errXExpected, "}")
|
||||
localError(p.config, p.info, "expected closing '}'")
|
||||
break
|
||||
llStreamWrite(p.outp, ')')
|
||||
llStreamWrite(p.outp, p.conc)
|
||||
@@ -197,22 +197,23 @@ proc parseLine(p: var TTmplParser) =
|
||||
inc(j)
|
||||
else:
|
||||
p.info.col = int16(j)
|
||||
localError(p.info, errInvalidExpression, "$")
|
||||
localError(p.config, p.info, "invalid expression")
|
||||
else:
|
||||
llStreamWrite(p.outp, p.x[j])
|
||||
inc(j)
|
||||
llStreamWrite(p.outp, "\\n\"")
|
||||
|
||||
proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode): PLLStream =
|
||||
proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode; conf: ConfigRef): PLLStream =
|
||||
var p: TTmplParser
|
||||
p.info = newLineInfo(filename, 0, 0)
|
||||
p.config = conf
|
||||
p.info = newLineInfo(conf, filename, 0, 0)
|
||||
p.outp = llStreamOpen("")
|
||||
p.inp = stdin
|
||||
p.subsChar = charArg(call, "subschar", 1, '$')
|
||||
p.nimDirective = charArg(call, "metachar", 2, '#')
|
||||
p.emit = strArg(call, "emit", 3, "result.add")
|
||||
p.conc = strArg(call, "conc", 4, " & ")
|
||||
p.toStr = strArg(call, "tostring", 5, "$")
|
||||
p.subsChar = charArg(conf, call, "subschar", 1, '$')
|
||||
p.nimDirective = charArg(conf, call, "metachar", 2, '#')
|
||||
p.emit = strArg(conf, call, "emit", 3, "result.add")
|
||||
p.conc = strArg(conf, call, "conc", 4, " & ")
|
||||
p.toStr = strArg(conf, call, "tostring", 5, "$")
|
||||
p.x = newStringOfCap(120)
|
||||
# do not process the first line which contains the directive:
|
||||
if llStreamReadLine(p.inp, p.x):
|
||||
|
||||
@@ -13,43 +13,44 @@ import
|
||||
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
|
||||
renderer
|
||||
|
||||
proc invalidPragma(n: PNode) =
|
||||
localError(n.info, errXNotAllowedHere, renderTree(n, {renderNoComments}))
|
||||
proc invalidPragma(conf: ConfigRef; n: PNode) =
|
||||
localError(conf, n.info,
|
||||
"'$1' not allowed here" % renderTree(n, {renderNoComments}))
|
||||
|
||||
proc getArg(n: PNode, name: string, pos: int): PNode =
|
||||
proc getArg(conf: ConfigRef; n: PNode, name: string, pos: int): PNode =
|
||||
result = nil
|
||||
if n.kind in {nkEmpty..nkNilLit}: return
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
if n.sons[i].kind == nkExprEqExpr:
|
||||
if n.sons[i].sons[0].kind != nkIdent: invalidPragma(n)
|
||||
if n.sons[i].sons[0].kind != nkIdent: invalidPragma(conf, n)
|
||||
if cmpIgnoreStyle(n.sons[i].sons[0].ident.s, name) == 0:
|
||||
return n.sons[i].sons[1]
|
||||
elif i == pos:
|
||||
return n.sons[i]
|
||||
|
||||
proc charArg*(n: PNode, name: string, pos: int, default: char): char =
|
||||
var x = getArg(n, name, pos)
|
||||
proc charArg*(conf: ConfigRef; n: PNode, name: string, pos: int, default: char): char =
|
||||
var x = getArg(conf, n, name, pos)
|
||||
if x == nil: result = default
|
||||
elif x.kind == nkCharLit: result = chr(int(x.intVal))
|
||||
else: invalidPragma(n)
|
||||
else: invalidPragma(conf, n)
|
||||
|
||||
proc strArg*(n: PNode, name: string, pos: int, default: string): string =
|
||||
var x = getArg(n, name, pos)
|
||||
proc strArg*(conf: ConfigRef; n: PNode, name: string, pos: int, default: string): string =
|
||||
var x = getArg(conf, n, name, pos)
|
||||
if x == nil: result = default
|
||||
elif x.kind in {nkStrLit..nkTripleStrLit}: result = x.strVal
|
||||
else: invalidPragma(n)
|
||||
else: invalidPragma(conf, n)
|
||||
|
||||
proc boolArg*(n: PNode, name: string, pos: int, default: bool): bool =
|
||||
var x = getArg(n, name, pos)
|
||||
proc boolArg*(conf: ConfigRef; n: PNode, name: string, pos: int, default: bool): bool =
|
||||
var x = getArg(conf, n, name, pos)
|
||||
if x == nil: result = default
|
||||
elif x.kind == nkIdent and cmpIgnoreStyle(x.ident.s, "true") == 0: result = true
|
||||
elif x.kind == nkIdent and cmpIgnoreStyle(x.ident.s, "false") == 0: result = false
|
||||
else: invalidPragma(n)
|
||||
else: invalidPragma(conf, n)
|
||||
|
||||
proc filterStrip*(stdin: PLLStream, filename: string, call: PNode): PLLStream =
|
||||
var pattern = strArg(call, "startswith", 1, "")
|
||||
var leading = boolArg(call, "leading", 2, true)
|
||||
var trailing = boolArg(call, "trailing", 3, true)
|
||||
proc filterStrip*(conf: ConfigRef; stdin: PLLStream, filename: string, call: PNode): PLLStream =
|
||||
var pattern = strArg(conf, call, "startswith", 1, "")
|
||||
var leading = boolArg(conf, call, "leading", 2, true)
|
||||
var trailing = boolArg(conf, call, "trailing", 3, true)
|
||||
result = llStreamOpen("")
|
||||
var line = newStringOfCap(80)
|
||||
while llStreamReadLine(stdin, line):
|
||||
@@ -60,10 +61,10 @@ proc filterStrip*(stdin: PLLStream, filename: string, call: PNode): PLLStream =
|
||||
llStreamWriteln(result, line)
|
||||
llStreamClose(stdin)
|
||||
|
||||
proc filterReplace*(stdin: PLLStream, filename: string, call: PNode): PLLStream =
|
||||
var sub = strArg(call, "sub", 1, "")
|
||||
if len(sub) == 0: invalidPragma(call)
|
||||
var by = strArg(call, "by", 2, "")
|
||||
proc filterReplace*(conf: ConfigRef; stdin: PLLStream, filename: string, call: PNode): PLLStream =
|
||||
var sub = strArg(conf, call, "sub", 1, "")
|
||||
if len(sub) == 0: invalidPragma(conf, call)
|
||||
var by = strArg(conf, call, "by", 2, "")
|
||||
result = llStreamOpen("")
|
||||
var line = newStringOfCap(80)
|
||||
while llStreamReadLine(stdin, line):
|
||||
|
||||
@@ -10,63 +10,59 @@
|
||||
# Built-in types and compilerprocs are registered here.
|
||||
|
||||
import
|
||||
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread
|
||||
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread,
|
||||
modulegraphs
|
||||
|
||||
var systemModule*: PSym
|
||||
proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt]
|
||||
|
||||
var
|
||||
gSysTypes: array[TTypeKind, PType]
|
||||
compilerprocs: TStrTable
|
||||
exposed: TStrTable
|
||||
proc registerSysType*(g: ModuleGraph; t: PType) =
|
||||
if g.sysTypes[t.kind] == nil: g.sysTypes[t.kind] = t
|
||||
|
||||
proc nilOrSysInt*: PType = gSysTypes[tyInt]
|
||||
|
||||
proc registerSysType*(t: PType) =
|
||||
if gSysTypes[t.kind] == nil: gSysTypes[t.kind] = t
|
||||
|
||||
proc newSysType(kind: TTypeKind, size: int): PType =
|
||||
result = newType(kind, systemModule)
|
||||
proc newSysType(g: ModuleGraph; kind: TTypeKind, size: int): PType =
|
||||
result = newType(kind, g.systemModule)
|
||||
result.size = size
|
||||
result.align = size.int16
|
||||
|
||||
proc getSysSym*(name: string): PSym =
|
||||
result = strTableGet(systemModule.tab, getIdent(name))
|
||||
proc getSysSym*(g: ModuleGraph; info: TLineInfo; name: string): PSym =
|
||||
result = strTableGet(g.systemModule.tab, getIdent(name))
|
||||
if result == nil:
|
||||
rawMessage(errSystemNeeds, name)
|
||||
result = newSym(skError, getIdent(name), systemModule, systemModule.info)
|
||||
result.typ = newType(tyError, systemModule)
|
||||
localError(g.config, info, "system module needs: " & name)
|
||||
result = newSym(skError, getIdent(name), g.systemModule, g.systemModule.info)
|
||||
result.typ = newType(tyError, g.systemModule)
|
||||
if result.kind == skStub: loadStub(result)
|
||||
if result.kind == skAlias: result = result.owner
|
||||
|
||||
proc createMagic*(name: string, m: TMagic): PSym =
|
||||
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
||||
result = newSym(skProc, getIdent(name), nil, unknownLineInfo())
|
||||
result.magic = m
|
||||
|
||||
let
|
||||
opNot* = createMagic("not", mNot)
|
||||
opContains* = createMagic("contains", mInSet)
|
||||
when false:
|
||||
let
|
||||
opNot* = createMagic("not", mNot)
|
||||
opContains* = createMagic("contains", mInSet)
|
||||
|
||||
proc getSysMagic*(name: string, m: TMagic): PSym =
|
||||
proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSym =
|
||||
var ti: TIdentIter
|
||||
let id = getIdent(name)
|
||||
var r = initIdentIter(ti, systemModule.tab, id)
|
||||
var r = initIdentIter(ti, g.systemModule.tab, id)
|
||||
while r != nil:
|
||||
if r.kind == skStub: loadStub(r)
|
||||
if r.magic == m:
|
||||
# prefer the tyInt variant:
|
||||
if r.typ.sons[0] != nil and r.typ.sons[0].kind == tyInt: return r
|
||||
result = r
|
||||
r = nextIdentIter(ti, systemModule.tab)
|
||||
r = nextIdentIter(ti, g.systemModule.tab)
|
||||
if result != nil: return result
|
||||
rawMessage(errSystemNeeds, name)
|
||||
result = newSym(skError, id, systemModule, systemModule.info)
|
||||
result.typ = newType(tyError, systemModule)
|
||||
localError(g.config, info, "system module needs: " & name)
|
||||
result = newSym(skError, id, g.systemModule, g.systemModule.info)
|
||||
result.typ = newType(tyError, g.systemModule)
|
||||
|
||||
proc sysTypeFromName*(name: string): PType =
|
||||
result = getSysSym(name).typ
|
||||
proc sysTypeFromName*(g: ModuleGraph; info: TLineInfo; name: string): PType =
|
||||
result = getSysSym(g, info, name).typ
|
||||
|
||||
proc getSysType*(kind: TTypeKind): PType =
|
||||
result = gSysTypes[kind]
|
||||
proc getSysType*(g: ModuleGraph; info: TLineInfo; kind: TTypeKind): PType =
|
||||
template sysTypeFromName(s: string): untyped = sysTypeFromName(g, info, s)
|
||||
result = g.sysTypes[kind]
|
||||
if result == nil:
|
||||
case kind
|
||||
of tyInt: result = sysTypeFromName("int")
|
||||
@@ -88,51 +84,49 @@ proc getSysType*(kind: TTypeKind): PType =
|
||||
of tyString: result = sysTypeFromName("string")
|
||||
of tyCString: result = sysTypeFromName("cstring")
|
||||
of tyPointer: result = sysTypeFromName("pointer")
|
||||
of tyNil: result = newSysType(tyNil, ptrSize)
|
||||
else: internalError("request for typekind: " & $kind)
|
||||
gSysTypes[kind] = result
|
||||
of tyNil: result = newSysType(g, tyNil, ptrSize)
|
||||
else: internalError(g.config, "request for typekind: " & $kind)
|
||||
g.sysTypes[kind] = result
|
||||
if result.kind != kind:
|
||||
internalError("wanted: " & $kind & " got: " & $result.kind)
|
||||
if result == nil: internalError("type not found: " & $kind)
|
||||
internalError(g.config, "wanted: " & $kind & " got: " & $result.kind)
|
||||
if result == nil: internalError(g.config, "type not found: " & $kind)
|
||||
|
||||
var
|
||||
intTypeCache: array[-5..64, PType]
|
||||
proc resetSysTypes*(g: ModuleGraph) =
|
||||
g.systemModule = nil
|
||||
initStrTable(g.compilerprocs)
|
||||
initStrTable(g.exposed)
|
||||
for i in low(g.sysTypes)..high(g.sysTypes):
|
||||
g.sysTypes[i] = nil
|
||||
|
||||
proc resetSysTypes* =
|
||||
systemModule = nil
|
||||
initStrTable(compilerprocs)
|
||||
initStrTable(exposed)
|
||||
for i in low(gSysTypes)..high(gSysTypes):
|
||||
gSysTypes[i] = nil
|
||||
for i in low(g.intTypeCache)..high(g.intTypeCache):
|
||||
g.intTypeCache[i] = nil
|
||||
|
||||
for i in low(intTypeCache)..high(intTypeCache):
|
||||
intTypeCache[i] = nil
|
||||
|
||||
proc getIntLitType*(literal: PNode): PType =
|
||||
proc getIntLitType*(g: ModuleGraph; literal: PNode): PType =
|
||||
# we cache some common integer literal types for performance:
|
||||
let value = literal.intVal
|
||||
if value >= low(intTypeCache) and value <= high(intTypeCache):
|
||||
result = intTypeCache[value.int]
|
||||
if value >= low(g.intTypeCache) and value <= high(g.intTypeCache):
|
||||
result = g.intTypeCache[value.int]
|
||||
if result == nil:
|
||||
let ti = getSysType(tyInt)
|
||||
let ti = getSysType(g, literal.info, tyInt)
|
||||
result = copyType(ti, ti.owner, false)
|
||||
result.n = literal
|
||||
intTypeCache[value.int] = result
|
||||
g.intTypeCache[value.int] = result
|
||||
else:
|
||||
let ti = getSysType(tyInt)
|
||||
let ti = getSysType(g, literal.info, tyInt)
|
||||
result = copyType(ti, ti.owner, false)
|
||||
result.n = literal
|
||||
|
||||
proc getFloatLitType*(literal: PNode): PType =
|
||||
proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
|
||||
# for now we do not cache these:
|
||||
result = newSysType(tyFloat, size=8)
|
||||
result = newSysType(g, tyFloat, size=8)
|
||||
result.n = literal
|
||||
|
||||
proc skipIntLit*(t: PType): PType {.inline.} =
|
||||
if t.n != nil:
|
||||
if t.kind in {tyInt, tyFloat}:
|
||||
return getSysType(t.kind)
|
||||
result = t
|
||||
if t.n != nil and t.kind in {tyInt, tyFloat}:
|
||||
result = copyType(t, t.owner, false)
|
||||
result.n = nil
|
||||
else:
|
||||
result = t
|
||||
|
||||
proc addSonSkipIntLit*(father, son: PType) =
|
||||
if isNil(father.sons): father.sons = @[]
|
||||
@@ -140,60 +134,59 @@ proc addSonSkipIntLit*(father, son: PType) =
|
||||
add(father.sons, s)
|
||||
propagateToOwner(father, s)
|
||||
|
||||
proc setIntLitType*(result: PNode) =
|
||||
proc setIntLitType*(g: ModuleGraph; result: PNode) =
|
||||
let i = result.intVal
|
||||
case platform.intSize
|
||||
of 8: result.typ = getIntLitType(result)
|
||||
of 8: result.typ = getIntLitType(g, result)
|
||||
of 4:
|
||||
if i >= low(int32) and i <= high(int32):
|
||||
result.typ = getIntLitType(result)
|
||||
result.typ = getIntLitType(g, result)
|
||||
else:
|
||||
result.typ = getSysType(tyInt64)
|
||||
result.typ = getSysType(g, result.info, tyInt64)
|
||||
of 2:
|
||||
if i >= low(int16) and i <= high(int16):
|
||||
result.typ = getIntLitType(result)
|
||||
result.typ = getIntLitType(g, result)
|
||||
elif i >= low(int32) and i <= high(int32):
|
||||
result.typ = getSysType(tyInt32)
|
||||
result.typ = getSysType(g, result.info, tyInt32)
|
||||
else:
|
||||
result.typ = getSysType(tyInt64)
|
||||
result.typ = getSysType(g, result.info, tyInt64)
|
||||
of 1:
|
||||
# 8 bit CPUs are insane ...
|
||||
if i >= low(int8) and i <= high(int8):
|
||||
result.typ = getIntLitType(result)
|
||||
result.typ = getIntLitType(g, result)
|
||||
elif i >= low(int16) and i <= high(int16):
|
||||
result.typ = getSysType(tyInt16)
|
||||
result.typ = getSysType(g, result.info, tyInt16)
|
||||
elif i >= low(int32) and i <= high(int32):
|
||||
result.typ = getSysType(tyInt32)
|
||||
result.typ = getSysType(g, result.info, tyInt32)
|
||||
else:
|
||||
result.typ = getSysType(tyInt64)
|
||||
else: internalError(result.info, "invalid int size")
|
||||
|
||||
proc getCompilerProc*(name: string): PSym =
|
||||
let ident = getIdent(name)
|
||||
result = strTableGet(compilerprocs, ident)
|
||||
if result == nil:
|
||||
result = strTableGet(rodCompilerprocs, ident)
|
||||
if result != nil:
|
||||
strTableAdd(compilerprocs, result)
|
||||
if result.kind == skStub: loadStub(result)
|
||||
if result.kind == skAlias: result = result.owner
|
||||
|
||||
proc registerCompilerProc*(s: PSym) =
|
||||
strTableAdd(compilerprocs, s)
|
||||
|
||||
proc registerNimScriptSymbol*(s: PSym) =
|
||||
# Nimscript symbols must be al unique:
|
||||
let conflict = strTableGet(exposed, s.name)
|
||||
if conflict == nil:
|
||||
strTableAdd(exposed, s)
|
||||
result.typ = getSysType(g, result.info, tyInt64)
|
||||
else:
|
||||
localError(s.info, "symbol conflicts with other .exportNims symbol at: " &
|
||||
$conflict.info)
|
||||
internalError(g.config, result.info, "invalid int size")
|
||||
|
||||
proc getNimScriptSymbol*(name: string): PSym =
|
||||
strTableGet(exposed, getIdent(name))
|
||||
proc getCompilerProc*(g: ModuleGraph; name: string): PSym =
|
||||
let ident = getIdent(name)
|
||||
result = strTableGet(g.compilerprocs, ident)
|
||||
when false:
|
||||
if result == nil:
|
||||
result = strTableGet(g.rodCompilerprocs, ident)
|
||||
if result != nil:
|
||||
strTableAdd(g.compilerprocs, result)
|
||||
if result.kind == skStub: loadStub(result)
|
||||
if result.kind == skAlias: result = result.owner
|
||||
|
||||
proc resetNimScriptSymbols*() = initStrTable(exposed)
|
||||
proc registerCompilerProc*(g: ModuleGraph; s: PSym) =
|
||||
strTableAdd(g.compilerprocs, s)
|
||||
|
||||
initStrTable(compilerprocs)
|
||||
initStrTable(exposed)
|
||||
proc registerNimScriptSymbol*(g: ModuleGraph; s: PSym) =
|
||||
# Nimscript symbols must be al unique:
|
||||
let conflict = strTableGet(g.exposed, s.name)
|
||||
if conflict == nil:
|
||||
strTableAdd(g.exposed, s)
|
||||
else:
|
||||
localError(g.config, s.info,
|
||||
"symbol conflicts with other .exportNims symbol at: " & $conflict.info)
|
||||
|
||||
proc getNimScriptSymbol*(g: ModuleGraph; name: string): PSym =
|
||||
strTableGet(g.exposed, getIdent(name))
|
||||
|
||||
proc resetNimScriptSymbols*(g: ModuleGraph) = initStrTable(g.exposed)
|
||||
|
||||
@@ -44,6 +44,11 @@ type
|
||||
usageSym*: PSym # for nimsuggest
|
||||
owners*: seq[PSym]
|
||||
methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]]
|
||||
systemModule*: PSym
|
||||
sysTypes*: array[TTypeKind, PType]
|
||||
compilerprocs*: TStrTable
|
||||
exposed*: TStrTable
|
||||
intTypeCache*: array[-5..64, PType]
|
||||
|
||||
proc hash*(x: FileIndex): Hash {.borrow.}
|
||||
|
||||
@@ -65,6 +70,8 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
|
||||
result.config = config
|
||||
result.owners = @[]
|
||||
result.methods = @[]
|
||||
initStrTable(result.compilerprocs)
|
||||
initStrTable(result.exposed)
|
||||
|
||||
proc resetAllModules*(g: ModuleGraph) =
|
||||
initStrTable(packageSyms)
|
||||
@@ -75,6 +82,8 @@ proc resetAllModules*(g: ModuleGraph) =
|
||||
usageSym = nil
|
||||
owners = @[]
|
||||
methods = @[]
|
||||
initStrTable(compilerprocs)
|
||||
initStrTable(exposed)
|
||||
|
||||
proc getModule*(g: ModuleGraph; fileIdx: FileIndex): PSym =
|
||||
if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len:
|
||||
|
||||
@@ -629,9 +629,9 @@ proc quotedFilename*(i: TLineInfo): Rope =
|
||||
ropes.errorHandler = proc (err: RopesError, msg: string, useWarning: bool) =
|
||||
case err
|
||||
of rInvalidFormatStr:
|
||||
internalError(newConfigRef(), "ropes: invalid format string: " & msg)
|
||||
internalError(newPartialConfigRef(), "ropes: invalid format string: " & msg)
|
||||
of rCannotOpenFile:
|
||||
rawMessage(newConfigRef(), if useWarning: warnCannotOpenFile else: errCannotOpenFile, msg)
|
||||
rawMessage(newPartialConfigRef(), if useWarning: warnCannotOpenFile else: errCannotOpenFile, msg)
|
||||
|
||||
proc listWarnings*(conf: ConfigRef) =
|
||||
msgWriteln("Warnings:")
|
||||
|
||||
@@ -141,6 +141,12 @@ proc newConfigRef*(): ConfigRef =
|
||||
notes: NotesVerbosity[1], mainPackageNotes: NotesVerbosity[1],
|
||||
symbols: newStringTable(modeStyleInsensitive))
|
||||
|
||||
proc newPartialConfigRef*(): ConfigRef =
|
||||
## create a new ConfigRef that is only good enough for error reporting.
|
||||
result = ConfigRef(foreignPackageNotes: {hintProcessing, warnUnknownMagic,
|
||||
hintQuitCalled, hintExecuting},
|
||||
notes: NotesVerbosity[1], mainPackageNotes: NotesVerbosity[1])
|
||||
|
||||
proc cppDefine*(c: ConfigRef; define: string) =
|
||||
c.cppDefines.incl define
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# This module implements the renderer of the standard Nim representation.
|
||||
|
||||
import
|
||||
lexer, options, idents, strutils, ast, msgs
|
||||
lexer, options, idents, strutils, ast, msgs, configuration
|
||||
|
||||
type
|
||||
TRenderFlag* = enum
|
||||
@@ -40,6 +40,7 @@ type
|
||||
when defined(nimpretty):
|
||||
pendingNewlineCount: int
|
||||
fid*: FileIndex
|
||||
config*: ConfigRef
|
||||
|
||||
# We render the source code in a two phases: The first
|
||||
# determines how long the subtree will likely be, the second
|
||||
@@ -90,7 +91,7 @@ const
|
||||
MaxLineLen = 80
|
||||
LineCommentColumn = 30
|
||||
|
||||
proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) =
|
||||
proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags; config: ConfigRef) =
|
||||
g.comStack = @[]
|
||||
g.tokens = @[]
|
||||
g.indent = 0
|
||||
@@ -102,6 +103,7 @@ proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) =
|
||||
g.pendingNL = -1
|
||||
g.pendingWhitespace = -1
|
||||
g.inGenericParams = false
|
||||
g.config = config
|
||||
|
||||
proc addTok(g: var TSrcGen, kind: TTokType, s: string) =
|
||||
var length = len(g.tokens)
|
||||
@@ -377,7 +379,7 @@ proc atom(g: TSrcGen; n: PNode): string =
|
||||
if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s
|
||||
else: result = "[type node]"
|
||||
else:
|
||||
internalError("rnimsyn.atom " & $n.kind)
|
||||
internalError(g.config, "rnimsyn.atom " & $n.kind)
|
||||
result = ""
|
||||
|
||||
proc lcomma(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int =
|
||||
@@ -1422,11 +1424,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||
gTypeClassTy(g, n)
|
||||
else:
|
||||
#nkNone, nkExplicitTypeListCall:
|
||||
internalError(n.info, "rnimsyn.gsub(" & $n.kind & ')')
|
||||
internalError(g.config, n.info, "rnimsyn.gsub(" & $n.kind & ')')
|
||||
|
||||
proc renderTree*(n: PNode, renderFlags: TRenderFlags = {}): string =
|
||||
var g: TSrcGen
|
||||
initSrcGen(g, renderFlags)
|
||||
initSrcGen(g, renderFlags, newPartialConfigRef())
|
||||
# do not indent the initial statement list so that
|
||||
# writeFile("file.nim", repr n)
|
||||
# produces working Nim code:
|
||||
@@ -1444,7 +1446,7 @@ proc renderModule*(n: PNode, infile, outfile: string,
|
||||
var
|
||||
f: File
|
||||
g: TSrcGen
|
||||
initSrcGen(g, renderFlags)
|
||||
initSrcGen(g, renderFlags, newPartialConfigRef())
|
||||
g.fid = fid
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
gsub(g, n.sons[i])
|
||||
@@ -1460,10 +1462,10 @@ proc renderModule*(n: PNode, infile, outfile: string,
|
||||
write(f, g.buf)
|
||||
close(f)
|
||||
else:
|
||||
rawMessage(errCannotOpenFile, outfile)
|
||||
rawMessage(g.config, errGenerated, "cannot open file: " & outfile)
|
||||
|
||||
proc initTokRender*(r: var TSrcGen, n: PNode, renderFlags: TRenderFlags = {}) =
|
||||
initSrcGen(r, renderFlags)
|
||||
initSrcGen(r, renderFlags, newPartialConfigRef())
|
||||
gsub(r, n)
|
||||
|
||||
proc getNextTok*(r: var TSrcGen, kind: var TTokType, literal: var string) =
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
|
||||
import
|
||||
os, options, strutils, nversion, ast, astalgo, msgs, platform, condsyms,
|
||||
ropes, idents, std / sha1, idgen, types, rodutils, memfiles, tables
|
||||
ropes, idents, std / sha1, idgen, types, rodutils, memfiles, tables,
|
||||
configuration
|
||||
|
||||
type
|
||||
TReasonForRecompile* = enum ## all the reasons that can trigger recompilation
|
||||
@@ -143,6 +144,7 @@ type
|
||||
origFile: string
|
||||
inViewMode: bool
|
||||
cache*: IdentCache
|
||||
config: ConfigRef
|
||||
|
||||
PRodReader* = ref TRodReader
|
||||
|
||||
@@ -222,14 +224,14 @@ proc decodeNodeLazyBody(r: PRodReader, fInfo: TLineInfo,
|
||||
var fl = decodeStr(r.s, r.pos)
|
||||
result.ident = r.cache.getIdent(fl)
|
||||
else:
|
||||
internalError(result.info, "decodeNode: nkIdent")
|
||||
internalError(r.config, result.info, "decodeNode: nkIdent")
|
||||
of nkSym:
|
||||
if r.s[r.pos] == '!':
|
||||
inc(r.pos)
|
||||
var id = decodeVInt(r.s, r.pos)
|
||||
result.sym = rrGetSym(r, id, result.info)
|
||||
else:
|
||||
internalError(result.info, "decodeNode: nkSym")
|
||||
internalError(r.config, result.info, "decodeNode: nkSym")
|
||||
else:
|
||||
var i = 0
|
||||
while r.s[r.pos] != ')':
|
||||
@@ -241,9 +243,9 @@ proc decodeNodeLazyBody(r: PRodReader, fInfo: TLineInfo,
|
||||
addSonNilAllowed(result, decodeNodeLazyBody(r, result.info, nil))
|
||||
inc i
|
||||
if r.s[r.pos] == ')': inc(r.pos)
|
||||
else: internalError(result.info, "decodeNode: ')' missing")
|
||||
else: internalError(r.config, result.info, "decodeNode: ')' missing")
|
||||
else:
|
||||
internalError(fInfo, "decodeNode: '(' missing " & $r.pos)
|
||||
internalError(r.config, fInfo, "decodeNode: '(' missing " & $r.pos)
|
||||
|
||||
proc decodeNode(r: PRodReader, fInfo: TLineInfo): PNode =
|
||||
result = decodeNodeLazyBody(r, fInfo, nil)
|
||||
@@ -277,7 +279,7 @@ proc decodeLoc(r: PRodReader, loc: var TLoc, info: TLineInfo) =
|
||||
else:
|
||||
loc.r = nil
|
||||
if r.s[r.pos] == '>': inc(r.pos)
|
||||
else: internalError(info, "decodeLoc " & r.s[r.pos])
|
||||
else: internalError(r.config, info, "decodeLoc " & r.s[r.pos])
|
||||
|
||||
proc decodeType(r: PRodReader, info: TLineInfo): PType =
|
||||
result = nil
|
||||
@@ -294,7 +296,7 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
|
||||
setId(result.id)
|
||||
if debugIds: registerID(result)
|
||||
else:
|
||||
internalError(info, "decodeType: no id")
|
||||
internalError(r.config, info, "decodeType: no id")
|
||||
# here this also avoids endless recursion for recursive type
|
||||
idTablePut(gTypeTable, result, result)
|
||||
if r.s[r.pos] == '(': result.n = decodeNode(r, unknownLineInfo())
|
||||
@@ -345,14 +347,14 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
|
||||
doAssert r.s[r.pos] == '\20'
|
||||
inc(r.pos)
|
||||
let y = rrGetSym(r, decodeVInt(r.s, r.pos), info)
|
||||
result.methods.safeAdd((x, y))
|
||||
result.methods.add((x, y))
|
||||
decodeLoc(r, result.loc, info)
|
||||
while r.s[r.pos] == '^':
|
||||
inc(r.pos)
|
||||
if r.s[r.pos] == '(':
|
||||
inc(r.pos)
|
||||
if r.s[r.pos] == ')': inc(r.pos)
|
||||
else: internalError(info, "decodeType ^(" & r.s[r.pos])
|
||||
else: internalError(r.config, info, "decodeType ^(" & r.s[r.pos])
|
||||
rawAddSon(result, nil)
|
||||
else:
|
||||
var d = decodeVInt(r.s, r.pos)
|
||||
@@ -364,10 +366,10 @@ proc decodeLib(r: PRodReader, info: TLineInfo): PLib =
|
||||
new(result)
|
||||
inc(r.pos)
|
||||
result.kind = TLibKind(decodeVInt(r.s, r.pos))
|
||||
if r.s[r.pos] != '|': internalError("decodeLib: 1")
|
||||
if r.s[r.pos] != '|': internalError(r.config, "decodeLib: 1")
|
||||
inc(r.pos)
|
||||
result.name = rope(decodeStr(r.s, r.pos))
|
||||
if r.s[r.pos] != '|': internalError("decodeLib: 2")
|
||||
if r.s[r.pos] != '|': internalError(r.config, "decodeLib: 2")
|
||||
inc(r.pos)
|
||||
result.path = decodeNode(r, info)
|
||||
|
||||
@@ -385,7 +387,7 @@ proc decodeInstantiations(r: PRodReader; info: TLineInfo;
|
||||
if r.s[r.pos] == '\20':
|
||||
inc(r.pos)
|
||||
ii.compilesId = decodeVInt(r.s, r.pos)
|
||||
s.safeAdd ii
|
||||
s.add ii
|
||||
|
||||
proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
||||
var
|
||||
@@ -403,12 +405,12 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
||||
id = decodeVInt(r.s, r.pos)
|
||||
setId(id)
|
||||
else:
|
||||
internalError(info, "decodeSym: no id")
|
||||
internalError(r.config, info, "decodeSym: no id")
|
||||
if r.s[r.pos] == '&':
|
||||
inc(r.pos)
|
||||
ident = r.cache.getIdent(decodeStr(r.s, r.pos))
|
||||
else:
|
||||
internalError(info, "decodeSym: no ident")
|
||||
internalError(r.config, info, "decodeSym: no ident")
|
||||
#echo "decoding: {", ident.s
|
||||
result = r.syms.getOrDefault(id)
|
||||
if result == nil:
|
||||
@@ -417,7 +419,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
||||
r.syms[result.id] = result
|
||||
if debugIds: registerID(result)
|
||||
elif result.id != id:
|
||||
internalError(info, "decodeSym: wrong id")
|
||||
internalError(r.config, info, "decodeSym: wrong id")
|
||||
elif result.kind != skStub and not r.inViewMode:
|
||||
# we already loaded the symbol
|
||||
return
|
||||
@@ -465,7 +467,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
||||
of skType, skGenericParam:
|
||||
while r.s[r.pos] == '\14':
|
||||
inc(r.pos)
|
||||
result.typeInstCache.safeAdd rrGetType(r, decodeVInt(r.s, r.pos), result.info)
|
||||
result.typeInstCache.add rrGetType(r, decodeVInt(r.s, r.pos), result.info)
|
||||
of routineKinds:
|
||||
decodeInstantiations(r, result.info, result.procInstCache)
|
||||
if r.s[r.pos] == '\16':
|
||||
@@ -512,7 +514,7 @@ proc skipSection(r: PRodReader) =
|
||||
else: discard
|
||||
inc(r.pos)
|
||||
else:
|
||||
internalError("skipSection " & $r.line)
|
||||
internalError(r.config, "skipSection " & $r.line)
|
||||
|
||||
proc rdWord(r: PRodReader): string =
|
||||
result = ""
|
||||
@@ -530,7 +532,7 @@ proc newStub(r: PRodReader, name: string, id: int): PSym =
|
||||
if debugIds: registerID(result)
|
||||
|
||||
proc processInterf(r: PRodReader, module: PSym) =
|
||||
if r.interfIdx == 0: internalError("processInterf")
|
||||
if r.interfIdx == 0: internalError(r.config, "processInterf")
|
||||
r.pos = r.interfIdx
|
||||
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
|
||||
var w = decodeStr(r.s, r.pos)
|
||||
@@ -543,7 +545,7 @@ proc processInterf(r: PRodReader, module: PSym) =
|
||||
r.syms[s.id] = s
|
||||
|
||||
proc processCompilerProcs(r: PRodReader, module: PSym) =
|
||||
if r.compilerProcsIdx == 0: internalError("processCompilerProcs")
|
||||
if r.compilerProcsIdx == 0: internalError(r.config, "processCompilerProcs")
|
||||
r.pos = r.compilerProcsIdx
|
||||
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
|
||||
var w = decodeStr(r.s, r.pos)
|
||||
@@ -637,10 +639,10 @@ proc processRodFile(r: PRodReader, hash: SecureHash) =
|
||||
while r.s[r.pos] > '\x0A':
|
||||
w = decodeStr(r.s, r.pos)
|
||||
inc(d)
|
||||
if not condsyms.isDefined(r.cache.getIdent(w)):
|
||||
if not isDefined(r.config, w):
|
||||
r.reason = rrDefines #MessageOut('not defined, but should: ' + w);
|
||||
if r.s[r.pos] == ' ': inc(r.pos)
|
||||
if d != countDefinedSymbols(): r.reason = rrDefines
|
||||
if d != countDefinedSymbols(r.config.symbols): r.reason = rrDefines
|
||||
of "FILES":
|
||||
inc(r.pos, 2) # skip "(\10"
|
||||
inc(r.line)
|
||||
@@ -648,7 +650,7 @@ proc processRodFile(r: PRodReader, hash: SecureHash) =
|
||||
let finalPath = decodeStr(r.s, r.pos)
|
||||
#let resolvedPath = relativePath.findModule(r.origFile)
|
||||
#let finalPath = if resolvedPath.len > 0: resolvedPath else: relativePath
|
||||
r.files.add(finalPath.fileInfoIdx)
|
||||
r.files.add(fileInfoIdx(r.config, finalPath))
|
||||
inc(r.pos) # skip #10
|
||||
inc(r.line)
|
||||
if r.s[r.pos] == ')': inc(r.pos)
|
||||
@@ -696,7 +698,7 @@ proc processRodFile(r: PRodReader, hash: SecureHash) =
|
||||
r.initIdx = r.pos + 2 # "(\10"
|
||||
skipSection(r)
|
||||
else:
|
||||
internalError("invalid section: '" & section &
|
||||
internalError(r.config, "invalid section: '" & section &
|
||||
"' at " & $r.line & " in " & r.filename)
|
||||
#MsgWriteln("skipping section: " & section &
|
||||
# " at " & $r.line & " in " & r.filename)
|
||||
@@ -712,9 +714,11 @@ proc startsWith(buf: cstring, token: string, pos = 0): bool =
|
||||
result = s == token.len
|
||||
|
||||
proc newRodReader(modfilename: string, hash: SecureHash,
|
||||
readerIndex: int; cache: IdentCache): PRodReader =
|
||||
readerIndex: int; cache: IdentCache;
|
||||
config: ConfigRef): PRodReader =
|
||||
new(result)
|
||||
result.cache = cache
|
||||
result.config = config
|
||||
try:
|
||||
result.memfile = memfiles.open(modfilename)
|
||||
except OSError:
|
||||
@@ -757,13 +761,13 @@ proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType =
|
||||
# load the type:
|
||||
var oldPos = r.pos
|
||||
var d = iiTableGet(r.index.tab, id)
|
||||
if d == InvalidKey: internalError(info, "rrGetType")
|
||||
if d == InvalidKey: internalError(r.config, info, "rrGetType")
|
||||
r.pos = d + r.dataIdx
|
||||
result = decodeType(r, info)
|
||||
r.pos = oldPos
|
||||
|
||||
type
|
||||
TFileModuleRec{.final.} = object
|
||||
TFileModuleRec = object
|
||||
filename*: string
|
||||
reason*: TReasonForRecompile
|
||||
rd*: PRodReader
|
||||
@@ -776,7 +780,7 @@ var gMods*: TFileModuleMap = @[]
|
||||
|
||||
proc decodeSymSafePos(rd: PRodReader, offset: int, info: TLineInfo): PSym =
|
||||
# all compiled modules
|
||||
if rd.dataIdx == 0: internalError(info, "dataIdx == 0")
|
||||
if rd.dataIdx == 0: internalError(rd.config, info, "dataIdx == 0")
|
||||
var oldPos = rd.pos
|
||||
rd.pos = offset + rd.dataIdx
|
||||
result = decodeSym(rd, info)
|
||||
@@ -811,7 +815,7 @@ proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym =
|
||||
if moduleID < 0:
|
||||
var x = ""
|
||||
encodeVInt(id, x)
|
||||
internalError(info, "missing from both indexes: +" & x)
|
||||
internalError(r.config, info, "missing from both indexes: +" & x)
|
||||
var rd = getReader(moduleID)
|
||||
doAssert rd != nil
|
||||
d = iiTableGet(rd.index.tab, id)
|
||||
@@ -821,14 +825,14 @@ proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym =
|
||||
var x = ""
|
||||
encodeVInt(id, x)
|
||||
when false: findSomeWhere(id)
|
||||
internalError(info, "rrGetSym: no reader found: +" & x)
|
||||
internalError(r.config, info, "rrGetSym: no reader found: +" & x)
|
||||
else:
|
||||
# own symbol:
|
||||
result = decodeSymSafePos(r, d, info)
|
||||
if result != nil and result.kind == skStub: rawLoadStub(result)
|
||||
|
||||
proc loadInitSection*(r: PRodReader): PNode =
|
||||
if r.initIdx == 0 or r.dataIdx == 0: internalError("loadInitSection")
|
||||
if r.initIdx == 0 or r.dataIdx == 0: internalError(r.config, "loadInitSection")
|
||||
var oldPos = r.pos
|
||||
r.pos = r.initIdx
|
||||
result = newNode(nkStmtList)
|
||||
@@ -845,7 +849,7 @@ proc loadConverters(r: PRodReader) =
|
||||
# We have to ensure that no exported converter is a stub anymore, and the
|
||||
# import mechanism takes care of the rest.
|
||||
if r.convertersIdx == 0 or r.dataIdx == 0:
|
||||
internalError("importConverters")
|
||||
internalError(r.config, "importConverters")
|
||||
r.pos = r.convertersIdx
|
||||
while r.s[r.pos] > '\x0A':
|
||||
var d = decodeVInt(r.s, r.pos)
|
||||
@@ -854,7 +858,7 @@ proc loadConverters(r: PRodReader) =
|
||||
|
||||
proc loadMethods(r: PRodReader) =
|
||||
if r.methodsIdx == 0 or r.dataIdx == 0:
|
||||
internalError("loadMethods")
|
||||
internalError(r.config, "loadMethods")
|
||||
r.pos = r.methodsIdx
|
||||
while r.s[r.pos] > '\x0A':
|
||||
var d = decodeVInt(r.s, r.pos)
|
||||
@@ -872,7 +876,7 @@ proc getHash*(fileIdx: FileIndex): SecureHash =
|
||||
template growCache*(cache, pos) =
|
||||
if cache.len <= pos: cache.setLen(pos+1)
|
||||
|
||||
proc checkDep(fileIdx: FileIndex; cache: IdentCache): TReasonForRecompile =
|
||||
proc checkDep(fileIdx: FileIndex; cache: IdentCache; conf: ConfigRef): TReasonForRecompile =
|
||||
assert fileIdx != InvalidFileIDX
|
||||
growCache gMods, fileIdx.int32
|
||||
if gMods[fileIdx.int32].reason != rrEmpty:
|
||||
@@ -882,8 +886,8 @@ proc checkDep(fileIdx: FileIndex; cache: IdentCache): TReasonForRecompile =
|
||||
var hash = getHash(fileIdx)
|
||||
gMods[fileIdx.int32].reason = rrNone # we need to set it here to avoid cycles
|
||||
result = rrNone
|
||||
var rodfile = toGeneratedFile(filename.withPackageName, RodExt)
|
||||
var r = newRodReader(rodfile, hash, fileIdx.int32, cache)
|
||||
var rodfile = toGeneratedFile(conf, filename.withPackageName, RodExt)
|
||||
var r = newRodReader(rodfile, hash, fileIdx.int32, cache, conf)
|
||||
if r == nil:
|
||||
result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
|
||||
else:
|
||||
@@ -894,15 +898,15 @@ proc checkDep(fileIdx: FileIndex; cache: IdentCache): TReasonForRecompile =
|
||||
# NOTE: we need to process the entire module graph so that no ID will
|
||||
# be used twice! However, compilation speed does not suffer much from
|
||||
# this, since results are cached.
|
||||
var res = checkDep(systemFileIdx, cache)
|
||||
var res = checkDep(systemFileIdx, cache, conf)
|
||||
if res != rrNone: result = rrModDeps
|
||||
for i in countup(0, high(r.modDeps)):
|
||||
res = checkDep(r.modDeps[i], cache)
|
||||
res = checkDep(r.modDeps[i], cache, conf)
|
||||
if res != rrNone:
|
||||
result = rrModDeps
|
||||
# we cannot break here, because of side-effects of `checkDep`
|
||||
if result != rrNone:
|
||||
rawMessage(hintProcessing, reasonToFrmt[result] % filename)
|
||||
rawMessage(conf, hintProcessing, reasonToFrmt[result] % filename)
|
||||
if result != rrNone or optForceFullMake in gGlobalOptions:
|
||||
# recompilation is necessary:
|
||||
if r != nil: memfiles.close(r.memfile)
|
||||
@@ -910,14 +914,14 @@ proc checkDep(fileIdx: FileIndex; cache: IdentCache): TReasonForRecompile =
|
||||
gMods[fileIdx.int32].rd = r
|
||||
gMods[fileIdx.int32].reason = result # now we know better
|
||||
|
||||
proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader =
|
||||
proc handleSymbolFile*(module: PSym; cache: IdentCache; conf: ConfigRef): PRodReader =
|
||||
if gSymbolFiles in {disabledSf, writeOnlySf, v2Sf}:
|
||||
module.id = getID()
|
||||
return nil
|
||||
idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
|
||||
idgen.loadMaxIds(conf, options.gProjectPath / options.gProjectName)
|
||||
let fileIdx = module.fileIdx
|
||||
discard checkDep(fileIdx, cache)
|
||||
if gMods[fileIdx.int32].reason == rrEmpty: internalError("handleSymbolFile")
|
||||
discard checkDep(fileIdx, cache, conf)
|
||||
#if gMods[fileIdx.int32].reason == rrEmpty: internalError("handleSymbolFile")
|
||||
result = gMods[fileIdx.int32].rd
|
||||
if result != nil:
|
||||
module.id = result.moduleID
|
||||
@@ -930,19 +934,20 @@ proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader =
|
||||
module.id = getID()
|
||||
|
||||
proc rawLoadStub(s: PSym) =
|
||||
if s.kind != skStub: internalError("loadStub")
|
||||
assert s.kind == skStub
|
||||
#if s.kind != skStub: internalError("loadStub")
|
||||
var rd = gMods[s.position].rd
|
||||
var theId = s.id # used for later check
|
||||
var d = iiTableGet(rd.index.tab, s.id)
|
||||
if d == InvalidKey: internalError("loadStub: invalid key")
|
||||
#if d == InvalidKey: internalError("loadStub: invalid key")
|
||||
var rs = decodeSymSafePos(rd, d, unknownLineInfo())
|
||||
if rs != s:
|
||||
#echo "rs: ", toHex(cast[int](rs.position), int.sizeof * 2),
|
||||
# "\ns: ", toHex(cast[int](s.position), int.sizeof * 2)
|
||||
internalError(rs.info, "loadStub: wrong symbol")
|
||||
elif rs.id != theId:
|
||||
internalError(rs.info, "loadStub: wrong ID")
|
||||
#MessageOut('loaded stub: ' + s.name.s);
|
||||
when false:
|
||||
if rs != s:
|
||||
#echo "rs: ", toHex(cast[int](rs.position), int.sizeof * 2),
|
||||
# "\ns: ", toHex(cast[int](s.position), int.sizeof * 2)
|
||||
internalError(rs.info, "loadStub: wrong symbol")
|
||||
elif rs.id != theId:
|
||||
internalError(rs.info, "loadStub: wrong ID")
|
||||
|
||||
proc loadStub*(s: PSym) =
|
||||
## loads the stub symbol `s`.
|
||||
@@ -1083,9 +1088,10 @@ proc writeType(f: File; t: PType) =
|
||||
f.write("]\n")
|
||||
|
||||
proc viewFile(rodfile: string) =
|
||||
var r = newRodReader(rodfile, secureHash(""), 0, newIdentCache())
|
||||
let conf = newConfigRef()
|
||||
var r = newRodReader(rodfile, secureHash(""), 0, newIdentCache(), conf)
|
||||
if r == nil:
|
||||
rawMessage(errGenerated, "cannot open file (or maybe wrong version):" &
|
||||
rawMessage(conf, errGenerated, "cannot open file (or maybe wrong version):" &
|
||||
rodfile)
|
||||
return
|
||||
r.inViewMode = true
|
||||
@@ -1133,9 +1139,9 @@ proc viewFile(rodfile: string) =
|
||||
outf.write("FILES(\n")
|
||||
while r.s[r.pos] != ')':
|
||||
let relativePath = decodeStr(r.s, r.pos)
|
||||
let resolvedPath = relativePath.findModule(r.origFile)
|
||||
let resolvedPath = findModule(conf, relativePath, r.origFile)
|
||||
let finalPath = if resolvedPath.len > 0: resolvedPath else: relativePath
|
||||
r.files.add(finalPath.fileInfoIdx)
|
||||
r.files.add(fileInfoIdx(conf, finalPath))
|
||||
inc(r.pos) # skip #10
|
||||
inc(r.line)
|
||||
outf.writeLine finalPath
|
||||
@@ -1227,7 +1233,7 @@ proc viewFile(rodfile: string) =
|
||||
if r.s[r.pos] == ')': inc r.pos
|
||||
outf.write("<not supported by viewer>)\n")
|
||||
else:
|
||||
internalError("invalid section: '" & section &
|
||||
internalError(r.config, "invalid section: '" & section &
|
||||
"' at " & $r.line & " in " & r.filename)
|
||||
skipSection(r)
|
||||
if r.s[r.pos] == '\x0A':
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
import
|
||||
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
||||
filters, filter_tmpl, renderer
|
||||
filters, filter_tmpl, renderer, configuration
|
||||
|
||||
type
|
||||
TFilterKind* = enum
|
||||
@@ -30,12 +30,14 @@ type
|
||||
skin*: TParserKind
|
||||
parser*: TParser
|
||||
|
||||
template config(p: TParsers): ConfigRef = p.parser.lex.config
|
||||
|
||||
proc parseAll*(p: var TParsers): PNode =
|
||||
case p.skin
|
||||
of skinStandard, skinStrongSpaces:
|
||||
result = parser.parseAll(p.parser)
|
||||
of skinEndX:
|
||||
internalError("parser to implement")
|
||||
internalError(p.config, "parser to implement")
|
||||
result = ast.emptyNode
|
||||
|
||||
proc parseTopLevelStmt*(p: var TParsers): PNode =
|
||||
@@ -43,7 +45,7 @@ proc parseTopLevelStmt*(p: var TParsers): PNode =
|
||||
of skinStandard, skinStrongSpaces:
|
||||
result = parser.parseTopLevelStmt(p.parser)
|
||||
of skinEndX:
|
||||
internalError("parser to implement")
|
||||
internalError(p.config, "parser to implement")
|
||||
result = ast.emptyNode
|
||||
|
||||
proc utf8Bom(s: string): int =
|
||||
@@ -86,39 +88,39 @@ proc getFilter(ident: PIdent): TFilterKind =
|
||||
return i
|
||||
result = filtNone
|
||||
|
||||
proc getParser(ident: PIdent): TParserKind =
|
||||
proc getParser(conf: ConfigRef; n: PNode; ident: PIdent): TParserKind =
|
||||
for i in countup(low(TParserKind), high(TParserKind)):
|
||||
if cmpIgnoreStyle(ident.s, parserNames[i]) == 0:
|
||||
return i
|
||||
rawMessage(errInvalidDirectiveX, ident.s)
|
||||
localError(conf, n.info, "unknown parser: " & ident.s)
|
||||
|
||||
proc getCallee(n: PNode): PIdent =
|
||||
proc getCallee(conf: ConfigRef; n: PNode): PIdent =
|
||||
if n.kind in nkCallKinds and n.sons[0].kind == nkIdent:
|
||||
result = n.sons[0].ident
|
||||
elif n.kind == nkIdent:
|
||||
result = n.ident
|
||||
else:
|
||||
rawMessage(errXNotAllowedHere, renderTree(n))
|
||||
localError(conf, n.info, "invalid filter: " & renderTree(n))
|
||||
|
||||
proc applyFilter(p: var TParsers, n: PNode, filename: string,
|
||||
stdin: PLLStream): PLLStream =
|
||||
var ident = getCallee(n)
|
||||
var ident = getCallee(p.config, n)
|
||||
var f = getFilter(ident)
|
||||
case f
|
||||
of filtNone:
|
||||
p.skin = getParser(ident)
|
||||
p.skin = getParser(p.config, n, ident)
|
||||
result = stdin
|
||||
of filtTemplate:
|
||||
result = filterTmpl(stdin, filename, n)
|
||||
result = filterTmpl(stdin, filename, n, p.config)
|
||||
of filtStrip:
|
||||
result = filterStrip(stdin, filename, n)
|
||||
result = filterStrip(p.config, stdin, filename, n)
|
||||
of filtReplace:
|
||||
result = filterReplace(stdin, filename, n)
|
||||
result = filterReplace(p.config, stdin, filename, n)
|
||||
if f != filtNone:
|
||||
if hintCodeBegin in gNotes:
|
||||
rawMessage(hintCodeBegin, [])
|
||||
if hintCodeBegin in p.config.notes:
|
||||
rawMessage(p.config, hintCodeBegin, [])
|
||||
msgWriteln(result.s)
|
||||
rawMessage(hintCodeEnd, [])
|
||||
rawMessage(p.config, hintCodeEnd, [])
|
||||
|
||||
proc evalPipe(p: var TParsers, n: PNode, filename: string,
|
||||
start: PLLStream): PLLStream =
|
||||
@@ -158,7 +160,7 @@ proc parseFile*(fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): PNode
|
||||
f: File
|
||||
let filename = fileIdx.toFullPathConsiderDirty
|
||||
if not open(f, filename):
|
||||
rawMessage(errCannotOpenFile, filename)
|
||||
rawMessage(config, errGenerated, "cannot open file: " & filename)
|
||||
return
|
||||
openParsers(p, fileIdx, llStreamOpen(f), cache, config)
|
||||
result = parseAll(p)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# this module contains routines for accessing and iterating over types
|
||||
|
||||
import
|
||||
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer
|
||||
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer, options
|
||||
|
||||
type
|
||||
TPreferedDesc* = enum
|
||||
@@ -92,8 +92,9 @@ proc getOrdValue*(n: PNode): BiggestInt =
|
||||
of nkNilLit: result = 0
|
||||
of nkHiddenStdConv: result = getOrdValue(n.sons[1])
|
||||
else:
|
||||
localError(n.info, errOrdinalTypeExpected)
|
||||
result = 0
|
||||
#localError(n.info, errOrdinalTypeExpected)
|
||||
# XXX check usages of getOrdValue
|
||||
result = high(BiggestInt)
|
||||
|
||||
proc isIntLit*(t: PType): bool {.inline.} =
|
||||
result = t.kind == tyInt and t.n != nil and t.n.kind == nkIntLit
|
||||
@@ -105,14 +106,14 @@ proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string =
|
||||
result = sym.owner.name.s & '.' & sym.name.s & '('
|
||||
var n = sym.typ.n
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
var p = n.sons[i]
|
||||
let p = n.sons[i]
|
||||
if p.kind == nkSym:
|
||||
add(result, p.sym.name.s)
|
||||
add(result, ": ")
|
||||
add(result, typeToString(p.sym.typ, prefer))
|
||||
if i != sonsLen(n)-1: add(result, ", ")
|
||||
else:
|
||||
internalError("getProcHeader")
|
||||
result.add renderTree(p)
|
||||
add(result, ')')
|
||||
if n.sons[0].typ != nil:
|
||||
result.add(": " & typeToString(n.sons[0].typ, prefer))
|
||||
@@ -195,10 +196,10 @@ proc searchTypeNodeForAux(n: PNode, p: TTypePredicate,
|
||||
of nkOfBranch, nkElse:
|
||||
result = searchTypeNodeForAux(lastSon(n.sons[i]), p, marker)
|
||||
if result: return
|
||||
else: internalError("searchTypeNodeForAux(record case branch)")
|
||||
else: discard
|
||||
of nkSym:
|
||||
result = searchTypeForAux(n.sym.typ, p, marker)
|
||||
else: internalError(n.info, "searchTypeNodeForAux()")
|
||||
else: discard
|
||||
|
||||
proc searchTypeForAux(t: PType, predicate: TTypePredicate,
|
||||
marker: var IntSet): bool =
|
||||
@@ -244,7 +245,7 @@ proc analyseObjectWithTypeFieldAux(t: PType,
|
||||
if t == nil: return
|
||||
case t.kind
|
||||
of tyObject:
|
||||
if (t.n != nil):
|
||||
if t.n != nil:
|
||||
if searchTypeNodeForAux(t.n, isObjectWithTypeFieldPredicate, marker):
|
||||
return frEmbedded
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
@@ -453,16 +454,17 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
if t.sons[0].kind == tyNone: result = "typedesc"
|
||||
else: result = "type " & typeToString(t.sons[0])
|
||||
of tyStatic:
|
||||
internalAssert t.len > 0
|
||||
if prefer == preferGenericArg and t.n != nil:
|
||||
result = t.n.renderTree
|
||||
else:
|
||||
result = "static[" & typeToString(t.sons[0]) & "]"
|
||||
result = "static[" & (if t.len > 0: typeToString(t.sons[0]) else: "") & "]"
|
||||
if t.n != nil: result.add "(" & renderTree(t.n) & ")"
|
||||
of tyUserTypeClass:
|
||||
internalAssert t.sym != nil and t.sym.owner != nil
|
||||
if t.isResolvedUserTypeClass: return typeToString(t.lastSon)
|
||||
return t.sym.owner.name.s
|
||||
if t.sym != nil and t.sym.owner != nil:
|
||||
if t.isResolvedUserTypeClass: return typeToString(t.lastSon)
|
||||
return t.sym.owner.name.s
|
||||
else:
|
||||
result = "<invalid tyUserTypeClass>"
|
||||
of tyBuiltInTypeClass:
|
||||
result = case t.base.kind:
|
||||
of tyVar: "var"
|
||||
@@ -496,7 +498,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
of tyNot:
|
||||
result = "not " & typeToString(t.sons[0])
|
||||
of tyExpr:
|
||||
internalAssert t.len == 0
|
||||
#internalAssert t.len == 0
|
||||
result = "untyped"
|
||||
of tyFromExpr:
|
||||
result = renderTree(t.n)
|
||||
@@ -616,9 +618,9 @@ proc firstOrd*(t: PType): BiggestInt =
|
||||
result = firstOrd(lastSon(t))
|
||||
of tyOrdinal:
|
||||
if t.len > 0: result = firstOrd(lastSon(t))
|
||||
else: internalError("invalid kind for firstOrd(" & $t.kind & ')')
|
||||
else: internalError(newPartialConfigRef(), "invalid kind for firstOrd(" & $t.kind & ')')
|
||||
else:
|
||||
internalError("invalid kind for firstOrd(" & $t.kind & ')')
|
||||
internalError(newPartialConfigRef(), "invalid kind for firstOrd(" & $t.kind & ')')
|
||||
result = 0
|
||||
|
||||
proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt =
|
||||
@@ -656,9 +658,9 @@ proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt =
|
||||
of tyProxy: result = 0
|
||||
of tyOrdinal:
|
||||
if t.len > 0: result = lastOrd(lastSon(t))
|
||||
else: internalError("invalid kind for lastOrd(" & $t.kind & ')')
|
||||
else: internalError(newPartialConfigRef(), "invalid kind for lastOrd(" & $t.kind & ')')
|
||||
else:
|
||||
internalError("invalid kind for lastOrd(" & $t.kind & ')')
|
||||
internalError(newPartialConfigRef(), "invalid kind for lastOrd(" & $t.kind & ')')
|
||||
result = 0
|
||||
|
||||
proc lengthOrd*(t: PType): BiggestInt =
|
||||
@@ -748,7 +750,7 @@ proc equalParam(a, b: PSym): TParamsEquality =
|
||||
|
||||
proc sameConstraints(a, b: PNode): bool =
|
||||
if isNil(a) and isNil(b): return true
|
||||
internalAssert a.len == b.len
|
||||
if a.len != b.len: return false
|
||||
for i in 1 ..< a.len:
|
||||
if not exprStructuralEquivalent(a[i].sym.constraint,
|
||||
b[i].sym.constraint):
|
||||
@@ -807,7 +809,8 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool =
|
||||
var y = b.n.sons[i].sym
|
||||
result = x.name.id == y.name.id
|
||||
if not result: break
|
||||
else: internalError(a.n.info, "sameTuple")
|
||||
else:
|
||||
return false
|
||||
elif a.n != b.n and (a.n == nil or b.n == nil) and IgnoreTupleFields notin c.flags:
|
||||
result = false
|
||||
|
||||
@@ -997,7 +1000,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
cycleCheck()
|
||||
result = sameTypeAux(a.lastSon, b.lastSon, c)
|
||||
of tyNone: result = false
|
||||
of tyUnused, tyOptAsRef: internalError("sameFlags")
|
||||
of tyUnused, tyOptAsRef: result = false
|
||||
|
||||
proc sameBackendType*(x, y: PType): bool =
|
||||
var c = initSameTypeClosure()
|
||||
@@ -1191,7 +1194,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||
# for now same as error node; we say it's a valid type as it should
|
||||
# prevent cascading errors:
|
||||
result = nil
|
||||
of tyUnused, tyOptAsRef: internalError("typeAllowedAux")
|
||||
of tyUnused, tyOptAsRef: result = t
|
||||
|
||||
proc typeAllowed*(t: PType, kind: TSymKind; flags: TTypeAllowedFlags = {}): PType =
|
||||
# returns 'nil' on success and otherwise the part of the type that is
|
||||
@@ -1280,7 +1283,8 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var BiggestInt): BiggestInt =
|
||||
if res < 0: return res
|
||||
maxSize = max(maxSize, res)
|
||||
maxAlign = max(maxAlign, b)
|
||||
else: internalError("computeRecSizeAux(record case branch)")
|
||||
else:
|
||||
return szIllegalRecursion
|
||||
currOffset = align(currOffset, maxAlign) + maxSize
|
||||
result = align(result, maxAlign) + maxSize
|
||||
a = maxAlign
|
||||
@@ -1441,7 +1445,8 @@ proc getReturnType*(s: PSym): PType =
|
||||
|
||||
proc getSize*(typ: PType): BiggestInt =
|
||||
result = computeSize(typ)
|
||||
if result < 0: internalError("getSize: " & $typ.kind)
|
||||
#if result < 0: internalError("getSize: " & $typ.kind)
|
||||
# XXX review all usages of 'getSize'
|
||||
|
||||
proc containsGenericTypeIter(t: PType, closure: RootRef): bool =
|
||||
case t.kind
|
||||
@@ -1469,8 +1474,7 @@ proc baseOfDistinct*(t: PType): PType =
|
||||
while it.kind in {tyPtr, tyRef}:
|
||||
parent = it
|
||||
it = it.lastSon
|
||||
if it.kind == tyDistinct:
|
||||
internalAssert parent != nil
|
||||
if it.kind == tyDistinct and parent != nil:
|
||||
parent.sons[0] = it.sons[0]
|
||||
|
||||
proc safeInheritanceDiff*(a, b: PType): int =
|
||||
@@ -1502,8 +1506,9 @@ type
|
||||
proc compatibleEffects*(formal, actual: PType): EffectsCompat =
|
||||
# for proc type compatibility checking:
|
||||
assert formal.kind == tyProc and actual.kind == tyProc
|
||||
internalAssert formal.n.sons[0].kind == nkEffectList
|
||||
internalAssert actual.n.sons[0].kind == nkEffectList
|
||||
if formal.n.sons[0].kind != nkEffectList or
|
||||
actual.n.sons[0].kind != nkEffectList:
|
||||
return efTagsUnknown
|
||||
|
||||
var spec = formal.n.sons[0]
|
||||
if spec.len != 0:
|
||||
@@ -1628,14 +1633,14 @@ proc skipHiddenSubConv*(n: PNode): PNode =
|
||||
else:
|
||||
result = n
|
||||
|
||||
proc typeMismatch*(info: TLineInfo, formal, actual: PType) =
|
||||
proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType) =
|
||||
if formal.kind != tyError and actual.kind != tyError:
|
||||
let named = typeToString(formal)
|
||||
let desc = typeToString(formal, preferDesc)
|
||||
let x = if named == desc: named else: named & " = " & desc
|
||||
var msg = msgKindToString(errTypeMismatch) &
|
||||
var msg = "type mismatch: got <" &
|
||||
typeToString(actual) & "> " &
|
||||
msgKindToString(errButExpectedX) % [x]
|
||||
"but expected " & x & "'"
|
||||
|
||||
if formal.kind == tyProc and actual.kind == tyProc:
|
||||
case compatibleEffects(formal, actual)
|
||||
@@ -1650,4 +1655,4 @@ proc typeMismatch*(info: TLineInfo, formal, actual: PType) =
|
||||
msg.add "\n.tag effect is 'any tag allowed'"
|
||||
of efLockLevelsDiffer:
|
||||
msg.add "\nlock levels differ"
|
||||
localError(info, errGenerated, msg)
|
||||
localError(conf, info, msg)
|
||||
|
||||
Reference in New Issue
Block a user