big refactoring: magicsys compiles again

This commit is contained in:
Andreas Rumpf
2018-05-10 13:12:42 +02:00
parent 61e57cfa13
commit 0d56dd4677
10 changed files with 269 additions and 244 deletions

View File

@@ -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):

View File

@@ -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):

View File

@@ -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)

View File

@@ -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:

View File

@@ -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:")

View File

@@ -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

View File

@@ -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) =

View File

@@ -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':

View File

@@ -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)

View File

@@ -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)