.compile pragma supports patterns and actions

This commit is contained in:
Araq 2017-01-27 22:54:31 +01:00 • committed by Andreas Rumpf
commit 03a1c3b077
4 changed files with 141 additions and 102 deletions

View file

@ -849,15 +849,15 @@ proc addIntTypes(result: var Rope) {.inline.} =
addf(result, "#define NIM_INTBITS $1" & tnl, [
platform.CPU[targetCPU].intSize.rope])
proc getCopyright(cfile: string): Rope =
proc getCopyright(cfile: Cfile): Rope =
if optCompileOnly in gGlobalOptions:
result = ("/* Generated by Nim Compiler v$1 */$N" &
"/* (c) 2017 Andreas Rumpf */$N" &
"/* (c) " & CompileDate.substr(0, 3) & " Andreas Rumpf */$N" &
"/* The generated code is subject to the original license. */$N") %
[rope(VersionAsString)]
else:
result = ("/* Generated by Nim Compiler v$1 */$N" &
"/* (c) 2017 Andreas Rumpf */$N" &
"/* (c) " & CompileDate.substr(0, 3) & " Andreas Rumpf */$N" &
"/* The generated code is subject to the original license. */$N" &
"/* Compiled for: $2, $3, $4 */$N" &
"/* Command for C compiler:$n $5 */$N") %
@ -867,7 +867,7 @@ proc getCopyright(cfile: string): Rope =
rope(extccomp.CC[extccomp.cCompiler].name),
rope(getCompileCFileCmd(cfile))]
proc getFileHeader(cfile: string): Rope =
proc getFileHeader(cfile: Cfile): Rope =
result = getCopyright(cfile)
addIntTypes(result)
@ -1096,7 +1096,7 @@ proc genInitCode(m: BModule) =
[(i.ord - '0'.ord).rope, el]
add(m.s[cfsInitProc], ex)
proc genModule(m: BModule, cfile: string): Rope =
proc genModule(m: BModule, cfile: Cfile): Rope =
result = getFileHeader(cfile)
result.add(genMergeInfo(m))
@ -1227,7 +1227,11 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
incl g.generatedHeader.flags, isHeaderFile
proc writeHeader(m: BModule) =
var result = getCopyright(m.filename)
var result = ("/* Generated by Nim Compiler v$1 */$N" &
"/* (c) " & CompileDate.substr(0, 3) & " Andreas Rumpf */$N" &
"/* The generated code is subject to the original license. */$N") %
[rope(VersionAsString)]
var guard = "__$1__" % [m.filename.splitFile.name.rope]
result.addf("#ifndef $1$n#define $1$n", [guard])
addIntTypes(result)
@ -1281,20 +1285,19 @@ proc finishModule(m: BModule) =
dec(m.g.forwardedProcsCounter, i)
setLen(m.forwardedProcs, 0)
proc shouldRecompile(code: Rope, cfile: string): bool =
proc shouldRecompile(code: Rope, cfile: Cfile): bool =
result = true
if optForceFullMake notin gGlobalOptions:
var objFile = toObjFile(cfile)
if not equalsFile(code, cfile):
if not equalsFile(code, cfile.cname):
if isDefined("nimdiff"):
copyFile(cfile, cfile & ".backup")
echo "diff ", cfile, ".backup ", cfile
writeRope(code, cfile)
copyFile(cfile.cname, cfile.cname & ".backup")
echo "diff ", cfile.cname, ".backup ", cfile.cname
writeRope(code, cfile.cname)
return
if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false
if existsFile(cfile.obj) and os.fileNewer(cfile.obj, cfile.cname):
result = false
else:
writeRope(code, cfile)
writeRope(code, cfile.cname)
# We need 2 different logics here: pending modules (including
# 'nim__dat') may require file merging for the combination of dead code
@ -1304,8 +1307,7 @@ proc shouldRecompile(code: Rope, cfile: string): bool =
proc writeModule(m: BModule, pending: bool) =
# generate code for the init statements of the module:
var cfile = getCFile(m)
var cfilenoext = changeFileExt(cfile, "")
let cfile = getCFile(m)
if not m.fromCache or optForceFullMake in gGlobalOptions:
genInitCode(m)
@ -1315,42 +1317,45 @@ proc writeModule(m: BModule, pending: bool) =
add(m.s[cfsProcHeaders], m.g.mainModProcs)
generateThreadVarsSize(m)
var code = genModule(m, cfile)
var cf = Cfile(cname: cfile, obj: completeCFilePath(toObjFile(cfile)), flags: {})
var code = genModule(m, cf)
when hasTinyCBackend:
if gCmd == cmdRun:
tccgen.compileCCode($code)
return
if shouldRecompile(code, cfile):
addFileToCompile(cfile)
if not shouldRecompile(code, cf): cf.flags = {CfileFlag.Cached}
addFileToCompile(cf)
elif pending and mergeRequired(m) and sfMainModule notin m.module.flags:
let cf = Cfile(cname: cfile, obj: completeCFilePath(toObjFile(cfile)), flags: {})
mergeFiles(cfile, m)
genInitCode(m)
finishTypeDescriptions(m)
var code = genModule(m, cfile)
var code = genModule(m, cf)
writeRope(code, cfile)
addFileToCompile(cfile)
elif not existsFile(toObjFile(cfilenoext)):
addFileToCompile(cf)
else:
# Consider: first compilation compiles ``system.nim`` and produces
# ``system.c`` but then compilation fails due to an error. This means
# that ``system.o`` is missing, so we need to call the C compiler for it:
addFileToCompile(cfile)
addFileToLink(cfilenoext)
var cf = Cfile(cname: cfile, obj: completeCFilePath(toObjFile(cfile)), flags: {})
if not existsFile(cf.obj): cf.flags = {CfileFlag.Cached}
addFileToCompile(cf)
proc updateCachedModule(m: BModule) =
let cfile = getCFile(m)
let cfilenoext = changeFileExt(cfile, "")
var cf = Cfile(cname: cfile, obj: completeCFilePath(toObjFile(cfile)), flags: {})
if mergeRequired(m) and sfMainModule notin m.module.flags:
mergeFiles(cfile, m)
genInitCode(m)
finishTypeDescriptions(m)
var code = genModule(m, cfile)
writeRope(code, cfile)
addFileToCompile(cfile)
addFileToLink(cfilenoext)
var code = genModule(m, cf)
writeRope(code, cfile)
else:
cf.flags = {CfileFlag.Cached}
addFileToCompile(cf)
proc myClose(b: PPassContext, n: PNode): PNode =
result = n