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