Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Andreas Rumpf 2016-12-17 14:22:58 +01:00
commit 9ac76b49c0
21 changed files with 440 additions and 277 deletions

View file

@ -657,14 +657,62 @@ proc compileCFile(list: TLinkedList, script: var Rope, cmds: var TStringSeq,
add(script, tnl)
it = PStrEntry(it.next)
proc getLinkCmd(projectfile, objfiles: string): string =
if optGenStaticLib in gGlobalOptions:
var libname: string
if options.outFile.len > 0:
libname = options.outFile.expandTilde
if not libname.isAbsolute():
libname = getCurrentDir() / libname
else:
libname = (libNameTmpl() % splitFile(gProjectName).name)
result = CC[cCompiler].buildLib % ["libfile", libname,
"objfiles", objfiles]
else:
var linkerExe = getConfigVar(cCompiler, ".linkerexe")
if len(linkerExe) == 0: linkerExe = cCompiler.getLinkerExe
if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
if noAbsolutePaths(): result = quoteShell(linkerExe)
else: result = quoteShell(joinPath(ccompilerpath, linkerExe))
let buildgui = if optGenGuiApp in gGlobalOptions: CC[cCompiler].buildGui
else: ""
var exefile, builddll: string
if optGenDynLib in gGlobalOptions:
exefile = platform.OS[targetOS].dllFrmt % splitFile(projectfile).name
builddll = CC[cCompiler].buildDll
else:
exefile = splitFile(projectfile).name & platform.OS[targetOS].exeExt
builddll = ""
if options.outFile.len > 0:
exefile = options.outFile.expandTilde
if not exefile.isAbsolute():
exefile = getCurrentDir() / exefile
if not noAbsolutePaths():
if not exefile.isAbsolute():
exefile = joinPath(splitFile(projectfile).dir, exefile)
if optCDebug in gGlobalOptions:
writeDebugInfo(exefile.changeFileExt("ndb"))
exefile = quoteShell(exefile)
let linkOptions = getLinkOptions() & " " &
getConfigVar(cCompiler, ".options.linker")
result = quoteShell(result % ["builddll", builddll,
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
"exefile", exefile, "nim", getPrefixDir(), "lib", libpath])
result.add ' '
addf(result, CC[cCompiler].linkTmpl, ["builddll", builddll,
"buildgui", buildgui, "options", linkOptions,
"objfiles", objfiles, "exefile", exefile,
"nim", quoteShell(getPrefixDir()),
"lib", quoteShell(libpath)])
proc callCCompiler*(projectfile: string) =
var
linkCmd, buildgui, builddll: string
linkCmd, buildgui: string
if gGlobalOptions * {optCompileOnly, optGenScript} == {optCompileOnly}:
return # speed up that call if only compiling and no script shall be
# generated
fileCounter = 0
var c = cCompiler
#var c = cCompiler
var script: Rope = nil
var cmds: TStringSeq = @[]
var prettyCmds: TStringSeq = @[]
@ -708,46 +756,7 @@ proc callCCompiler*(projectfile: string) =
addFileExt(objFile, CC[cCompiler].objExt)))
it = PStrEntry(it.next)
if optGenStaticLib in gGlobalOptions:
let name = splitFile(gProjectName).name
linkCmd = CC[c].buildLib % ["libfile", (libNameTmpl() % name),
"objfiles", objfiles]
else:
var linkerExe = getConfigVar(c, ".linkerexe")
if len(linkerExe) == 0: linkerExe = c.getLinkerExe
if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
if noAbsolutePaths(): linkCmd = quoteShell(linkerExe)
else: linkCmd = quoteShell(joinPath(ccompilerpath, linkerExe))
if optGenGuiApp in gGlobalOptions: buildgui = CC[c].buildGui
else: buildgui = ""
var exefile: string
if optGenDynLib in gGlobalOptions:
exefile = platform.OS[targetOS].dllFrmt % splitFile(projectfile).name
builddll = CC[c].buildDll
else:
exefile = splitFile(projectfile).name & platform.OS[targetOS].exeExt
builddll = ""
if options.outFile.len > 0:
exefile = options.outFile.expandTilde
if not exefile.isAbsolute():
exefile = getCurrentDir() / exefile
if not noAbsolutePaths():
if not exefile.isAbsolute():
exefile = joinPath(splitFile(projectfile).dir, exefile)
if optCDebug in gGlobalOptions:
writeDebugInfo(exefile.changeFileExt("ndb"))
exefile = quoteShell(exefile)
let linkOptions = getLinkOptions() & " " &
getConfigVar(cCompiler, ".options.linker")
linkCmd = quoteShell(linkCmd % ["builddll", builddll,
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
"exefile", exefile, "nim", getPrefixDir(), "lib", libpath])
linkCmd.add ' '
addf(linkCmd, CC[c].linkTmpl, ["builddll", builddll,
"buildgui", buildgui, "options", linkOptions,
"objfiles", objfiles, "exefile", exefile,
"nim", quoteShell(getPrefixDir()),
"lib", quoteShell(libpath)])
linkCmd = getLinkCmd(projectfile, objfiles)
if optCompileOnly notin gGlobalOptions:
execExternalProgram(linkCmd,
if optListCmd in gGlobalOptions or gVerbosity > 1: hintExecuting else: hintLinking)
@ -758,6 +767,62 @@ proc callCCompiler*(projectfile: string) =
add(script, tnl)
generateScript(projectfile, script)
from json import escapeJson
proc writeJsonBuildInstructions*(projectfile: string) =
template lit(x: untyped) = f.write x
template str(x: untyped) =
buf.setLen 0
escapeJson(x, buf)
f.write buf
proc cfiles(f: File; buf: var string; list: TLinkedList, isExternal: bool) =
var it = PStrEntry(list.head)
while it != nil:
let compileCmd = getCompileCFileCmd(it.data, isExternal)
lit "["
str it.data
lit ", "
str compileCmd
it = PStrEntry(it.next)
if it == nil:
lit "]\L"
else:
lit "],\L"
proc linkfiles(f: File; buf, objfiles: var string; toLink: TLinkedList) =
var it = PStrEntry(toLink.head)
while it != nil:
let objfile = addFileExt(it.data, CC[cCompiler].objExt)
str objfile
add(objfiles, ' ')
add(objfiles, quoteShell(objfile))
it = PStrEntry(it.next)
if it == nil:
lit "\L"
else:
lit ",\L"
var buf = newStringOfCap(50)
let file = projectfile.splitFile.name
let jsonFile = toGeneratedFile(file, "json")
var f: File
if open(f, jsonFile, fmWrite):
lit "{\"compile\":[\L"
cfiles(f, buf, toCompile, false)
lit "],\L\"extcompile\":[\L"
cfiles(f, buf, externalToCompile, true)
lit "],\L\"link\":[\L"
var objfiles = ""
linkfiles(f, buf, objfiles, toLink)
lit "],\L\"linkcmd\": "
str getLinkCmd(projectfile, objfiles)
lit "\L}\L"
close(f)
proc genMappingFiles(list: TLinkedList): Rope =
var it = PStrEntry(list.head)
while it != nil:

View file

@ -66,7 +66,9 @@ proc commandCompileToC(graph: ModuleGraph; cache: IdentCache) =
compileProject(graph, cache)
cgenWriteModules()
if gCmd != cmdRun:
extccomp.callCCompiler(changeFileExt(gProjectFull, ""))
let proj = changeFileExt(gProjectFull, "")
extccomp.callCCompiler(proj)
extccomp.writeJsonBuildInstructions(proj)
proc commandCompileToJS(graph: ModuleGraph; cache: IdentCache) =
#incl(gGlobalOptions, optSafeCode)

View file

@ -48,7 +48,7 @@ type
errIndexOutOfBounds, errIndexTypesDoNotMatch, errBracketsInvalidForType,
errValueOutOfSetBounds, errFieldInitTwice, errFieldNotInit,
errExprXCannotBeCalled, errExprHasNoType, errExprXHasNoType,
errCastNotInSafeMode, errExprCannotBeCastedToX, errCommaOrParRiExpected,
errCastNotInSafeMode, errExprCannotBeCastToX, errCommaOrParRiExpected,
errCurlyLeOrParLeExpected, errSectionExpected, errRangeExpected,
errMagicOnlyInSystem, errPowerOfTwoExpected,
errStringMayNotBeEmpty, errCallConvExpected, errProcOnlyOneCallConv,
@ -229,7 +229,7 @@ const
errExprHasNoType: "expression has no type",
errExprXHasNoType: "expression \'$1\' has no type (or is ambiguous)",
errCastNotInSafeMode: "\'cast\' not allowed in safe mode",
errExprCannotBeCastedToX: "expression cannot be casted to $1",
errExprCannotBeCastToX: "expression cannot be cast to $1",
errCommaOrParRiExpected: "',' or ')' expected",
errCurlyLeOrParLeExpected: "\'{\' or \'(\' expected",
errSectionExpected: "section (\'type\', \'proc\', etc.) expected",

View file

@ -127,7 +127,7 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus =
discard
proc isCastable(dst, src: PType): bool =
## Checks whether the source type can be casted to the destination type.
## Checks whether the source type can be cast to the destination type.
## Casting is very unrestrictive; casts are allowed as long as
## castDest.size >= src.size, and typeAllowed(dst, skParam)
#const
@ -223,7 +223,7 @@ proc semCast(c: PContext, n: PNode): PNode =
addSon(result, copyTree(n.sons[0]))
addSon(result, semExprWithType(c, n.sons[1]))
if not isCastable(result.typ, result.sons[1].typ):
localError(result.info, errExprCannotBeCastedToX,
localError(result.info, errExprCannotBeCastToX,
typeToString(result.typ))
proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =

View file

@ -73,6 +73,10 @@ proc atomicTypeX(name: string; m: TMagic; t: PType; info: TLineInfo): PNode =
result = newSymNode(sym)
result.typ = t
proc atomicTypeX(s: PSym; info: TLineInfo): PNode =
result = newSymNode(s)
result.info = info
proc mapTypeToAstX(t: PType; info: TLineInfo;
inst=false; allowRecursionX=false): PNode
@ -103,6 +107,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
inst=false; allowRecursionX=false): PNode =
var allowRecursion = allowRecursionX
template atomicType(name, m): untyped = atomicTypeX(name, m, t, info)
template atomicType(s): untyped = atomicTypeX(s, info)
template mapTypeToAst(t,info): untyped = mapTypeToAstX(t, info, inst)
template mapTypeToAstR(t,info): untyped = mapTypeToAstX(t, info, inst, true)
template mapTypeToAst(t,i,info): untyped =
@ -125,7 +130,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
if allowRecursion: # getTypeImpl behavior: turn off recursion
allowRecursion = false
else: # getTypeInst behavior: return symbol
return atomicType(t.sym.name.s, t.sym.magic)
return atomicType(t.sym)
case t.kind
of tyNone: result = atomicType("none", mNone)
@ -180,9 +185,9 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
if allowRecursion or t.sym == nil:
result = mapTypeToBracket("distinct", mDistinct, t, info)
else:
result = atomicType(t.sym.name.s, t.sym.magic)
result = atomicType(t.sym)
of tyGenericParam, tyForward:
result = atomicType(t.sym.name.s, t.sym.magic)
result = atomicType(t.sym)
of tyObject:
if inst:
result = newNodeX(nkObjectTy)
@ -206,7 +211,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
result.add mapTypeToAst(t.sons[0], info)
result.add copyTree(t.n)
else:
result = atomicType(t.sym.name.s, t.sym.magic)
result = atomicType(t.sym)
of tyEnum:
result = newNodeIT(nkEnumTy, if t.n.isNil: info else: t.n.info, t)
result.add copyTree(t.n)