cleaned up configuration file handling and documented the new behaviour
This commit is contained in:
parent
59543ef0a3
commit
fc9fdc2b9d
19 changed files with 157 additions and 152 deletions
|
|
@ -862,7 +862,7 @@ proc newModule(module: PSym, filename: string): BModule =
|
||||||
proc registerTypeInfoModule() =
|
proc registerTypeInfoModule() =
|
||||||
const moduleName = "nim__dat"
|
const moduleName = "nim__dat"
|
||||||
var s = NewSym(skModule, getIdent(moduleName), nil)
|
var s = NewSym(skModule, getIdent(moduleName), nil)
|
||||||
gNimDat = rawNewModule(s, (options.projectPath / moduleName) & ".nim")
|
gNimDat = rawNewModule(s, (options.gProjectPath / moduleName) & ".nim")
|
||||||
gNimDat.PreventStackTrace = true
|
gNimDat.PreventStackTrace = true
|
||||||
addPendingModule(gNimDat)
|
addPendingModule(gNimDat)
|
||||||
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n",
|
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n",
|
||||||
|
|
|
||||||
|
|
@ -37,37 +37,28 @@ proc getCommandLineDesc(): string =
|
||||||
result = (HelpMessage % [VersionAsString, platform.os[platform.hostOS].name,
|
result = (HelpMessage % [VersionAsString, platform.os[platform.hostOS].name,
|
||||||
cpu[platform.hostCPU].name]) & Usage
|
cpu[platform.hostCPU].name]) & Usage
|
||||||
|
|
||||||
var
|
|
||||||
helpWritten: bool # BUGFIX 19
|
|
||||||
versionWritten: bool
|
|
||||||
advHelpWritten: bool
|
|
||||||
|
|
||||||
proc HelpOnError(pass: TCmdLinePass) =
|
proc HelpOnError(pass: TCmdLinePass) =
|
||||||
if (pass == passCmd1) and not helpWritten:
|
if pass == passCmd1:
|
||||||
# BUGFIX 19
|
|
||||||
MsgWriteln(getCommandLineDesc())
|
MsgWriteln(getCommandLineDesc())
|
||||||
helpWritten = true
|
|
||||||
quit(0)
|
quit(0)
|
||||||
|
|
||||||
proc writeAdvancedUsage(pass: TCmdLinePass) =
|
proc writeAdvancedUsage(pass: TCmdLinePass) =
|
||||||
if (pass == passCmd1) and not advHelpWritten:
|
if pass == passCmd1:
|
||||||
# BUGFIX 19
|
|
||||||
MsgWriteln(`%`(HelpMessage, [VersionAsString,
|
MsgWriteln(`%`(HelpMessage, [VersionAsString,
|
||||||
platform.os[platform.hostOS].name,
|
platform.os[platform.hostOS].name,
|
||||||
cpu[platform.hostCPU].name]) & AdvancedUsage)
|
cpu[platform.hostCPU].name]) & AdvancedUsage)
|
||||||
advHelpWritten = true
|
|
||||||
helpWritten = true
|
|
||||||
quit(0)
|
quit(0)
|
||||||
|
|
||||||
proc writeVersionInfo(pass: TCmdLinePass) =
|
proc writeVersionInfo(pass: TCmdLinePass) =
|
||||||
if (pass == passCmd1) and not versionWritten:
|
if pass == passCmd1:
|
||||||
versionWritten = true
|
|
||||||
helpWritten = true
|
|
||||||
MsgWriteln(`%`(HelpMessage, [VersionAsString,
|
MsgWriteln(`%`(HelpMessage, [VersionAsString,
|
||||||
platform.os[platform.hostOS].name,
|
platform.os[platform.hostOS].name,
|
||||||
cpu[platform.hostCPU].name]))
|
cpu[platform.hostCPU].name]))
|
||||||
quit(0)
|
quit(0)
|
||||||
|
|
||||||
|
var
|
||||||
|
helpWritten: bool
|
||||||
|
|
||||||
proc writeCommandLineUsage() =
|
proc writeCommandLineUsage() =
|
||||||
if not helpWritten:
|
if not helpWritten:
|
||||||
MsgWriteln(getCommandLineDesc())
|
MsgWriteln(getCommandLineDesc())
|
||||||
|
|
@ -197,8 +188,8 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
|
||||||
proc processPath(path: string): string =
|
proc processPath(path: string): string =
|
||||||
result = UnixToNativePath(path % ["nimrod", getPrefixDir(), "lib", libpath,
|
result = UnixToNativePath(path % ["nimrod", getPrefixDir(), "lib", libpath,
|
||||||
"home", removeTrailingDirSep(os.getHomeDir()),
|
"home", removeTrailingDirSep(os.getHomeDir()),
|
||||||
"projectname", options.projectName,
|
"projectname", options.gProjectName,
|
||||||
"projectpath", options.projectPath])
|
"projectpath", options.gProjectPath])
|
||||||
|
|
||||||
proc addPath(path: string, info: TLineInfo) =
|
proc addPath(path: string, info: TLineInfo) =
|
||||||
if not contains(options.searchPaths, path):
|
if not contains(options.searchPaths, path):
|
||||||
|
|
@ -246,8 +237,8 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||||
options.outFile = arg
|
options.outFile = arg
|
||||||
of "mainmodule", "m":
|
of "mainmodule", "m":
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
projectName = arg
|
gProjectName = arg
|
||||||
projectFullPath = projectPath/projectName
|
gProjectFull = gProjectPath / gProjectName
|
||||||
of "define", "d":
|
of "define", "d":
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
DefineSymbol(arg)
|
DefineSymbol(arg)
|
||||||
|
|
@ -433,6 +424,9 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||||
of "skipusercfg":
|
of "skipusercfg":
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
incl(gGlobalOptions, optSkipUserConfigFile)
|
incl(gGlobalOptions, optSkipUserConfigFile)
|
||||||
|
of "skipparentcfg":
|
||||||
|
expectNoArg(switch, arg, pass, info)
|
||||||
|
incl(gGlobalOptions, optSkipParentConfigFiles)
|
||||||
of "genscript":
|
of "genscript":
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
incl(gGlobalOptions, optGenScript)
|
incl(gGlobalOptions, optGenScript)
|
||||||
|
|
|
||||||
|
|
@ -865,13 +865,13 @@ proc writeOutput(d: PDoc, filename, outExt: string) =
|
||||||
writeRope(content, getOutFile(filename, outExt))
|
writeRope(content, getOutFile(filename, outExt))
|
||||||
|
|
||||||
proc CommandDoc =
|
proc CommandDoc =
|
||||||
var ast = parseFile(addFileExt(projectFullPath, nimExt))
|
var ast = parseFile(addFileExt(gProjectFull, nimExt))
|
||||||
if ast == nil: return
|
if ast == nil: return
|
||||||
var d = newDocumentor(projectFullPath)
|
var d = newDocumentor(gProjectFull)
|
||||||
initIndexFile(d)
|
initIndexFile(d)
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
generateDoc(d, ast)
|
generateDoc(d, ast)
|
||||||
writeOutput(d, projectFullPath, HtmlExt)
|
writeOutput(d, gProjectFull, HtmlExt)
|
||||||
generateIndex(d)
|
generateIndex(d)
|
||||||
|
|
||||||
proc CommandRstAux(filename, outExt: string) =
|
proc CommandRstAux(filename, outExt: string) =
|
||||||
|
|
@ -884,9 +884,9 @@ proc CommandRstAux(filename, outExt: string) =
|
||||||
generateIndex(d)
|
generateIndex(d)
|
||||||
|
|
||||||
proc CommandRst2Html =
|
proc CommandRst2Html =
|
||||||
CommandRstAux(projectFullPath, HtmlExt)
|
CommandRstAux(gProjectFull, HtmlExt)
|
||||||
|
|
||||||
proc CommandRst2TeX =
|
proc CommandRst2TeX =
|
||||||
splitter = "\\-"
|
splitter = "\\-"
|
||||||
CommandRstAux(projectFullPath, TexExt)
|
CommandRstAux(gProjectFull, TexExt)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -305,16 +305,14 @@ var
|
||||||
cExt* = "c" # extension of generated C/C++ files
|
cExt* = "c" # extension of generated C/C++ files
|
||||||
# (can be changed to .cpp later)
|
# (can be changed to .cpp later)
|
||||||
|
|
||||||
cIncludes*: seq[string] = @[] # list of directories to search for included files
|
cIncludes*: seq[string] = @[] # directories to search for included files
|
||||||
cLibs*: seq[string] = @[] # list of directories to search for lib files
|
cLibs*: seq[string] = @[] # directories to search for lib files
|
||||||
cLinkedLibs*: seq[string] = @[] # list of libraries to link
|
cLinkedLibs*: seq[string] = @[] # libraries to link
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
when defined(windows):
|
proc libNameTmpl(): string {.inline.} =
|
||||||
var libNameTmpl = "$1.lib"
|
result = if targetOS == osWindows: "$1.lib" else: "lib$1.a"
|
||||||
else:
|
|
||||||
var libNameTmpl = "lib$1.a"
|
|
||||||
|
|
||||||
var
|
var
|
||||||
toLink, toCompile, externalToCompile: TLinkedList
|
toLink, toCompile, externalToCompile: TLinkedList
|
||||||
|
|
@ -431,43 +429,41 @@ const
|
||||||
var fileCounter: int
|
var fileCounter: int
|
||||||
|
|
||||||
proc add(s: var string, many: openarray[string]) =
|
proc add(s: var string, many: openarray[string]) =
|
||||||
# XXX: is there something like C++'s reserve?
|
s.add many.join
|
||||||
# We can use it here to avoid multiple reallocations
|
|
||||||
for x in items(many): s.add x
|
|
||||||
|
|
||||||
proc getCompileCFileCmd*(cfilename: string, isExternal: bool = false): string =
|
proc CFileSpecificOptions(cfilename: string): string =
|
||||||
var
|
result = compileOptions
|
||||||
cfile, objfile, options, includeCmd, compilePattern, key, trunk, exe: string
|
var trunk = splitFile(cfilename).name
|
||||||
var c = ccompiler
|
|
||||||
options = compileOptions
|
|
||||||
trunk = splitFile(cfilename).name
|
|
||||||
if optCDebug in gGlobalOptions:
|
if optCDebug in gGlobalOptions:
|
||||||
key = trunk & ".debug"
|
var key = trunk & ".debug"
|
||||||
if existsConfigVar(key): addOpt(options, getConfigVar(key))
|
if existsConfigVar(key): addOpt(result, getConfigVar(key))
|
||||||
else: addOpt(options, getDebug(c))
|
else: addOpt(result, getDebug(ccompiler))
|
||||||
if (optOptimizeSpeed in gOptions):
|
if optOptimizeSpeed in gOptions:
|
||||||
#if ((fileCounter >= specialFileA) and (fileCounter <= specialFileB)) then
|
var key = trunk & ".speed"
|
||||||
key = trunk & ".speed"
|
if existsConfigVar(key): addOpt(result, getConfigVar(key))
|
||||||
if existsConfigVar(key): addOpt(options, getConfigVar(key))
|
else: addOpt(result, getOptSpeed(ccompiler))
|
||||||
else: addOpt(options, getOptSpeed(c))
|
|
||||||
elif optOptimizeSize in gOptions:
|
elif optOptimizeSize in gOptions:
|
||||||
key = trunk & ".size"
|
var key = trunk & ".size"
|
||||||
if existsConfigVar(key): addOpt(options, getConfigVar(key))
|
if existsConfigVar(key): addOpt(result, getConfigVar(key))
|
||||||
else: addOpt(options, getOptSize(c))
|
else: addOpt(result, getOptSize(ccompiler))
|
||||||
key = trunk & ".always"
|
var key = trunk & ".always"
|
||||||
if existsConfigVar(key): addOpt(options, getConfigVar(key))
|
if existsConfigVar(key): addOpt(result, getConfigVar(key))
|
||||||
exe = cc[c].compilerExe
|
|
||||||
key = cc[c].name & ".exe"
|
proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
|
var c = ccompiler
|
||||||
|
var options = CFileSpecificOptions(cfilename)
|
||||||
|
var exe = cc[c].compilerExe
|
||||||
|
var key = cc[c].name & ".exe"
|
||||||
if existsConfigVar(key): exe = getConfigVar(key)
|
if existsConfigVar(key): exe = getConfigVar(key)
|
||||||
if targetOS == osWindows: exe = addFileExt(exe, "exe")
|
if targetOS == osWindows: exe = addFileExt(exe, "exe")
|
||||||
if optGenDynLib in gGlobalOptions and
|
if optGenDynLib in gGlobalOptions and
|
||||||
ospNeedsPIC in platform.OS[targetOS].props:
|
ospNeedsPIC in platform.OS[targetOS].props:
|
||||||
add(options, ' ' & cc[c].pic)
|
add(options, ' ' & cc[c].pic)
|
||||||
|
|
||||||
|
var includeCmd, compilePattern: string
|
||||||
if targetOS == platform.hostOS:
|
if targetOS == platform.hostOS:
|
||||||
# compute include paths:
|
# compute include paths:
|
||||||
includeCmd = cc[c].includeCmd # this is more complex than needed, but
|
includeCmd = cc[c].includeCmd & quoteIfContainsWhite(libpath)
|
||||||
# a workaround of a FPC bug...
|
|
||||||
add(includeCmd, quoteIfContainsWhite(libpath))
|
|
||||||
|
|
||||||
for includeDir in items(cIncludes):
|
for includeDir in items(cIncludes):
|
||||||
includeCmd.add cc[c].includeCmd, includeDir.quoteIfContainsWhite
|
includeCmd.add cc[c].includeCmd, includeDir.quoteIfContainsWhite
|
||||||
|
|
@ -476,15 +472,17 @@ proc getCompileCFileCmd*(cfilename: string, isExternal: bool = false): string =
|
||||||
else:
|
else:
|
||||||
includeCmd = ""
|
includeCmd = ""
|
||||||
compilePattern = cc[c].compilerExe
|
compilePattern = cc[c].compilerExe
|
||||||
if targetOS == platform.hostOS: cfile = cfilename
|
|
||||||
else: cfile = extractFileName(cfilename)
|
# XXX fix the grammar finally, we need multi-line if expressions:
|
||||||
if not isExternal or targetOS != platform.hostOS: objfile = toObjFile(cfile)
|
var cfile = if targetOS == platform.hostOS: cfilename else: extractFileName(
|
||||||
else: objfile = completeCFilePath(toObjFile(cfile))
|
cfilename)
|
||||||
|
var objfile = if not isExternal or targetOS != platform.hostOS: toObjFile(
|
||||||
|
cfile) else: completeCFilePath(toObjFile(cfile))
|
||||||
cfile = quoteIfContainsWhite(AddFileExt(cfile, cExt))
|
cfile = quoteIfContainsWhite(AddFileExt(cfile, cExt))
|
||||||
objfile = quoteIfContainsWhite(objfile)
|
objfile = quoteIfContainsWhite(objfile)
|
||||||
result = quoteIfContainsWhite(`%`(compilePattern, ["file", cfile, "objfile",
|
result = quoteIfContainsWhite(compilePattern % [
|
||||||
objfile, "options", options, "include", includeCmd, "nimrod",
|
"file", cfile, "objfile", objfile, "options", options,
|
||||||
getPrefixDir(), "lib", libpath]))
|
"include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
|
||||||
add(result, ' ')
|
add(result, ' ')
|
||||||
addf(result, cc[c].compileTmpl, [
|
addf(result, cc[c].compileTmpl, [
|
||||||
"file", cfile, "objfile", objfile,
|
"file", cfile, "objfile", objfile,
|
||||||
|
|
@ -498,9 +496,9 @@ proc CompileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
|
||||||
while it != nil:
|
while it != nil:
|
||||||
inc(fileCounter) # call the C compiler for the .c file:
|
inc(fileCounter) # call the C compiler for the .c file:
|
||||||
var compileCmd = getCompileCFileCmd(it.data, isExternal)
|
var compileCmd = getCompileCFileCmd(it.data, isExternal)
|
||||||
if not (optCompileOnly in gGlobalOptions):
|
if optCompileOnly notin gGlobalOptions:
|
||||||
add(cmds, compileCmd)
|
add(cmds, compileCmd)
|
||||||
if (optGenScript in gGlobalOptions):
|
if optGenScript in gGlobalOptions:
|
||||||
app(script, compileCmd)
|
app(script, compileCmd)
|
||||||
app(script, tnl)
|
app(script, tnl)
|
||||||
it = PStrEntry(it.next)
|
it = PStrEntry(it.next)
|
||||||
|
|
@ -522,7 +520,7 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
var res = 0
|
var res = 0
|
||||||
if gNumberOfProcessors <= 1:
|
if gNumberOfProcessors <= 1:
|
||||||
for i in countup(0, high(cmds)): res = max(execCmd(cmds[i]), res)
|
for i in countup(0, high(cmds)): res = max(execCmd(cmds[i]), res)
|
||||||
elif (optListCmd in gGlobalOptions) or (gVerbosity > 0):
|
elif optListCmd in gGlobalOptions or gVerbosity > 0:
|
||||||
res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
|
res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
|
||||||
gNumberOfProcessors)
|
gNumberOfProcessors)
|
||||||
else:
|
else:
|
||||||
|
|
@ -535,26 +533,25 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
var objfiles = ""
|
var objfiles = ""
|
||||||
while it != nil:
|
while it != nil:
|
||||||
add(objfiles, ' ')
|
add(objfiles, ' ')
|
||||||
if targetOS == platform.hostOS:
|
add(objfiles, quoteIfContainsWhite(
|
||||||
add(objfiles, quoteIfContainsWhite(addFileExt(it.data, cc[ccompiler].objExt)))
|
addFileExt(it.data, cc[ccompiler].objExt)))
|
||||||
else:
|
|
||||||
add(objfiles, quoteIfContainsWhite(addFileExt(it.data, cc[ccompiler].objExt)))
|
|
||||||
it = PStrEntry(it.next)
|
it = PStrEntry(it.next)
|
||||||
|
|
||||||
if optGenStaticLib in gGlobalOptions:
|
if optGenStaticLib in gGlobalOptions:
|
||||||
linkcmd = cc[c].buildLib % ["libfile", (libNameTmpl % projectName), "objfiles", objfiles]
|
linkcmd = cc[c].buildLib % ["libfile", (libNameTmpl() % gProjectName),
|
||||||
|
"objfiles", objfiles]
|
||||||
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
||||||
else:
|
else:
|
||||||
var linkerExe = getConfigVar(cc[c].name & ".linkerexe")
|
var linkerExe = getConfigVar(cc[c].name & ".linkerexe")
|
||||||
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
||||||
if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe")
|
if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe")
|
||||||
if (platform.hostOS != targetOS): linkCmd = quoteIfContainsWhite(linkerExe)
|
if platform.hostOS != targetOS: linkCmd = quoteIfContainsWhite(linkerExe)
|
||||||
else: linkCmd = quoteIfContainsWhite(JoinPath(ccompilerpath, linkerExe))
|
else: linkCmd = quoteIfContainsWhite(JoinPath(ccompilerpath, linkerExe))
|
||||||
if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui
|
if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui
|
||||||
else: buildGui = ""
|
else: buildGui = ""
|
||||||
var exefile: string
|
var exefile: string
|
||||||
if optGenDynLib in gGlobalOptions:
|
if optGenDynLib in gGlobalOptions:
|
||||||
exefile = `%`(platform.os[targetOS].dllFrmt, [splitFile(projectFile).name])
|
exefile = platform.os[targetOS].dllFrmt % [splitFile(projectFile).name]
|
||||||
buildDll = cc[c].buildDll
|
buildDll = cc[c].buildDll
|
||||||
else:
|
else:
|
||||||
exefile = splitFile(projectFile).name & platform.os[targetOS].exeExt
|
exefile = splitFile(projectFile).name & platform.os[targetOS].exeExt
|
||||||
|
|
@ -596,4 +593,5 @@ proc writeMapping*(gSymbolMapping: PRope) =
|
||||||
app(code, genMappingFiles(toCompile))
|
app(code, genMappingFiles(toCompile))
|
||||||
app(code, genMappingFiles(externalToCompile))
|
app(code, genMappingFiles(externalToCompile))
|
||||||
appf(code, "[Symbols]$n$1", [gSymbolMapping])
|
appf(code, "[Symbols]$n$1", [gSymbolMapping])
|
||||||
WriteRope(code, joinPath(projectPath, "mapping.txt"))
|
WriteRope(code, joinPath(gProjectPath, "mapping.txt"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ proc CompileModule(filename: string, flags: TSymFlags): PSym =
|
||||||
result.id = getID()
|
result.id = getID()
|
||||||
processModule(result, f, nil, rd)
|
processModule(result, f, nil, rd)
|
||||||
|
|
||||||
proc CompileProject(projectFile = projectFullPath) =
|
proc CompileProject(projectFile = gProjectFull) =
|
||||||
discard CompileModule(options.libpath / "system", {sfSystemModule})
|
discard CompileModule(options.libpath / "system", {sfSystemModule})
|
||||||
discard CompileModule(projectFile, {sfMainModule})
|
discard CompileModule(projectFile, {sfMainModule})
|
||||||
|
|
||||||
|
|
@ -95,9 +95,9 @@ proc CommandGenDepend =
|
||||||
registerPass(genDependPass())
|
registerPass(genDependPass())
|
||||||
registerPass(cleanupPass())
|
registerPass(cleanupPass())
|
||||||
compileProject()
|
compileProject()
|
||||||
generateDot(projectFullPath)
|
generateDot(gProjectFull)
|
||||||
execExternalProgram("dot -Tpng -o" & changeFileExt(projectFullPath, "png") &
|
execExternalProgram("dot -Tpng -o" & changeFileExt(gProjectFull, "png") &
|
||||||
' ' & changeFileExt(projectFullPath, "dot"))
|
' ' & changeFileExt(gProjectFull, "dot"))
|
||||||
|
|
||||||
proc CommandCheck =
|
proc CommandCheck =
|
||||||
msgs.gErrorMax = high(int) # do not stop after first error
|
msgs.gErrorMax = high(int) # do not stop after first error
|
||||||
|
|
@ -112,7 +112,7 @@ proc CommandCompileToC =
|
||||||
#registerPass(cleanupPass())
|
#registerPass(cleanupPass())
|
||||||
compileProject()
|
compileProject()
|
||||||
if gCmd != cmdRun:
|
if gCmd != cmdRun:
|
||||||
extccomp.CallCCompiler(changeFileExt(projectFullPath, ""))
|
extccomp.CallCCompiler(changeFileExt(gProjectFull, ""))
|
||||||
|
|
||||||
when has_LLVM_Backend:
|
when has_LLVM_Backend:
|
||||||
proc CommandCompileToLLVM =
|
proc CommandCompileToLLVM =
|
||||||
|
|
@ -177,14 +177,14 @@ proc CommandSuggest =
|
||||||
compileProject()
|
compileProject()
|
||||||
|
|
||||||
proc wantMainModule =
|
proc wantMainModule =
|
||||||
if projectFullPath.len == 0:
|
if gProjectFull.len == 0:
|
||||||
Fatal(newLineInfo("command line", 1, 1), errCommandExpectsFilename)
|
Fatal(newLineInfo("command line", 1, 1), errCommandExpectsFilename)
|
||||||
|
|
||||||
proc MainCommand =
|
proc MainCommand =
|
||||||
appendStr(searchPaths, options.libpath)
|
appendStr(searchPaths, options.libpath)
|
||||||
if projectFullPath.len != 0:
|
if gProjectFull.len != 0:
|
||||||
# current path is dalways looked first for modules
|
# current path is always looked first for modules
|
||||||
prependStr(searchPaths, projectPath)
|
prependStr(searchPaths, gProjectPath)
|
||||||
setID(100)
|
setID(100)
|
||||||
passes.gIncludeFile = syntaxes.parseFile
|
passes.gIncludeFile = syntaxes.parseFile
|
||||||
passes.gImportModule = importModule
|
passes.gImportModule = importModule
|
||||||
|
|
@ -259,7 +259,7 @@ proc MainCommand =
|
||||||
of "parse":
|
of "parse":
|
||||||
gCmd = cmdParse
|
gCmd = cmdParse
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
discard parseFile(addFileExt(projectFullPath, nimExt))
|
discard parseFile(addFileExt(gProjectFull, nimExt))
|
||||||
of "scan":
|
of "scan":
|
||||||
gCmd = cmdScan
|
gCmd = cmdScan
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ type
|
||||||
errUser,
|
errUser,
|
||||||
warnCannotOpenFile,
|
warnCannotOpenFile,
|
||||||
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
|
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
|
||||||
warnDeprecated,
|
warnDeprecated, warnConfigDeprecated,
|
||||||
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
||||||
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
||||||
warnXisPassedToProcVar, warnDerefDeprecated, warnAnalysisLoophole,
|
warnXisPassedToProcVar, warnDerefDeprecated, warnAnalysisLoophole,
|
||||||
|
|
@ -328,6 +328,7 @@ const
|
||||||
warnXIsNeverRead: "\'$1\' is never read [XIsNeverRead]",
|
warnXIsNeverRead: "\'$1\' is never read [XIsNeverRead]",
|
||||||
warnXmightNotBeenInit: "\'$1\' might not have been initialized [XmightNotBeenInit]",
|
warnXmightNotBeenInit: "\'$1\' might not have been initialized [XmightNotBeenInit]",
|
||||||
warnDeprecated: "\'$1\' is deprecated [Deprecated]",
|
warnDeprecated: "\'$1\' is deprecated [Deprecated]",
|
||||||
|
warnConfigDeprecated: "config file '$1' is deprecated [ConfigDeprecated]",
|
||||||
warnSmallLshouldNotBeUsed: "\'l\' should not be used as an identifier; may look like \'1\' (one) [SmallLshouldNotBeUsed]",
|
warnSmallLshouldNotBeUsed: "\'l\' should not be used as an identifier; may look like \'1\' (one) [SmallLshouldNotBeUsed]",
|
||||||
warnUnknownMagic: "unknown magic \'$1\' might crash the compiler [UnknownMagic]",
|
warnUnknownMagic: "unknown magic \'$1\' might crash the compiler [UnknownMagic]",
|
||||||
warnRedefinitionOfLabel: "redefinition of label \'$1\' [RedefinitionOfLabel]",
|
warnRedefinitionOfLabel: "redefinition of label \'$1\' [RedefinitionOfLabel]",
|
||||||
|
|
@ -356,9 +357,10 @@ const
|
||||||
hintUser: "$1 [User]"]
|
hintUser: "$1 [User]"]
|
||||||
|
|
||||||
const
|
const
|
||||||
WarningsToStr*: array[0..16, string] = ["CannotOpenFile", "OctalEscape",
|
WarningsToStr*: array[0..17, string] = ["CannotOpenFile", "OctalEscape",
|
||||||
"XIsNeverRead", "XmightNotBeenInit",
|
"XIsNeverRead", "XmightNotBeenInit",
|
||||||
"Deprecated", "SmallLshouldNotBeUsed", "UnknownMagic",
|
"Deprecated", "ConfigDeprecated",
|
||||||
|
"SmallLshouldNotBeUsed", "UnknownMagic",
|
||||||
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
||||||
"CommentXIgnored", "XisPassedToProcVar", "DerefDeprecated",
|
"CommentXIgnored", "XisPassedToProcVar", "DerefDeprecated",
|
||||||
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", "User"]
|
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", "User"]
|
||||||
|
|
@ -443,7 +445,7 @@ proc includeFilename*(f: string): int =
|
||||||
|
|
||||||
filenames.add((filename: f, fullpath: fullpath))
|
filenames.add((filename: f, fullpath: fullpath))
|
||||||
|
|
||||||
proc newLineInfo*(filename: string, line, col: int): TLineInfo =
|
proc newLineInfo(filename: string, line, col: int): TLineInfo =
|
||||||
result.fileIndex = includeFilename(filename)
|
result.fileIndex = includeFilename(filename)
|
||||||
result.line = int16(line)
|
result.line = int16(line)
|
||||||
result.col = int16(col)
|
result.col = int16(col)
|
||||||
|
|
|
||||||
|
|
@ -194,9 +194,9 @@ proc readConfigFile(filename: string) =
|
||||||
L: TLexer
|
L: TLexer
|
||||||
tok: TToken
|
tok: TToken
|
||||||
stream: PLLStream
|
stream: PLLStream
|
||||||
initToken(tok)
|
|
||||||
stream = LLStreamOpen(filename, fmRead)
|
stream = LLStreamOpen(filename, fmRead)
|
||||||
if stream != nil:
|
if stream != nil:
|
||||||
|
initToken(tok)
|
||||||
openLexer(L, filename, stream)
|
openLexer(L, filename, stream)
|
||||||
tok.tokType = tkEof # to avoid a pointless warning
|
tok.tokType = tkEof # to avoid a pointless warning
|
||||||
confTok(L, tok) # read in the first token
|
confTok(L, tok) # read in the first token
|
||||||
|
|
@ -214,7 +214,7 @@ proc getSystemConfigPath(filename: string): string =
|
||||||
result = joinPath([getPrefixDir(), "config", filename])
|
result = joinPath([getPrefixDir(), "config", filename])
|
||||||
if not ExistsFile(result): result = "/etc/" & filename
|
if not ExistsFile(result): result = "/etc/" & filename
|
||||||
|
|
||||||
proc LoadConfigs*(cfg = "nimrod.cfg") =
|
proc LoadConfigs*(cfg: string) =
|
||||||
# set default value (can be overwritten):
|
# set default value (can be overwritten):
|
||||||
if libpath == "":
|
if libpath == "":
|
||||||
# choose default libpath:
|
# choose default libpath:
|
||||||
|
|
@ -224,12 +224,21 @@ proc LoadConfigs*(cfg = "nimrod.cfg") =
|
||||||
else: libpath = joinPath(prefix, "lib")
|
else: libpath = joinPath(prefix, "lib")
|
||||||
|
|
||||||
if optSkipConfigFile notin gGlobalOptions:
|
if optSkipConfigFile notin gGlobalOptions:
|
||||||
readConfigFile getSystemConfigPath(cfg)
|
readConfigFile(getSystemConfigPath(cfg))
|
||||||
|
|
||||||
if optSkipUserConfigFile notin gGlobalOptions:
|
if optSkipUserConfigFile notin gGlobalOptions:
|
||||||
readConfigFile getUserConfigPath(cfg)
|
readConfigFile(getUserConfigPath(cfg))
|
||||||
|
|
||||||
if optSkipProjConfigFile notin gGlobalOptions and projectPath != "":
|
var pd = if gProjectPath.len > 0: gProjectPath else: getCurrentDir()
|
||||||
for dir in parentDirs(projectPath, fromRoot = true):
|
if optSkipParentConfigFiles notin gGlobalOptions:
|
||||||
readConfigFile(dir/cfg)
|
for dir in parentDirs(pd, fromRoot=true, inclusive=false):
|
||||||
|
readConfigFile(dir / cfg)
|
||||||
|
|
||||||
|
if optSkipProjConfigFile notin gGlobalOptions and gProjectName.len != 0:
|
||||||
|
readConfigFile(pd / cfg)
|
||||||
|
|
||||||
|
var conffile = changeFileExt(gProjectFull, "cfg")
|
||||||
|
if conffile != pd / cfg and existsFile(conffile):
|
||||||
|
readConfigFile(conffile)
|
||||||
|
rawMessage(warnConfigDeprecated, conffile)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ proc ProcessCmdLine(pass: TCmdLinePass) =
|
||||||
else:
|
else:
|
||||||
options.commandArgs.add p.key
|
options.commandArgs.add p.key
|
||||||
|
|
||||||
if options.projectName == "":
|
if options.gProjectName == "":
|
||||||
# support UNIX style filenames anywhere for portable build scripts:
|
# support UNIX style filenames anywhere for portable build scripts:
|
||||||
options.projectName = unixToNativePath(p.key)
|
options.gProjectName = unixToNativePath(p.key)
|
||||||
arguments = cmdLineRest(p)
|
arguments = cmdLineRest(p)
|
||||||
|
|
||||||
if pass == passCmd2:
|
if pass == passCmd2:
|
||||||
|
|
@ -67,17 +67,17 @@ proc HandleCmdLine() =
|
||||||
else:
|
else:
|
||||||
# Process command line arguments:
|
# Process command line arguments:
|
||||||
ProcessCmdLine(passCmd1)
|
ProcessCmdLine(passCmd1)
|
||||||
if projectName != "":
|
if gProjectName != "":
|
||||||
try:
|
try:
|
||||||
projectFullPath = expandFilename(projectName)
|
gProjectFull = expandFilename(gProjectName)
|
||||||
except EOS:
|
except EOS:
|
||||||
projectFullPath = projectName
|
gProjectFull = gProjectName
|
||||||
var p = splitFile(projectFullPath)
|
var p = splitFile(gProjectFull)
|
||||||
projectPath = p.dir
|
gProjectPath = p.dir
|
||||||
projectName = p.name
|
gProjectName = p.name
|
||||||
else:
|
else:
|
||||||
projectPath = getCurrentDir()
|
gProjectPath = getCurrentDir()
|
||||||
LoadConfigs() # load all config files
|
LoadConfigs(DefaultConfig) # load all config files
|
||||||
# now process command line arguments again, because some options in the
|
# now process command line arguments again, because some options in the
|
||||||
# command line can overwite the config file's settings
|
# command line can overwite the config file's settings
|
||||||
extccomp.initVars()
|
extccomp.initVars()
|
||||||
|
|
@ -93,7 +93,7 @@ proc HandleCmdLine() =
|
||||||
formatFloat(epochTime() - start, ffDecimal, 3)])
|
formatFloat(epochTime() - start, ffDecimal, 3)])
|
||||||
if optRun in gGlobalOptions:
|
if optRun in gGlobalOptions:
|
||||||
var ex = quoteIfContainsWhite(
|
var ex = quoteIfContainsWhite(
|
||||||
changeFileExt(projectFullPath, "").prependCurDir)
|
changeFileExt(gProjectFull, "").prependCurDir)
|
||||||
execExternalProgram(ex & ' ' & arguments)
|
execExternalProgram(ex & ' ' & arguments)
|
||||||
|
|
||||||
#GC_disableMarkAndSweep()
|
#GC_disableMarkAndSweep()
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ type # please make sure we have under 32 options
|
||||||
optSkipConfigFile, # skip the general config file
|
optSkipConfigFile, # skip the general config file
|
||||||
optSkipProjConfigFile, # skip the project's config file
|
optSkipProjConfigFile, # skip the project's config file
|
||||||
optSkipUserConfigFile, # skip the users's config file
|
optSkipUserConfigFile, # skip the users's config file
|
||||||
|
optSkipParentConfigFiles, # skip parent dir's config files
|
||||||
optNoMain, # do not generate a "main" proc
|
optNoMain, # do not generate a "main" proc
|
||||||
optThreads, # support for multi-threading
|
optThreads, # support for multi-threading
|
||||||
optStdout, # output to stdout
|
optStdout, # output to stdout
|
||||||
|
|
@ -93,6 +94,7 @@ const
|
||||||
HtmlExt* = "html"
|
HtmlExt* = "html"
|
||||||
TexExt* = "tex"
|
TexExt* = "tex"
|
||||||
IniExt* = "ini"
|
IniExt* = "ini"
|
||||||
|
DefaultConfig* = "nimrod.cfg"
|
||||||
DocConfig* = "nimdoc.cfg"
|
DocConfig* = "nimdoc.cfg"
|
||||||
DocTexConfig* = "nimdoc.tex.cfg"
|
DocTexConfig* = "nimdoc.tex.cfg"
|
||||||
|
|
||||||
|
|
@ -100,9 +102,9 @@ const
|
||||||
var
|
var
|
||||||
gConfigVars* = newStringTable(modeStyleInsensitive)
|
gConfigVars* = newStringTable(modeStyleInsensitive)
|
||||||
libpath* = ""
|
libpath* = ""
|
||||||
projectName* = "" # holds a name like `nimrod'
|
gProjectName* = "" # holds a name like 'nimrod'
|
||||||
projectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/
|
gProjectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/
|
||||||
projectFullPath* = "" # projectPath/projectName
|
gProjectFull* = "" # projectPath/projectName
|
||||||
nimcacheDir* = ""
|
nimcacheDir* = ""
|
||||||
command* = "" # the main command (e.g. cc, check, scan, etc)
|
command* = "" # the main command (e.g. cc, check, scan, etc)
|
||||||
commandArgs*: seq[string] = @[] # any arguments after the main command
|
commandArgs*: seq[string] = @[] # any arguments after the main command
|
||||||
|
|
@ -117,7 +119,7 @@ proc mainCommandArg*: string =
|
||||||
if commandArgs.len > 0:
|
if commandArgs.len > 0:
|
||||||
result = commandArgs[0]
|
result = commandArgs[0]
|
||||||
else:
|
else:
|
||||||
result = projectName
|
result = gProjectName
|
||||||
|
|
||||||
proc existsConfigVar*(key: string): bool =
|
proc existsConfigVar*(key: string): bool =
|
||||||
result = hasKey(gConfigVars, key)
|
result = hasKey(gConfigVars, key)
|
||||||
|
|
@ -136,7 +138,7 @@ proc getPrefixDir*(): string =
|
||||||
## gets the application directory
|
## gets the application directory
|
||||||
result = SplitPath(getAppDir()).head
|
result = SplitPath(getAppDir()).head
|
||||||
|
|
||||||
proc shortenDir(dir: string): string =
|
proc shortenDir*(dir: string): string =
|
||||||
## returns the interesting part of a dir
|
## returns the interesting part of a dir
|
||||||
var prefix = getPrefixDir() & dirSep
|
var prefix = getPrefixDir() & dirSep
|
||||||
if startsWith(dir, prefix):
|
if startsWith(dir, prefix):
|
||||||
|
|
@ -144,8 +146,7 @@ proc shortenDir(dir: string): string =
|
||||||
prefix = getCurrentDir() & dirSep
|
prefix = getCurrentDir() & dirSep
|
||||||
if startsWith(dir, prefix):
|
if startsWith(dir, prefix):
|
||||||
return substr(dir, len(prefix))
|
return substr(dir, len(prefix))
|
||||||
prefix = projectPath & dirSep #writeln(output, prefix);
|
prefix = gProjectPath & dirSep
|
||||||
#writeln(output, dir);
|
|
||||||
if startsWith(dir, prefix):
|
if startsWith(dir, prefix):
|
||||||
return substr(dir, len(prefix))
|
return substr(dir, len(prefix))
|
||||||
result = dir
|
result = dir
|
||||||
|
|
@ -157,7 +158,7 @@ proc removeTrailingDirSep*(path: string): string =
|
||||||
result = path
|
result = path
|
||||||
|
|
||||||
proc getGeneratedPath: string =
|
proc getGeneratedPath: string =
|
||||||
result = if nimcacheDir.len > 0: nimcacheDir else: projectPath.shortenDir /
|
result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
|
||||||
genSubDir
|
genSubDir
|
||||||
|
|
||||||
proc toGeneratedFile*(path, ext: string): string =
|
proc toGeneratedFile*(path, ext: string): string =
|
||||||
|
|
|
||||||
|
|
@ -836,7 +836,7 @@ proc handleSymbolFile(module: PSym, filename: string): PRodReader =
|
||||||
if optSymbolFiles notin gGlobalOptions:
|
if optSymbolFiles notin gGlobalOptions:
|
||||||
module.id = getID()
|
module.id = getID()
|
||||||
return nil
|
return nil
|
||||||
idgen.loadMaxIds(options.projectPath / options.projectName)
|
idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
|
||||||
|
|
||||||
discard checkDep(filename)
|
discard checkDep(filename)
|
||||||
var idx = getModuleIdx(filename)
|
var idx = getModuleIdx(filename)
|
||||||
|
|
|
||||||
|
|
@ -576,7 +576,7 @@ proc myClose(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.projectPath / options.projectName)
|
idgen.saveMaxIds(options.gProjectPath / options.gProjectName)
|
||||||
|
|
||||||
proc rodwritePass(): TPass =
|
proc rodwritePass(): TPass =
|
||||||
initPass(result)
|
initPass(result)
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,9 @@ Advanced options:
|
||||||
--taintMode:on|off turn taint mode on|off
|
--taintMode:on|off turn taint mode on|off
|
||||||
--symbolFiles:on|off turn symbol files on|off (experimental)
|
--symbolFiles:on|off turn symbol files on|off (experimental)
|
||||||
--skipCfg do not read the general configuration file
|
--skipCfg do not read the general configuration file
|
||||||
--skipProjCfg do not read the project's configuration file
|
|
||||||
--skipUserCfg do not read the user's configuration file
|
--skipUserCfg do not read the user's configuration file
|
||||||
|
--skipParentCfg do not read the parent dirs' configuration files
|
||||||
|
--skipProjCfg do not read the project's configuration file
|
||||||
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
||||||
--index:FILE use FILE to generate a documentation index file
|
--index:FILE use FILE to generate a documentation index file
|
||||||
--putenv:key=value set an environment variable
|
--putenv:key=value set an environment variable
|
||||||
|
|
|
||||||
|
|
@ -37,25 +37,21 @@ Advanced command line switches are:
|
||||||
.. include:: advopt.txt
|
.. include:: advopt.txt
|
||||||
|
|
||||||
|
|
||||||
Configuration file
|
Configuration files
|
||||||
------------------
|
-------------------
|
||||||
The default configuration file is ``nimrod.cfg``. The ``nimrod`` executable
|
|
||||||
looks for it in the following directories (in this order):
|
|
||||||
|
|
||||||
1. ``/home/$user/.config/nimrod.cfg`` (UNIX) or ``%APPDATA%/nimrod.cfg`` (Windows)
|
|
||||||
2. ``$nimrod/config/nimrod.cfg`` (UNIX), ``%NIMROD%/config/nimrod.cfg`` (Windows)
|
|
||||||
3. ``/etc/nimrod.cfg`` (UNIX)
|
|
||||||
|
|
||||||
The search stops as soon as a configuration file has been found. The reading
|
|
||||||
of ``nimrod.cfg`` can be suppressed by the ``--skipCfg`` command line option.
|
|
||||||
|
|
||||||
**Note:** The *project file name* is the name of the ``.nim`` file that is
|
**Note:** The *project file name* is the name of the ``.nim`` file that is
|
||||||
passed as a command line argument to the compiler.
|
passed as a command line argument to the compiler.
|
||||||
|
|
||||||
Configuration settings can be overwritten individually in a project specific
|
All configuration files have the name ``nimrod.cfg``. The ``nimrod``
|
||||||
configuration file that is read automatically. This specific file has to
|
executable processes configuration files in the following directories
|
||||||
be in the same directory as the project and be of the same name, except
|
(in this order; later files overwrite previous settings):
|
||||||
that its extension should be ``.cfg``.
|
|
||||||
|
1) ``$nimrod/config/nimrod.cfg``, ``/etc/nimrod.cfg`` (UNIX) or ``%NIMROD%/config/nimrod.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option.
|
||||||
|
2) ``/home/$user/.config/nimrod.cfg`` (UNIX) or ``%APPDATA%/nimrod.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option.
|
||||||
|
3) ``$parentDir/nimrod.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option.
|
||||||
|
4) ``$projectDir/nimrod.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option.
|
||||||
|
|
||||||
|
|
||||||
Command line settings have priority over configuration file settings.
|
Command line settings have priority over configuration file settings.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,3 +140,6 @@ proc rejectSpecialTests(r: var TResults, options: string) =
|
||||||
proc compileSpecialTests(r: var TResults, options: string) =
|
proc compileSpecialTests(r: var TResults, options: string) =
|
||||||
compileRodFiles(r, options)
|
compileRodFiles(r, options)
|
||||||
|
|
||||||
|
compileSingleTest(r, "compiler/c2nim/c2nim.nim", options)
|
||||||
|
compileSingleTest(r, "compiler/pas2nim/pas2nim.nim", options)
|
||||||
|
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -1,11 +1,10 @@
|
||||||
version 0.8.14
|
version 0.8.14
|
||||||
==============
|
==============
|
||||||
|
|
||||||
- bug: compiler uses full file names again
|
|
||||||
- implicit invokation of `items`/`pairs` seems nice
|
|
||||||
- warning for implicit openArray -> varargs convention
|
- warning for implicit openArray -> varargs convention
|
||||||
- implement explicit varargs; **but** ``len(varargs)`` problem remains!
|
- implement explicit varargs; **but** ``len(varargs)`` problem remains!
|
||||||
--> solve by implicit conversion from varargs to openarray
|
--> solve by implicit conversion from varargs to openarray
|
||||||
|
- implicit invokation of `items`/`pairs` seems nice
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,13 @@ Compiler Additions
|
||||||
directory for generated code.
|
directory for generated code.
|
||||||
- Added ``--cincludes:dir``, ``--clibdir:lib`` configuration options for
|
- Added ``--cincludes:dir``, ``--clibdir:lib`` configuration options for
|
||||||
modifying the C compiler's header/library search path in cross-platform way.
|
modifying the C compiler's header/library search path in cross-platform way.
|
||||||
- Added ``--clib:lib`` configuration options for specifying additional
|
- Added ``--clib:lib`` configuration option for specifying additional
|
||||||
C libraries to be linked.
|
C libraries to be linked.
|
||||||
- Added ``--mainmodule:file`` configuration options for specifying the main
|
- Added ``--mainmodule:file`` configuration options for specifying the main
|
||||||
project file. This is intended to be used in project configuration files to
|
project file. This is intended to be used in project configuration files to
|
||||||
allow commands like ``nimrod c`` or ``nimrod check`` to be executed anywhere
|
allow commands like ``nimrod c`` or ``nimrod check`` to be executed anywhere
|
||||||
within the project's directory structure
|
within the project's directory structure.
|
||||||
- Added a ``--app:staticlib`` option for creating static libraries
|
- Added a ``--app:staticlib`` option for creating static libraries.
|
||||||
- Added a ``--tlsEmulation:on|off`` switch for control over thread local
|
- Added a ``--tlsEmulation:on|off`` switch for control over thread local
|
||||||
storage emulation.
|
storage emulation.
|
||||||
- The compiler and standard library now support a *taint mode*. Input strings
|
- The compiler and standard library now support a *taint mode*. Input strings
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ interpretation you will have to look harder.
|
||||||
Why yet another programming language?
|
Why yet another programming language?
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
Nimrod is one of the very few *programmable* strongly typed languages, and
|
Nimrod is one of the very few *programmable* statically typed languages, and
|
||||||
one of the even fewer that will produce native binaries that require no
|
one of the even fewer that will produce native binaries that require no
|
||||||
runtime or interpreter.
|
runtime or interpreter.
|
||||||
|
|
||||||
|
|
@ -54,7 +54,9 @@ However, the compiler is quite stable already: It is able to compile itself
|
||||||
and a substantial body of other code. Until version 1.0.0 is released,
|
and a substantial body of other code. Until version 1.0.0 is released,
|
||||||
incompatibilities with older versions of the compiler will be introduced. The
|
incompatibilities with older versions of the compiler will be introduced. The
|
||||||
semantic details of overloading, macros/templates/generics and iterators
|
semantic details of overloading, macros/templates/generics and iterators
|
||||||
and their interactions are subject to change.
|
and their interactions are subject to change. Changes to the syntax
|
||||||
|
are also planned; gone will be the distinction between expressions and
|
||||||
|
statements.
|
||||||
|
|
||||||
|
|
||||||
How fast is Nimrod?
|
How fast is Nimrod?
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue