big refactoring: mores stuff compiles
This commit is contained in:
parent
0d56dd4677
commit
5bf31fcabe
6 changed files with 82 additions and 99 deletions
|
|
@ -113,16 +113,16 @@ when false:
|
||||||
localError(pkg.info, "package name must be an identifier or string literal")
|
localError(pkg.info, "package name must be an identifier or string literal")
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
proc getModuleName*(n: PNode): string =
|
proc getModuleName*(conf: ConfigRef; n: PNode): string =
|
||||||
# This returns a short relative module name without the nim extension
|
# This returns a short relative module name without the nim extension
|
||||||
# e.g. like "system", "importer" or "somepath/module"
|
# e.g. like "system", "importer" or "somepath/module"
|
||||||
# The proc won't perform any checks that the path is actually valid
|
# The proc won't perform any checks that the path is actually valid
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||||
try:
|
try:
|
||||||
result = pathSubs(n.strVal, n.info.toFullPath().splitFile().dir)
|
result = pathSubs(conf, n.strVal, n.info.toFullPath().splitFile().dir)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
localError(n.info, "invalid path: " & n.strVal)
|
localError(conf, n.info, "invalid path: " & n.strVal)
|
||||||
result = n.strVal
|
result = n.strVal
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
result = n.ident.s
|
result = n.ident.s
|
||||||
|
|
@ -137,7 +137,7 @@ proc getModuleName*(n: PNode): string =
|
||||||
n.sons[0] = n.sons[1]
|
n.sons[0] = n.sons[1]
|
||||||
n.sons[1] = n.sons[2]
|
n.sons[1] = n.sons[2]
|
||||||
n.sons.setLen(2)
|
n.sons.setLen(2)
|
||||||
return getModuleName(n.sons[0])
|
return getModuleName(conf, n.sons[0])
|
||||||
when false:
|
when false:
|
||||||
if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$":
|
if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$":
|
||||||
if n0.kind == nkIdent and n0.ident.s == "/":
|
if n0.kind == nkIdent and n0.ident.s == "/":
|
||||||
|
|
@ -146,7 +146,7 @@ proc getModuleName*(n: PNode): string =
|
||||||
localError(n.info, "only '/' supported with $package notation")
|
localError(n.info, "only '/' supported with $package notation")
|
||||||
result = ""
|
result = ""
|
||||||
else:
|
else:
|
||||||
let modname = getModuleName(n[2])
|
let modname = getModuleName(conf, n[2])
|
||||||
if $n1 == "std":
|
if $n1 == "std":
|
||||||
template attempt(a) =
|
template attempt(a) =
|
||||||
let x = addFileExt(a, "nim")
|
let x = addFileExt(a, "nim")
|
||||||
|
|
@ -155,7 +155,7 @@ proc getModuleName*(n: PNode): string =
|
||||||
attempt(options.libpath / candidate / modname)
|
attempt(options.libpath / candidate / modname)
|
||||||
|
|
||||||
# hacky way to implement 'x / y /../ z':
|
# hacky way to implement 'x / y /../ z':
|
||||||
result = getModuleName(n1)
|
result = getModuleName(conf, n1)
|
||||||
result.add renderTree(n0, {renderNoComments})
|
result.add renderTree(n0, {renderNoComments})
|
||||||
result.add modname
|
result.add modname
|
||||||
of nkPrefix:
|
of nkPrefix:
|
||||||
|
|
@ -169,19 +169,19 @@ proc getModuleName*(n: PNode): string =
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
result = renderTree(n, {renderNoComments}).replace(".", "/")
|
result = renderTree(n, {renderNoComments}).replace(".", "/")
|
||||||
of nkImportAs:
|
of nkImportAs:
|
||||||
result = getModuleName(n.sons[0])
|
result = getModuleName(conf, n.sons[0])
|
||||||
else:
|
else:
|
||||||
localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree)
|
localError(conf, n.info, "invalid module name: '$1'" % n.renderTree)
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
proc checkModuleName*(n: PNode; doLocalError=true): FileIndex =
|
proc checkModuleName*(conf: ConfigRef; n: PNode; doLocalError=true): FileIndex =
|
||||||
# This returns the full canonical path for a given module import
|
# This returns the full canonical path for a given module import
|
||||||
let modulename = n.getModuleName
|
let modulename = getModuleName(conf, n)
|
||||||
let fullPath = findModule(modulename, n.info.toFullPath)
|
let fullPath = findModule(conf, modulename, n.info.toFullPath)
|
||||||
if fullPath.len == 0:
|
if fullPath.len == 0:
|
||||||
if doLocalError:
|
if doLocalError:
|
||||||
let m = if modulename.len > 0: modulename else: $n
|
let m = if modulename.len > 0: modulename else: $n
|
||||||
localError(n.info, errCannotOpenFile, m)
|
localError(conf, n.info, "cannot open file: " & m)
|
||||||
result = InvalidFileIDX
|
result = InvalidFileIDX
|
||||||
else:
|
else:
|
||||||
result = fullPath.fileInfoIdx
|
result = fileInfoIdx(conf, fullPath)
|
||||||
|
|
|
||||||
|
|
@ -12,27 +12,10 @@
|
||||||
import
|
import
|
||||||
ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer
|
ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer
|
||||||
|
|
||||||
proc toBitSet*(s: PNode, b: var TBitSet)
|
proc inSet*(s: PNode, elem: PNode): bool =
|
||||||
# this function is used for case statement checking:
|
assert s.kind == nkCurly
|
||||||
proc overlap*(a, b: PNode): bool
|
|
||||||
proc inSet*(s: PNode, elem: PNode): bool
|
|
||||||
proc someInSet*(s: PNode, a, b: PNode): bool
|
|
||||||
proc emptyRange*(a, b: PNode): bool
|
|
||||||
proc setHasRange*(s: PNode): bool
|
|
||||||
# returns true if set contains a range (needed by the code generator)
|
|
||||||
# these are used for constant folding:
|
|
||||||
proc unionSets*(a, b: PNode): PNode
|
|
||||||
proc diffSets*(a, b: PNode): PNode
|
|
||||||
proc intersectSets*(a, b: PNode): PNode
|
|
||||||
proc symdiffSets*(a, b: PNode): PNode
|
|
||||||
proc containsSets*(a, b: PNode): bool
|
|
||||||
proc equalSets*(a, b: PNode): bool
|
|
||||||
proc cardSet*(a: PNode): BiggestInt
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
proc inSet(s: PNode, elem: PNode): bool =
|
|
||||||
if s.kind != nkCurly:
|
if s.kind != nkCurly:
|
||||||
internalError(s.info, "inSet")
|
#internalError(s.info, "inSet")
|
||||||
return false
|
return false
|
||||||
for i in countup(0, sonsLen(s) - 1):
|
for i in countup(0, sonsLen(s) - 1):
|
||||||
if s.sons[i].kind == nkRange:
|
if s.sons[i].kind == nkRange:
|
||||||
|
|
@ -44,7 +27,7 @@ proc inSet(s: PNode, elem: PNode): bool =
|
||||||
return true
|
return true
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc overlap(a, b: PNode): bool =
|
proc overlap*(a, b: PNode): bool =
|
||||||
if a.kind == nkRange:
|
if a.kind == nkRange:
|
||||||
if b.kind == nkRange:
|
if b.kind == nkRange:
|
||||||
# X..Y and C..D overlap iff (X <= D and C <= Y)
|
# X..Y and C..D overlap iff (X <= D and C <= Y)
|
||||||
|
|
@ -58,10 +41,11 @@ proc overlap(a, b: PNode): bool =
|
||||||
else:
|
else:
|
||||||
result = sameValue(a, b)
|
result = sameValue(a, b)
|
||||||
|
|
||||||
proc someInSet(s: PNode, a, b: PNode): bool =
|
proc someInSet*(s: PNode, a, b: PNode): bool =
|
||||||
# checks if some element of a..b is in the set s
|
# checks if some element of a..b is in the set s
|
||||||
|
assert s.kind == nkCurly
|
||||||
if s.kind != nkCurly:
|
if s.kind != nkCurly:
|
||||||
internalError(s.info, "SomeInSet")
|
#internalError(s.info, "SomeInSet")
|
||||||
return false
|
return false
|
||||||
for i in countup(0, sonsLen(s) - 1):
|
for i in countup(0, sonsLen(s) - 1):
|
||||||
if s.sons[i].kind == nkRange:
|
if s.sons[i].kind == nkRange:
|
||||||
|
|
@ -74,7 +58,7 @@ proc someInSet(s: PNode, a, b: PNode): bool =
|
||||||
return true
|
return true
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc toBitSet(s: PNode, b: var TBitSet) =
|
proc toBitSet*(s: PNode, b: var TBitSet) =
|
||||||
var first, j: BiggestInt
|
var first, j: BiggestInt
|
||||||
first = firstOrd(s.typ.sons[0])
|
first = firstOrd(s.typ.sons[0])
|
||||||
bitSetInit(b, int(getSize(s.typ)))
|
bitSetInit(b, int(getSize(s.typ)))
|
||||||
|
|
@ -87,7 +71,7 @@ proc toBitSet(s: PNode, b: var TBitSet) =
|
||||||
else:
|
else:
|
||||||
bitSetIncl(b, getOrdValue(s.sons[i]) - first)
|
bitSetIncl(b, getOrdValue(s.sons[i]) - first)
|
||||||
|
|
||||||
proc toTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
|
proc toTreeSet*(s: TBitSet, settype: PType, info: TLineInfo): PNode =
|
||||||
var
|
var
|
||||||
a, b, e, first: BiggestInt # a, b are interval borders
|
a, b, e, first: BiggestInt # a, b are interval borders
|
||||||
elemType: PType
|
elemType: PType
|
||||||
|
|
@ -128,18 +112,18 @@ template nodeSetOp(a, b: PNode, op: untyped) {.dirty.} =
|
||||||
op(x, y)
|
op(x, y)
|
||||||
result = toTreeSet(x, a.typ, a.info)
|
result = toTreeSet(x, a.typ, a.info)
|
||||||
|
|
||||||
proc unionSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetUnion)
|
proc unionSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetUnion)
|
||||||
proc diffSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff)
|
proc diffSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff)
|
||||||
proc intersectSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect)
|
proc intersectSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect)
|
||||||
proc symdiffSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff)
|
proc symdiffSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff)
|
||||||
|
|
||||||
proc containsSets(a, b: PNode): bool =
|
proc containsSets*(a, b: PNode): bool =
|
||||||
var x, y: TBitSet
|
var x, y: TBitSet
|
||||||
toBitSet(a, x)
|
toBitSet(a, x)
|
||||||
toBitSet(b, y)
|
toBitSet(b, y)
|
||||||
result = bitSetContains(x, y)
|
result = bitSetContains(x, y)
|
||||||
|
|
||||||
proc equalSets(a, b: PNode): bool =
|
proc equalSets*(a, b: PNode): bool =
|
||||||
var x, y: TBitSet
|
var x, y: TBitSet
|
||||||
toBitSet(a, x)
|
toBitSet(a, x)
|
||||||
toBitSet(b, y)
|
toBitSet(b, y)
|
||||||
|
|
@ -156,20 +140,19 @@ proc deduplicate*(a: PNode): PNode =
|
||||||
toBitSet(a, x)
|
toBitSet(a, x)
|
||||||
result = toTreeSet(x, a.typ, a.info)
|
result = toTreeSet(x, a.typ, a.info)
|
||||||
|
|
||||||
proc cardSet(a: PNode): BiggestInt =
|
proc cardSet*(a: PNode): BiggestInt =
|
||||||
var x: TBitSet
|
var x: TBitSet
|
||||||
toBitSet(a, x)
|
toBitSet(a, x)
|
||||||
result = bitSetCard(x)
|
result = bitSetCard(x)
|
||||||
|
|
||||||
proc setHasRange(s: PNode): bool =
|
proc setHasRange*(s: PNode): bool =
|
||||||
|
assert s.kind == nkCurly
|
||||||
if s.kind != nkCurly:
|
if s.kind != nkCurly:
|
||||||
internalError(s.info, "SetHasRange")
|
|
||||||
return false
|
return false
|
||||||
for i in countup(0, sonsLen(s) - 1):
|
for i in countup(0, sonsLen(s) - 1):
|
||||||
if s.sons[i].kind == nkRange:
|
if s.sons[i].kind == nkRange:
|
||||||
return true
|
return true
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc emptyRange(a, b: PNode): bool =
|
proc emptyRange*(a, b: PNode): bool =
|
||||||
result = not leValue(a, b) # a > b iff not (a <= b)
|
result = not leValue(a, b) # a > b iff not (a <= b)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
import
|
import
|
||||||
strutils, options, ast, astalgo, llstream, msgs, platform, os,
|
strutils, options, ast, astalgo, llstream, msgs, platform, os,
|
||||||
condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
|
condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
|
||||||
nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder, rod
|
nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder, rod,
|
||||||
|
configuration
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -57,11 +58,11 @@ var
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
proc skipCodegen*(n: PNode): bool {.inline.} =
|
proc skipCodegen*(config: ConfigRef; n: PNode): bool {.inline.} =
|
||||||
# can be used by codegen passes to determine whether they should do
|
# can be used by codegen passes to determine whether they should do
|
||||||
# something with `n`. Currently, this ignores `n` and uses the global
|
# something with `n`. Currently, this ignores `n` and uses the global
|
||||||
# error count instead.
|
# error count instead.
|
||||||
result = msgs.gErrorCounter > 0
|
result = config.errorCounter > 0
|
||||||
|
|
||||||
const
|
const
|
||||||
maxPasses = 10
|
maxPasses = 10
|
||||||
|
|
@ -139,20 +140,21 @@ proc closePassesCached(graph: ModuleGraph; a: var TPassContextArray) =
|
||||||
m = gPasses[i].close(graph, a[i], m)
|
m = gPasses[i].close(graph, a[i], m)
|
||||||
a[i] = nil # free the memory here
|
a[i] = nil # free the memory here
|
||||||
|
|
||||||
proc resolveMod(module, relativeTo: string): FileIndex =
|
proc resolveMod(conf: ConfigRef; module, relativeTo: string): FileIndex =
|
||||||
let fullPath = findModule(module, relativeTo)
|
let fullPath = findModule(conf, module, relativeTo)
|
||||||
if fullPath.len == 0:
|
if fullPath.len == 0:
|
||||||
result = InvalidFileIDX
|
result = InvalidFileIDX
|
||||||
else:
|
else:
|
||||||
result = fullPath.fileInfoIdx
|
result = fileInfoIdx(conf, fullPath)
|
||||||
|
|
||||||
proc processImplicits(implicits: seq[string], nodeKind: TNodeKind,
|
proc processImplicits(conf: ConfigRef; implicits: seq[string], nodeKind: TNodeKind,
|
||||||
a: var TPassContextArray; m: PSym) =
|
a: var TPassContextArray; m: PSym) =
|
||||||
# XXX fixme this should actually be relative to the config file!
|
# XXX fixme this should actually be relative to the config file!
|
||||||
|
let gCmdLineInfo = newLineInfo(FileIndex(0), 1, 1)
|
||||||
let relativeTo = m.info.toFullPath
|
let relativeTo = m.info.toFullPath
|
||||||
for module in items(implicits):
|
for module in items(implicits):
|
||||||
# implicit imports should not lead to a module importing itself
|
# implicit imports should not lead to a module importing itself
|
||||||
if m.position != resolveMod(module, relativeTo).int32:
|
if m.position != resolveMod(conf, module, relativeTo).int32:
|
||||||
var importStmt = newNodeI(nodeKind, gCmdLineInfo)
|
var importStmt = newNodeI(nodeKind, gCmdLineInfo)
|
||||||
var str = newStrNode(nkStrLit, module)
|
var str = newStrNode(nkStrLit, module)
|
||||||
str.info = gCmdLineInfo
|
str.info = gCmdLineInfo
|
||||||
|
|
@ -202,7 +204,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||||
let filename = fileIdx.toFullPathConsiderDirty
|
let filename = fileIdx.toFullPathConsiderDirty
|
||||||
s = llStreamOpen(filename, fmRead)
|
s = llStreamOpen(filename, fmRead)
|
||||||
if s == nil:
|
if s == nil:
|
||||||
rawMessage(errCannotOpenFile, filename)
|
rawMessage(graph.config, errCannotOpenFile, filename)
|
||||||
return false
|
return false
|
||||||
else:
|
else:
|
||||||
s = stream
|
s = stream
|
||||||
|
|
@ -214,8 +216,8 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||||
# modules to include between compilation runs? we'd need to track that
|
# modules to include between compilation runs? we'd need to track that
|
||||||
# in ROD files. I think we should enable this feature only
|
# in ROD files. I think we should enable this feature only
|
||||||
# for the interactive mode.
|
# for the interactive mode.
|
||||||
processImplicits implicitImports, nkImportStmt, a, module
|
processImplicits graph.config, implicitImports, nkImportStmt, a, module
|
||||||
processImplicits implicitIncludes, nkIncludeStmt, a, module
|
processImplicits graph.config, implicitIncludes, nkIncludeStmt, a, module
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
if graph.stopCompile(): break
|
if graph.stopCompile(): break
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils,
|
intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils,
|
||||||
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables
|
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables,
|
||||||
|
configuration
|
||||||
|
|
||||||
type
|
type
|
||||||
DepN = ref object
|
DepN = ref object
|
||||||
|
|
@ -151,10 +152,10 @@ proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode,
|
||||||
for a in n:
|
for a in n:
|
||||||
if a.kind == nkIncludeStmt:
|
if a.kind == nkIncludeStmt:
|
||||||
for i in 0..<a.len:
|
for i in 0..<a.len:
|
||||||
var f = checkModuleName(a.sons[i])
|
var f = checkModuleName(graph.config, a.sons[i])
|
||||||
if f != InvalidFileIDX:
|
if f != InvalidFileIDX:
|
||||||
if containsOrIncl(includedFiles, f.int):
|
if containsOrIncl(includedFiles, f.int):
|
||||||
localError(a.info, errRecursiveDependencyX, f.toFilename)
|
localError(graph.config, a.info, "recursive dependency: '$1'" % f.toFilename)
|
||||||
else:
|
else:
|
||||||
let nn = includeModule(graph, module, f, cache)
|
let nn = includeModule(graph, module, f, cache)
|
||||||
let nnn = expandIncludes(graph, module, nn, modulePath,
|
let nnn = expandIncludes(graph, module, nn, modulePath,
|
||||||
|
|
@ -189,7 +190,7 @@ proc haveSameKind(dns: seq[DepN]): bool =
|
||||||
if dn.pnode.kind != kind:
|
if dn.pnode.kind != kind:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
proc mergeSections(comps: seq[seq[DepN]], res: PNode) =
|
proc mergeSections(conf: ConfigRef; comps: seq[seq[DepN]], res: PNode) =
|
||||||
# Merges typeSections and ConstSections when they form
|
# Merges typeSections and ConstSections when they form
|
||||||
# a strong component (ex: circular type definition)
|
# a strong component (ex: circular type definition)
|
||||||
for c in comps:
|
for c in comps:
|
||||||
|
|
@ -229,7 +230,7 @@ proc mergeSections(comps: seq[seq[DepN]], res: PNode) =
|
||||||
wmsg &= "line " & $cs[^1].pnode.info.line &
|
wmsg &= "line " & $cs[^1].pnode.info.line &
|
||||||
" depends on line " & $cs[j].pnode.info.line &
|
" depends on line " & $cs[j].pnode.info.line &
|
||||||
": " & cs[^1].expls[ci] & "\n"
|
": " & cs[^1].expls[ci] & "\n"
|
||||||
message(cs[0].pnode.info, warnUser, wmsg)
|
message(conf, cs[0].pnode.info, warnUser, wmsg)
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < cs.len:
|
while i < cs.len:
|
||||||
|
|
@ -441,4 +442,4 @@ proc reorder*(graph: ModuleGraph, n: PNode, module: PSym, cache: IdentCache): PN
|
||||||
|
|
||||||
var g = buildGraph(n, deps)
|
var g = buildGraph(n, deps)
|
||||||
let comps = getStrongComponents(g)
|
let comps = getStrongComponents(g)
|
||||||
mergeSections(comps, result)
|
mergeSections(graph.config, comps, result)
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,13 @@ type
|
||||||
files: TStringSeq
|
files: TStringSeq
|
||||||
origFile: string
|
origFile: string
|
||||||
cache: IdentCache
|
cache: IdentCache
|
||||||
|
config: ConfigRef
|
||||||
|
|
||||||
PRodWriter = ref TRodWriter
|
PRodWriter = ref TRodWriter
|
||||||
|
|
||||||
proc getDefines(): string =
|
proc getDefines(conf: ConfigRef): string =
|
||||||
result = ""
|
result = ""
|
||||||
for d in definedSymbolNames():
|
for d in definedSymbolNames(conf.symbols):
|
||||||
if result.len != 0: add(result, " ")
|
if result.len != 0: add(result, " ")
|
||||||
add(result, d)
|
add(result, d)
|
||||||
|
|
||||||
|
|
@ -57,8 +58,10 @@ proc fileIdx(w: PRodWriter, filename: string): int =
|
||||||
template filename*(w: PRodWriter): string =
|
template filename*(w: PRodWriter): string =
|
||||||
toFilename(FileIndex w.module.position)
|
toFilename(FileIndex w.module.position)
|
||||||
|
|
||||||
proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache): PRodWriter =
|
proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache;
|
||||||
|
config: ConfigRef): PRodWriter =
|
||||||
new(result)
|
new(result)
|
||||||
|
result.config = config
|
||||||
result.sstack = @[]
|
result.sstack = @[]
|
||||||
result.tstack = @[]
|
result.tstack = @[]
|
||||||
initIiTable(result.index.tab)
|
initIiTable(result.index.tab)
|
||||||
|
|
@ -67,7 +70,7 @@ proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache): PRodWriter
|
||||||
result.imports.r = ""
|
result.imports.r = ""
|
||||||
result.hash = hash
|
result.hash = hash
|
||||||
result.module = module
|
result.module = module
|
||||||
result.defines = getDefines()
|
result.defines = getDefines(config)
|
||||||
result.options = options.gOptions
|
result.options = options.gOptions
|
||||||
result.files = @[]
|
result.files = @[]
|
||||||
result.inclDeps = ""
|
result.inclDeps = ""
|
||||||
|
|
@ -83,14 +86,14 @@ proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache): PRodWriter
|
||||||
|
|
||||||
proc addModDep(w: PRodWriter, dep: string; info: TLineInfo) =
|
proc addModDep(w: PRodWriter, dep: string; info: TLineInfo) =
|
||||||
if w.modDeps.len != 0: add(w.modDeps, ' ')
|
if w.modDeps.len != 0: add(w.modDeps, ' ')
|
||||||
let resolved = dep.findModule(info.toFullPath)
|
let resolved = findModule(w.config, dep, info.toFullPath)
|
||||||
encodeVInt(fileIdx(w, resolved), w.modDeps)
|
encodeVInt(fileIdx(w, resolved), w.modDeps)
|
||||||
|
|
||||||
const
|
const
|
||||||
rodNL = "\x0A"
|
rodNL = "\x0A"
|
||||||
|
|
||||||
proc addInclDep(w: PRodWriter, dep: string; info: TLineInfo) =
|
proc addInclDep(w: PRodWriter, dep: string; info: TLineInfo) =
|
||||||
let resolved = dep.findModule(info.toFullPath)
|
let resolved = findModule(w.config, dep, info.toFullPath)
|
||||||
encodeVInt(fileIdx(w, resolved), w.inclDeps)
|
encodeVInt(fileIdx(w, resolved), w.inclDeps)
|
||||||
add(w.inclDeps, " ")
|
add(w.inclDeps, " ")
|
||||||
encodeStr($secureHashFile(resolved), w.inclDeps)
|
encodeStr($secureHashFile(resolved), w.inclDeps)
|
||||||
|
|
@ -201,7 +204,7 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) =
|
||||||
result.add("[]")
|
result.add("[]")
|
||||||
return
|
return
|
||||||
# we need no surrounding [] here because the type is in a line of its own
|
# we need no surrounding [] here because the type is in a line of its own
|
||||||
if t.kind == tyForward: internalError("encodeType: tyForward")
|
if t.kind == tyForward: internalError(w.config, "encodeType: tyForward")
|
||||||
# for the new rodfile viewer we use a preceding [ so that the data section
|
# for the new rodfile viewer we use a preceding [ so that the data section
|
||||||
# can easily be disambiguated:
|
# can easily be disambiguated:
|
||||||
add(result, '[')
|
add(result, '[')
|
||||||
|
|
@ -454,7 +457,7 @@ proc processStacks(w: PRodWriter, finalPass: bool) =
|
||||||
oldS = slen
|
oldS = slen
|
||||||
oldT = tlen
|
oldT = tlen
|
||||||
if finalPass and (oldS != 0 or oldT != 0):
|
if finalPass and (oldS != 0 or oldT != 0):
|
||||||
internalError("could not serialize some forwarded symbols/types")
|
internalError(w.config, "could not serialize some forwarded symbols/types")
|
||||||
|
|
||||||
proc rawAddInterfaceSym(w: PRodWriter, s: PSym) =
|
proc rawAddInterfaceSym(w: PRodWriter, s: PSym) =
|
||||||
pushSym(w, s)
|
pushSym(w, s)
|
||||||
|
|
@ -476,7 +479,7 @@ proc addStmt(w: PRodWriter, n: PNode) =
|
||||||
proc writeRod(w: PRodWriter) =
|
proc writeRod(w: PRodWriter) =
|
||||||
processStacks(w, true)
|
processStacks(w, true)
|
||||||
var f: File
|
var f: File
|
||||||
if not open(f, completeGeneratedFilePath(changeFileExt(
|
if not open(f, completeGeneratedFilePath(w.config, changeFileExt(
|
||||||
w.filename.withPackageName, RodExt)),
|
w.filename.withPackageName, RodExt)),
|
||||||
fmWrite):
|
fmWrite):
|
||||||
#echo "couldn't write rod file for: ", w.filename
|
#echo "couldn't write rod file for: ", w.filename
|
||||||
|
|
@ -587,17 +590,17 @@ proc process(c: PPassContext, n: PNode): PNode =
|
||||||
of nkProcDef, nkFuncDef, nkIteratorDef, nkConverterDef,
|
of nkProcDef, nkFuncDef, nkIteratorDef, nkConverterDef,
|
||||||
nkTemplateDef, nkMacroDef:
|
nkTemplateDef, nkMacroDef:
|
||||||
let s = n.sons[namePos].sym
|
let s = n.sons[namePos].sym
|
||||||
if s == nil: internalError(n.info, "rodwrite.process")
|
if s == nil: internalError(w.config, n.info, "rodwrite.process")
|
||||||
if n.sons[bodyPos] == nil:
|
if n.sons[bodyPos] == nil:
|
||||||
internalError(n.info, "rodwrite.process: body is nil")
|
internalError(w.config, n.info, "rodwrite.process: body is nil")
|
||||||
if n.sons[bodyPos].kind != nkEmpty or s.magic != mNone or
|
if n.sons[bodyPos].kind != nkEmpty or s.magic != mNone or
|
||||||
sfForward notin s.flags:
|
sfForward notin s.flags:
|
||||||
addInterfaceSym(w, s)
|
addInterfaceSym(w, s)
|
||||||
of nkMethodDef:
|
of nkMethodDef:
|
||||||
let s = n.sons[namePos].sym
|
let s = n.sons[namePos].sym
|
||||||
if s == nil: internalError(n.info, "rodwrite.process")
|
if s == nil: internalError(w.config, n.info, "rodwrite.process")
|
||||||
if n.sons[bodyPos] == nil:
|
if n.sons[bodyPos] == nil:
|
||||||
internalError(n.info, "rodwrite.process: body is nil")
|
internalError(w.config, n.info, "rodwrite.process: body is nil")
|
||||||
if n.sons[bodyPos].kind != nkEmpty or s.magic != mNone or
|
if n.sons[bodyPos].kind != nkEmpty or s.magic != mNone or
|
||||||
sfForward notin s.flags:
|
sfForward notin s.flags:
|
||||||
pushSym(w, s)
|
pushSym(w, s)
|
||||||
|
|
@ -612,7 +615,7 @@ proc process(c: PPassContext, n: PNode): PNode =
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var a = n.sons[i]
|
var a = n.sons[i]
|
||||||
if a.kind == nkCommentStmt: continue
|
if a.kind == nkCommentStmt: continue
|
||||||
if a.sons[0].kind != nkSym: internalError(a.info, "rodwrite.process")
|
if a.sons[0].kind != nkSym: internalError(w.config, a.info, "rodwrite.process")
|
||||||
var s = a.sons[0].sym
|
var s = a.sons[0].sym
|
||||||
addInterfaceSym(w, s)
|
addInterfaceSym(w, s)
|
||||||
# this takes care of enum fields too
|
# this takes care of enum fields too
|
||||||
|
|
@ -627,22 +630,22 @@ proc process(c: PPassContext, n: PNode): PNode =
|
||||||
# end
|
# end
|
||||||
of nkImportStmt:
|
of nkImportStmt:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
addModDep(w, getModuleName(n.sons[i]), n.info)
|
addModDep(w, getModuleName(w.config, n.sons[i]), n.info)
|
||||||
addStmt(w, n)
|
addStmt(w, n)
|
||||||
of nkFromStmt, nkImportExceptStmt:
|
of nkFromStmt, nkImportExceptStmt:
|
||||||
addModDep(w, getModuleName(n.sons[0]), n.info)
|
addModDep(w, getModuleName(w.config, n.sons[0]), n.info)
|
||||||
addStmt(w, n)
|
addStmt(w, n)
|
||||||
of nkIncludeStmt:
|
of nkIncludeStmt:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
addInclDep(w, getModuleName(n.sons[i]), n.info)
|
addInclDep(w, getModuleName(w.config, n.sons[i]), n.info)
|
||||||
of nkPragma:
|
of nkPragma:
|
||||||
addStmt(w, n)
|
addStmt(w, n)
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
if module.id < 0: internalError("rodwrite: module ID not set")
|
if module.id < 0: internalError(g.config, "rodwrite: module ID not set")
|
||||||
var w = newRodWriter(rodread.getHash FileIndex module.position, module, cache)
|
var w = newRodWriter(rodread.getHash FileIndex module.position, module, cache, g.config)
|
||||||
rawAddInterfaceSym(w, module)
|
rawAddInterfaceSym(w, module)
|
||||||
result = w
|
result = w
|
||||||
|
|
||||||
|
|
@ -650,7 +653,7 @@ proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
|
||||||
result = process(c, n)
|
result = process(c, n)
|
||||||
var w = PRodWriter(c)
|
var w = PRodWriter(c)
|
||||||
writeRod(w)
|
writeRod(w)
|
||||||
idgen.saveMaxIds(options.gProjectPath / options.gProjectName)
|
idgen.saveMaxIds(graph.config, options.gProjectPath / options.gProjectName)
|
||||||
|
|
||||||
const rodwritePass* = makePass(open = myOpen, close = myClose, process = process)
|
const rodwritePass* = makePass(open = myOpen, close = myClose, process = process)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,12 @@
|
||||||
import
|
import
|
||||||
strutils, options, ast, astalgo, trees, treetab, nimsets, times,
|
strutils, options, ast, astalgo, trees, treetab, nimsets, times,
|
||||||
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
|
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
|
||||||
commands, magicsys
|
commands, magicsys, modulegraphs
|
||||||
|
|
||||||
proc getConstExpr*(m: PSym, n: PNode): PNode
|
proc getConstExpr*(m: PSym, n: PNode): PNode
|
||||||
# evaluates the constant expression or returns nil if it is no constant
|
# evaluates the constant expression or returns nil if it is no constant
|
||||||
# expression
|
# expression
|
||||||
proc evalOp*(m: TMagic, n, a, b, c: PNode): PNode
|
proc evalOp*(m: TMagic, n, a, b, c: PNode): PNode
|
||||||
proc leValueConv*(a, b: PNode): bool
|
|
||||||
proc newIntNodeT*(intVal: BiggestInt, n: PNode): PNode
|
|
||||||
proc newFloatNodeT(floatVal: BiggestFloat, n: PNode): PNode
|
|
||||||
proc newStrNodeT*(strVal: string, n: PNode): PNode
|
|
||||||
|
|
||||||
proc checkInRange(n: PNode, res: BiggestInt): bool =
|
proc checkInRange(n: PNode, res: BiggestInt): bool =
|
||||||
if res in firstOrd(n.typ)..lastOrd(n.typ):
|
if res in firstOrd(n.typ)..lastOrd(n.typ):
|
||||||
|
|
@ -32,7 +28,7 @@ proc foldAdd(a, b: BiggestInt, n: PNode): PNode =
|
||||||
let res = a +% b
|
let res = a +% b
|
||||||
if ((res xor a) >= 0'i64 or (res xor b) >= 0'i64) and
|
if ((res xor a) >= 0'i64 or (res xor b) >= 0'i64) and
|
||||||
checkInRange(n, res):
|
checkInRange(n, res):
|
||||||
result = newIntNodeT(res, n)
|
result = newIntNodeT(res, n)
|
||||||
|
|
||||||
proc foldSub*(a, b: BiggestInt, n: PNode): PNode =
|
proc foldSub*(a, b: BiggestInt, n: PNode): PNode =
|
||||||
let res = a -% b
|
let res = a -% b
|
||||||
|
|
@ -43,7 +39,7 @@ proc foldSub*(a, b: BiggestInt, n: PNode): PNode =
|
||||||
proc foldAbs*(a: BiggestInt, n: PNode): PNode =
|
proc foldAbs*(a: BiggestInt, n: PNode): PNode =
|
||||||
if a != firstOrd(n.typ):
|
if a != firstOrd(n.typ):
|
||||||
result = newIntNodeT(a, n)
|
result = newIntNodeT(a, n)
|
||||||
|
|
||||||
proc foldMod*(a, b: BiggestInt, n: PNode): PNode =
|
proc foldMod*(a, b: BiggestInt, n: PNode): PNode =
|
||||||
if b != 0'i64:
|
if b != 0'i64:
|
||||||
result = newIntNodeT(a mod b, n)
|
result = newIntNodeT(a mod b, n)
|
||||||
|
|
@ -81,9 +77,7 @@ proc foldMul*(a, b: BiggestInt, n: PNode): PNode =
|
||||||
checkInRange(n, res):
|
checkInRange(n, res):
|
||||||
return newIntNodeT(res, n)
|
return newIntNodeT(res, n)
|
||||||
|
|
||||||
# implementation
|
proc newIntNodeT*(intVal: BiggestInt, n: PNode): PNode =
|
||||||
|
|
||||||
proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
|
|
||||||
case skipTypes(n.typ, abstractVarRange).kind
|
case skipTypes(n.typ, abstractVarRange).kind
|
||||||
of tyInt:
|
of tyInt:
|
||||||
result = newIntNode(nkIntLit, intVal)
|
result = newIntNode(nkIntLit, intVal)
|
||||||
|
|
@ -103,7 +97,7 @@ proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
||||||
proc newFloatNodeT(floatVal: BiggestFloat, n: PNode): PNode =
|
proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode): PNode =
|
||||||
result = newFloatNode(nkFloatLit, floatVal)
|
result = newFloatNode(nkFloatLit, floatVal)
|
||||||
if skipTypes(n.typ, abstractVarRange).kind == tyFloat:
|
if skipTypes(n.typ, abstractVarRange).kind == tyFloat:
|
||||||
result.typ = getFloatLitType(result)
|
result.typ = getFloatLitType(result)
|
||||||
|
|
@ -111,7 +105,7 @@ proc newFloatNodeT(floatVal: BiggestFloat, n: PNode): PNode =
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
||||||
proc newStrNodeT(strVal: string, n: PNode): PNode =
|
proc newStrNodeT*(strVal: string, n: PNode): PNode =
|
||||||
result = newStrNode(nkStrLit, strVal)
|
result = newStrNode(nkStrLit, strVal)
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
@ -378,7 +372,7 @@ proc getConstIfExpr(c: PSym, n: PNode): PNode =
|
||||||
if result == nil: result = getConstExpr(c, it.sons[0])
|
if result == nil: result = getConstExpr(c, it.sons[0])
|
||||||
else: internalError(it.info, "getConstIfExpr()")
|
else: internalError(it.info, "getConstIfExpr()")
|
||||||
|
|
||||||
proc leValueConv(a, b: PNode): bool =
|
proc leValueConv*(a, b: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkUInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue