commit
3949c9f977
90 changed files with 404 additions and 378 deletions
|
|
@ -102,4 +102,10 @@
|
||||||
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual
|
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual
|
||||||
machine.
|
machine.
|
||||||
|
|
||||||
|
- The ``deadCodeElim`` option is now always turned on and the switch has no
|
||||||
|
effect anymore, but is recognized for backwards compatibility.
|
||||||
|
|
||||||
|
- ``experimental`` is now a pragma / command line switch that can enable specific
|
||||||
|
language extensions, it is not an all-or-nothing switch anymore.
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,8 @@ type
|
||||||
# variable is a thread variable
|
# variable is a thread variable
|
||||||
sfCompileTime, # proc can be evaluated at compile time
|
sfCompileTime, # proc can be evaluated at compile time
|
||||||
sfConstructor, # proc is a C++ constructor
|
sfConstructor, # proc is a C++ constructor
|
||||||
sfDeadCodeElim, # dead code elimination for the module is turned on
|
sfDispatcher, # copied method symbol is the dispatcher
|
||||||
|
# deprecated and unused, except for the con
|
||||||
sfBorrow, # proc is borrowed
|
sfBorrow, # proc is borrowed
|
||||||
sfInfixCall, # symbol needs infix call syntax in target language;
|
sfInfixCall, # symbol needs infix call syntax in target language;
|
||||||
# for interfacing with C++, JS
|
# for interfacing with C++, JS
|
||||||
|
|
@ -275,10 +276,9 @@ type
|
||||||
TSymFlags* = set[TSymFlag]
|
TSymFlags* = set[TSymFlag]
|
||||||
|
|
||||||
const
|
const
|
||||||
sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher
|
|
||||||
sfNoInit* = sfMainModule # don't generate code to init the variable
|
sfNoInit* = sfMainModule # don't generate code to init the variable
|
||||||
|
|
||||||
sfImmediate* = sfDeadCodeElim
|
sfImmediate* = sfDispatcher
|
||||||
# macro or template is immediately expanded
|
# macro or template is immediately expanded
|
||||||
# without considering any possible overloads
|
# without considering any possible overloads
|
||||||
sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
|
sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
|
||||||
|
|
@ -1622,7 +1622,7 @@ iterator items*(n: PNode): PNode =
|
||||||
for i in 0..<n.safeLen: yield n.sons[i]
|
for i in 0..<n.safeLen: yield n.sons[i]
|
||||||
|
|
||||||
iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
|
iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
|
||||||
for i in 0..<n.len: yield (i, n.sons[i])
|
for i in 0..<n.safeLen: yield (i, n.sons[i])
|
||||||
|
|
||||||
proc isAtom*(n: PNode): bool {.inline.} =
|
proc isAtom*(n: PNode): bool {.inline.} =
|
||||||
result = n.kind >= nkNone and n.kind <= nkNilLit
|
result = n.kind >= nkNone and n.kind <= nkNilLit
|
||||||
|
|
|
||||||
|
|
@ -2264,7 +2264,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
of nkEmpty: discard
|
of nkEmpty: discard
|
||||||
of nkWhileStmt: genWhileStmt(p, n)
|
of nkWhileStmt: genWhileStmt(p, n)
|
||||||
of nkVarSection, nkLetSection: genVarStmt(p, n)
|
of nkVarSection, nkLetSection: genVarStmt(p, n)
|
||||||
of nkConstSection: genConstStmt(p, n)
|
of nkConstSection: discard # consts generated lazily on use
|
||||||
of nkForStmt: internalError(n.info, "for statement not eliminated")
|
of nkForStmt: internalError(n.info, "for statement not eliminated")
|
||||||
of nkCaseStmt: genCase(p, n, d)
|
of nkCaseStmt: genCase(p, n, d)
|
||||||
of nkReturnStmt: genReturnStmt(p, n)
|
of nkReturnStmt: genReturnStmt(p, n)
|
||||||
|
|
@ -2315,8 +2315,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
# are not transformed correctly. We work around this issue (#411) here
|
# are not transformed correctly. We work around this issue (#411) here
|
||||||
# by ensuring it's no inner proc (owner is a module):
|
# by ensuring it's no inner proc (owner is a module):
|
||||||
if prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags:
|
if prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags:
|
||||||
if (not emitLazily(prc)) or
|
if ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
|
||||||
({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
|
|
||||||
(sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
|
(sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
|
||||||
(prc.kind == skMethod):
|
(prc.kind == skMethod):
|
||||||
# we have not only the header:
|
# we have not only the header:
|
||||||
|
|
|
||||||
|
|
@ -280,20 +280,6 @@ proc genVarStmt(p: BProc, n: PNode) =
|
||||||
else:
|
else:
|
||||||
genVarTuple(p, it)
|
genVarTuple(p, it)
|
||||||
|
|
||||||
proc genConstStmt(p: BProc, n: PNode) =
|
|
||||||
for it in n.sons:
|
|
||||||
if it.kind == nkCommentStmt: continue
|
|
||||||
if it.kind != nkConstDef: internalError(n.info, "genConstStmt")
|
|
||||||
|
|
||||||
let sym = it.sons[0].sym
|
|
||||||
if sym.typ.containsCompileTimeOnly or
|
|
||||||
sym.typ.kind notin ConstantDataTypes or
|
|
||||||
sym.ast.len == 0 or
|
|
||||||
emitLazily(sym):
|
|
||||||
continue
|
|
||||||
|
|
||||||
requestConstImpl(p, sym)
|
|
||||||
|
|
||||||
proc genIf(p: BProc, n: PNode, d: var TLoc) =
|
proc genIf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
#
|
#
|
||||||
# { if (!expr1) goto L1;
|
# { if (!expr1) goto L1;
|
||||||
|
|
@ -587,7 +573,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
if isImportedException(typ):
|
if isImportedException(typ):
|
||||||
lineF(p, cpsStmts, "throw $1;$n", [e])
|
lineF(p, cpsStmts, "throw $1;$n", [e])
|
||||||
else:
|
else:
|
||||||
lineCg(p, cpsStmts, "#raiseException((#Exception*)$1, $2);$n",
|
lineCg(p, cpsStmts, "#raiseException((#Exception*)$1, $2);$n",
|
||||||
[e, makeCString(typ.sym.name.s)])
|
[e, makeCString(typ.sym.name.s)])
|
||||||
else:
|
else:
|
||||||
|
|
@ -836,7 +822,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
for j in 0..t[i].len-2:
|
for j in 0..t[i].len-2:
|
||||||
if t[i][j].isInfixAs():
|
if t[i][j].isInfixAs():
|
||||||
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
|
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
|
||||||
fillLoc(exvar.sym.loc, locTemp, exvar, mangleLocalName(p, exvar.sym), OnUnknown)
|
fillLoc(exvar.sym.loc, locTemp, exvar, mangleLocalName(p, exvar.sym), OnUnknown)
|
||||||
startBlock(p, "catch ($1& $2) {$n", getTypeDesc(p.module, t[i][j][1].typ), rdLoc(exvar.sym.loc))
|
startBlock(p, "catch ($1& $2) {$n", getTypeDesc(p.module, t[i][j][1].typ), rdLoc(exvar.sym.loc))
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -211,8 +211,4 @@ proc mangle*(name: string): string =
|
||||||
if requiresUnderscore:
|
if requiresUnderscore:
|
||||||
result.add "_"
|
result.add "_"
|
||||||
|
|
||||||
proc emitLazily*(s: PSym): bool {.inline.} =
|
|
||||||
result = optDeadCodeElim in gGlobalOptions or
|
|
||||||
sfDeadCodeElim in getModule(s).flags
|
|
||||||
|
|
||||||
initTypeTables()
|
initTypeTables()
|
||||||
|
|
|
||||||
|
|
@ -1309,10 +1309,6 @@ proc newModule(g: BModuleList; module: PSym): BModule =
|
||||||
growCache g.modules, module.position
|
growCache g.modules, module.position
|
||||||
g.modules[module.position] = result
|
g.modules[module.position] = result
|
||||||
|
|
||||||
if (optDeadCodeElim in gGlobalOptions):
|
|
||||||
if (sfDeadCodeElim in module.flags):
|
|
||||||
internalError("added pending module twice: " & toFilename(FileIndex module.position))
|
|
||||||
|
|
||||||
template injectG(config) {.dirty.} =
|
template injectG(config) {.dirty.} =
|
||||||
if graph.backend == nil:
|
if graph.backend == nil:
|
||||||
graph.backend = newModuleList(config)
|
graph.backend = newModuleList(config)
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ type
|
||||||
passCmd2, # second pass over the command line
|
passCmd2, # second pass over the command line
|
||||||
passPP # preprocessor called processCommand()
|
passPP # preprocessor called processCommand()
|
||||||
|
|
||||||
proc processCommand*(switch: string, pass: TCmdLinePass)
|
proc processCommand*(switch: string, pass: TCmdLinePass; config: ConfigRef)
|
||||||
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
config: ConfigRef = nil)
|
config: ConfigRef)
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
|
|
@ -58,7 +58,13 @@ const
|
||||||
|
|
||||||
const
|
const
|
||||||
Usage = slurp"../doc/basicopt.txt".replace("//", "")
|
Usage = slurp"../doc/basicopt.txt".replace("//", "")
|
||||||
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "")
|
FeatureDesc = block:
|
||||||
|
var x = ""
|
||||||
|
for f in low(Feature)..high(Feature):
|
||||||
|
if x.len > 0: x.add "|"
|
||||||
|
x.add $f
|
||||||
|
x
|
||||||
|
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "") % FeatureDesc
|
||||||
|
|
||||||
proc getCommandLineDesc(): string =
|
proc getCommandLineDesc(): string =
|
||||||
result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name,
|
result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name,
|
||||||
|
|
@ -268,7 +274,6 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
|
||||||
of "movechecks": result = contains(gOptions, optMoveCheck)
|
of "movechecks": result = contains(gOptions, optMoveCheck)
|
||||||
of "linedir": result = contains(gOptions, optLineDir)
|
of "linedir": result = contains(gOptions, optLineDir)
|
||||||
of "assertions", "a": result = contains(gOptions, optAssert)
|
of "assertions", "a": result = contains(gOptions, optAssert)
|
||||||
of "deadcodeelim": result = contains(gGlobalOptions, optDeadCodeElim)
|
|
||||||
of "run", "r": result = contains(gGlobalOptions, optRun)
|
of "run", "r": result = contains(gGlobalOptions, optRun)
|
||||||
of "symbolfiles": result = gSymbolFiles != disabledSf
|
of "symbolfiles": result = gSymbolFiles != disabledSf
|
||||||
of "genscript": result = contains(gGlobalOptions, optGenScript)
|
of "genscript": result = contains(gGlobalOptions, optGenScript)
|
||||||
|
|
@ -277,7 +282,6 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
|
||||||
of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
|
of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
|
||||||
of "implicitstatic": result = contains(gOptions, optImplicitStatic)
|
of "implicitstatic": result = contains(gOptions, optImplicitStatic)
|
||||||
of "patterns": result = contains(gOptions, optPatterns)
|
of "patterns": result = contains(gOptions, optPatterns)
|
||||||
of "experimental": result = gExperimentalMode
|
|
||||||
of "excessivestacktrace": result = contains(gGlobalOptions, optExcessiveStackTrace)
|
of "excessivestacktrace": result = contains(gGlobalOptions, optExcessiveStackTrace)
|
||||||
else: invalidCmdLineOption(passCmd1, switch, info)
|
else: invalidCmdLineOption(passCmd1, switch, info)
|
||||||
|
|
||||||
|
|
@ -340,7 +344,7 @@ proc dynlibOverride(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||||
options.inclDynlibOverride(arg)
|
options.inclDynlibOverride(arg)
|
||||||
|
|
||||||
proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
config: ConfigRef = nil) =
|
config: ConfigRef) =
|
||||||
var
|
var
|
||||||
theOS: TSystemOS
|
theOS: TSystemOS
|
||||||
cpu: TSystemCPU
|
cpu: TSystemCPU
|
||||||
|
|
@ -509,7 +513,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
of "movechecks": processOnOffSwitch({optMoveCheck}, arg, pass, info)
|
of "movechecks": processOnOffSwitch({optMoveCheck}, arg, pass, info)
|
||||||
of "linedir": processOnOffSwitch({optLineDir}, arg, pass, info)
|
of "linedir": processOnOffSwitch({optLineDir}, arg, pass, info)
|
||||||
of "assertions", "a": processOnOffSwitch({optAssert}, arg, pass, info)
|
of "assertions", "a": processOnOffSwitch({optAssert}, arg, pass, info)
|
||||||
of "deadcodeelim": processOnOffSwitchG({optDeadCodeElim}, arg, pass, info)
|
of "deadcodeelim": discard # deprecated, dead code elim always on
|
||||||
of "threads":
|
of "threads":
|
||||||
processOnOffSwitchG({optThreads}, arg, pass, info)
|
processOnOffSwitchG({optThreads}, arg, pass, info)
|
||||||
#if optThreads in gGlobalOptions: incl(gNotes, warnGcUnsafe)
|
#if optThreads in gGlobalOptions: incl(gNotes, warnGcUnsafe)
|
||||||
|
|
@ -648,6 +652,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
of "genscript", "gendeps":
|
of "genscript", "gendeps":
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
incl(gGlobalOptions, optGenScript)
|
incl(gGlobalOptions, optGenScript)
|
||||||
|
incl(gGlobalOptions, optCompileOnly)
|
||||||
of "colors": processOnOffSwitchG({optUseColors}, arg, pass, info)
|
of "colors": processOnOffSwitchG({optUseColors}, arg, pass, info)
|
||||||
of "lib":
|
of "lib":
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
|
|
@ -695,8 +700,13 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
# only supported for compatibility. Does nothing.
|
# only supported for compatibility. Does nothing.
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
of "experimental":
|
of "experimental":
|
||||||
expectNoArg(switch, arg, pass, info)
|
if arg.len == 0:
|
||||||
gExperimentalMode = true
|
config.features.incl oldExperimentalFeatures
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
config.features.incl parseEnum[Feature](arg)
|
||||||
|
except ValueError:
|
||||||
|
localError(info, "unknown experimental feature")
|
||||||
of "nocppexceptions":
|
of "nocppexceptions":
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
incl(gGlobalOptions, optNoCppExceptions)
|
incl(gGlobalOptions, optNoCppExceptions)
|
||||||
|
|
@ -707,7 +717,8 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
config.cppDefine(arg)
|
config.cppDefine(arg)
|
||||||
of "newruntime":
|
of "newruntime":
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
newDestructors = true
|
doAssert(config != nil)
|
||||||
|
incl(config.features, destructor)
|
||||||
defineSymbol("nimNewRuntime")
|
defineSymbol("nimNewRuntime")
|
||||||
of "cppcompiletonamespace":
|
of "cppcompiletonamespace":
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
|
|
@ -717,36 +728,31 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
||||||
else: invalidCmdLineOption(pass, switch, info)
|
else: invalidCmdLineOption(pass, switch, info)
|
||||||
|
|
||||||
proc processCommand(switch: string, pass: TCmdLinePass) =
|
proc processCommand(switch: string, pass: TCmdLinePass; config: ConfigRef) =
|
||||||
var cmd, arg: string
|
var cmd, arg: string
|
||||||
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
|
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
|
||||||
processSwitch(cmd, arg, pass, gCmdLineInfo)
|
processSwitch(cmd, arg, pass, gCmdLineInfo, config)
|
||||||
|
|
||||||
|
|
||||||
var
|
proc processSwitch*(pass: TCmdLinePass; p: OptParser; config: ConfigRef) =
|
||||||
arguments* = ""
|
|
||||||
# the arguments to be passed to the program that
|
|
||||||
# should be run
|
|
||||||
|
|
||||||
proc processSwitch*(pass: TCmdLinePass; p: OptParser) =
|
|
||||||
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
|
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
|
||||||
# we fix this here
|
# we fix this here
|
||||||
var bracketLe = strutils.find(p.key, '[')
|
var bracketLe = strutils.find(p.key, '[')
|
||||||
if bracketLe >= 0:
|
if bracketLe >= 0:
|
||||||
var key = substr(p.key, 0, bracketLe - 1)
|
var key = substr(p.key, 0, bracketLe - 1)
|
||||||
var val = substr(p.key, bracketLe + 1) & ':' & p.val
|
var val = substr(p.key, bracketLe + 1) & ':' & p.val
|
||||||
processSwitch(key, val, pass, gCmdLineInfo)
|
processSwitch(key, val, pass, gCmdLineInfo, config)
|
||||||
else:
|
else:
|
||||||
processSwitch(p.key, p.val, pass, gCmdLineInfo)
|
processSwitch(p.key, p.val, pass, gCmdLineInfo, config)
|
||||||
|
|
||||||
proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
||||||
argsCount: var int): bool =
|
argsCount: var int; config: ConfigRef): bool =
|
||||||
if argsCount == 0:
|
if argsCount == 0:
|
||||||
# nim filename.nims is the same as "nim e filename.nims":
|
# nim filename.nims is the same as "nim e filename.nims":
|
||||||
if p.key.endswith(".nims"):
|
if p.key.endswith(".nims"):
|
||||||
options.command = "e"
|
options.command = "e"
|
||||||
options.gProjectName = unixToNativePath(p.key)
|
options.gProjectName = unixToNativePath(p.key)
|
||||||
arguments = cmdLineRest(p)
|
config.arguments = cmdLineRest(p)
|
||||||
result = true
|
result = true
|
||||||
elif pass != passCmd2:
|
elif pass != passCmd2:
|
||||||
options.command = p.key
|
options.command = p.key
|
||||||
|
|
@ -755,6 +761,6 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
||||||
if argsCount == 1:
|
if argsCount == 1:
|
||||||
# support UNIX style filenames everywhere for portable build scripts:
|
# support UNIX style filenames everywhere for portable build scripts:
|
||||||
options.gProjectName = unixToNativePath(p.key)
|
options.gProjectName = unixToNativePath(p.key)
|
||||||
arguments = cmdLineRest(p)
|
config.arguments = cmdLineRest(p)
|
||||||
result = true
|
result = true
|
||||||
inc argsCount
|
inc argsCount
|
||||||
|
|
|
||||||
|
|
@ -470,8 +470,9 @@ proc execExternalProgram*(cmd: string, msg = hintExecuting) =
|
||||||
|
|
||||||
proc generateScript(projectFile: string, script: Rope) =
|
proc generateScript(projectFile: string, script: Rope) =
|
||||||
let (dir, name, ext) = splitFile(projectFile)
|
let (dir, name, ext) = splitFile(projectFile)
|
||||||
writeRope(script, dir / addFileExt("compile_" & name,
|
writeRope(script, getNimcacheDir() / addFileExt("compile_" & name,
|
||||||
platform.OS[targetOS].scriptExt))
|
platform.OS[targetOS].scriptExt))
|
||||||
|
copyFile(libpath / "nimbase.h", getNimcacheDir() / "nimbase.h")
|
||||||
|
|
||||||
proc getOptSpeed(c: TSystemCC): string =
|
proc getOptSpeed(c: TSystemCC): string =
|
||||||
result = getConfigVar(c, ".options.speed")
|
result = getConfigVar(c, ".options.speed")
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
writeCommandLineUsage()
|
writeCommandLineUsage()
|
||||||
else:
|
else:
|
||||||
# Process command line arguments:
|
# Process command line arguments:
|
||||||
processCmdLine(passCmd1, "")
|
processCmdLine(passCmd1, "", config)
|
||||||
if gProjectName == "-":
|
if gProjectName == "-":
|
||||||
gProjectName = "stdinfile"
|
gProjectName = "stdinfile"
|
||||||
gProjectFull = "stdinfile"
|
gProjectFull = "stdinfile"
|
||||||
|
|
@ -71,7 +71,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
# 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()
|
||||||
processCmdLine(passCmd2, "")
|
processCmdLine(passCmd2, "", config)
|
||||||
if options.command == "":
|
if options.command == "":
|
||||||
rawMessage(errNoCommand, command)
|
rawMessage(errNoCommand, command)
|
||||||
mainCommand(newModuleGraph(config), cache)
|
mainCommand(newModuleGraph(config), cache)
|
||||||
|
|
@ -80,7 +80,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
if msgs.gErrorCounter == 0:
|
if msgs.gErrorCounter == 0:
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
if gCmd == cmdRun:
|
if gCmd == cmdRun:
|
||||||
tccgen.run(commands.arguments)
|
tccgen.run(config.arguments)
|
||||||
if optRun in gGlobalOptions:
|
if optRun in gGlobalOptions:
|
||||||
if gCmd == cmdCompileToJS:
|
if gCmd == cmdCompileToJS:
|
||||||
var ex: string
|
var ex: string
|
||||||
|
|
@ -89,7 +89,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
else:
|
else:
|
||||||
ex = quoteShell(
|
ex = quoteShell(
|
||||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||||
execExternalProgram(findNodeJs() & " " & ex & ' ' & commands.arguments)
|
execExternalProgram(findNodeJs() & " " & ex & ' ' & config.arguments)
|
||||||
else:
|
else:
|
||||||
var binPath: string
|
var binPath: string
|
||||||
if options.outFile.len > 0:
|
if options.outFile.len > 0:
|
||||||
|
|
@ -99,7 +99,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
# Figure out ourselves a valid binary name.
|
# Figure out ourselves a valid binary name.
|
||||||
binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir
|
binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir
|
||||||
var ex = quoteShell(binPath)
|
var ex = quoteShell(binPath)
|
||||||
execExternalProgram(ex & ' ' & commands.arguments)
|
execExternalProgram(ex & ' ' & config.arguments)
|
||||||
|
|
||||||
when declared(GC_setMaxPause):
|
when declared(GC_setMaxPause):
|
||||||
GC_setMaxPause 2_000
|
GC_setMaxPause 2_000
|
||||||
|
|
|
||||||
|
|
@ -247,10 +247,6 @@ proc loadConfigs*(cfg: string; cache: IdentCache; config: ConfigRef = nil) =
|
||||||
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
|
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
|
||||||
if not fileExists(projectConfig):
|
if not fileExists(projectConfig):
|
||||||
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
|
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
|
||||||
if not fileExists(projectConfig):
|
|
||||||
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
|
|
||||||
if fileExists(projectConfig):
|
|
||||||
rawMessage(warnDeprecated, projectConfig)
|
|
||||||
readConfigFile(projectConfig, cache, config)
|
readConfigFile(projectConfig, cache, config)
|
||||||
|
|
||||||
proc loadConfigs*(cfg: string; config: ConfigRef = nil) =
|
proc loadConfigs*(cfg: string; config: ConfigRef = nil) =
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ type # please make sure we have under 32 options
|
||||||
|
|
||||||
TOptions* = set[TOption]
|
TOptions* = set[TOption]
|
||||||
TGlobalOption* = enum # **keep binary compatible**
|
TGlobalOption* = enum # **keep binary compatible**
|
||||||
gloptNone, optForceFullMake, optDeadCodeElim,
|
gloptNone, optForceFullMake,
|
||||||
|
optDeadCodeElimUnused, # deprecated, always on
|
||||||
optListCmd, optCompileOnly, optNoLinking,
|
optListCmd, optCompileOnly, optNoLinking,
|
||||||
optCDebug, # turn on debugging information
|
optCDebug, # turn on debugging information
|
||||||
optGenDynLib, # generate a dynamic library
|
optGenDynLib, # generate a dynamic library
|
||||||
|
|
@ -102,13 +103,25 @@ type
|
||||||
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
|
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
|
||||||
ideHighlight, ideOutline, ideKnown, ideMsg
|
ideHighlight, ideOutline, ideKnown, ideMsg
|
||||||
|
|
||||||
|
Feature* = enum ## experimental features
|
||||||
|
implicitDeref,
|
||||||
|
dotOperators,
|
||||||
|
callOperator,
|
||||||
|
parallel,
|
||||||
|
destructor
|
||||||
|
|
||||||
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
||||||
cppDefines*: HashSet[string]
|
cppDefines*: HashSet[string]
|
||||||
headerFile*: string
|
headerFile*: string
|
||||||
|
features*: set[Feature]
|
||||||
|
arguments*: string ## the arguments to be passed to the program that
|
||||||
|
## should be run
|
||||||
|
|
||||||
|
const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel}
|
||||||
|
|
||||||
proc newConfigRef*(): ConfigRef =
|
proc newConfigRef*(): ConfigRef =
|
||||||
result = ConfigRef(cppDefines: initSet[string](),
|
result = ConfigRef(cppDefines: initSet[string](),
|
||||||
headerFile: "")
|
headerFile: "", features: {})
|
||||||
|
|
||||||
proc cppDefine*(c: ConfigRef; define: string) =
|
proc cppDefine*(c: ConfigRef; define: string) =
|
||||||
c.cppDefines.incl define
|
c.cppDefines.incl define
|
||||||
|
|
@ -145,8 +158,6 @@ var
|
||||||
gListFullPaths*: bool
|
gListFullPaths*: bool
|
||||||
gPreciseStack*: bool = false
|
gPreciseStack*: bool = false
|
||||||
gNoNimblePath* = false
|
gNoNimblePath* = false
|
||||||
gExperimentalMode*: bool
|
|
||||||
newDestructors*: bool
|
|
||||||
gDynlibOverrideAll*: bool
|
gDynlibOverrideAll*: bool
|
||||||
useNimNamespace*: bool
|
useNimNamespace*: bool
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||||
p: TParsers
|
p: TParsers
|
||||||
a: TPassContextArray
|
a: TPassContextArray
|
||||||
s: PLLStream
|
s: PLLStream
|
||||||
fileIdx = FileIndex module.fileIdx
|
fileIdx = module.fileIdx
|
||||||
if module.id < 0:
|
if module.id < 0:
|
||||||
# new module caching mechanism:
|
# new module caching mechanism:
|
||||||
for i in 0..<gPassesLen:
|
for i in 0..<gPassesLen:
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,9 @@ const
|
||||||
wWarnings, wHints,
|
wWarnings, wHints,
|
||||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
||||||
wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop,
|
wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop,
|
||||||
wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated,
|
wBreakpoint, wWatchPoint, wPassl, wPassc,
|
||||||
|
wDeadCodeElimUnused, # deprecated, always on
|
||||||
|
wDeprecated,
|
||||||
wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
||||||
wLinearScanEnd, wPatterns, wEffects, wNoForward, wReorder, wComputedGoto,
|
wLinearScanEnd, wPatterns, wEffects, wNoForward, wReorder, wComputedGoto,
|
||||||
wInjectStmt, wDeprecated, wExperimental, wThis}
|
wInjectStmt, wDeprecated, wExperimental, wThis}
|
||||||
|
|
@ -215,10 +217,6 @@ proc onOff(c: PContext, n: PNode, op: TOptions) =
|
||||||
if isTurnedOn(c, n): gOptions = gOptions + op
|
if isTurnedOn(c, n): gOptions = gOptions + op
|
||||||
else: gOptions = gOptions - op
|
else: gOptions = gOptions - op
|
||||||
|
|
||||||
proc pragmaDeadCodeElim(c: PContext, n: PNode) =
|
|
||||||
if isTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim)
|
|
||||||
else: excl(c.module.flags, sfDeadCodeElim)
|
|
||||||
|
|
||||||
proc pragmaNoForward(c: PContext, n: PNode; flag=sfNoForward) =
|
proc pragmaNoForward(c: PContext, n: PNode; flag=sfNoForward) =
|
||||||
if isTurnedOn(c, n): incl(c.module.flags, flag)
|
if isTurnedOn(c, n): incl(c.module.flags, flag)
|
||||||
else: excl(c.module.flags, flag)
|
else: excl(c.module.flags, flag)
|
||||||
|
|
@ -682,6 +680,22 @@ proc semCustomPragma(c: PContext, n: PNode): PNode =
|
||||||
elif n.kind == nkExprColonExpr:
|
elif n.kind == nkExprColonExpr:
|
||||||
result.kind = n.kind # pragma(arg) -> pragma: arg
|
result.kind = n.kind # pragma(arg) -> pragma: arg
|
||||||
|
|
||||||
|
proc processExperimental(c: PContext; n: PNode; s: PSym) =
|
||||||
|
if not isTopLevel(c):
|
||||||
|
localError(n.info, "'experimental' pragma only valid as toplevel statement")
|
||||||
|
if n.kind notin nkPragmaCallKinds or n.len != 2:
|
||||||
|
c.features.incl oldExperimentalFeatures
|
||||||
|
else:
|
||||||
|
n[1] = c.semConstExpr(c, n[1])
|
||||||
|
case n[1].kind
|
||||||
|
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||||
|
try:
|
||||||
|
c.features.incl parseEnum[Feature](n[1].strVal)
|
||||||
|
except ValueError:
|
||||||
|
localError(n[1].info, "unknown experimental feature")
|
||||||
|
else:
|
||||||
|
localError(n.info, errStringLiteralExpected)
|
||||||
|
|
||||||
proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
validPragmas: TSpecialWords): bool =
|
validPragmas: TSpecialWords): bool =
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
|
|
@ -764,7 +778,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
of wThreadVar:
|
of wThreadVar:
|
||||||
noVal(it)
|
noVal(it)
|
||||||
incl(sym.flags, sfThread)
|
incl(sym.flags, sfThread)
|
||||||
of wDeadCodeElim: pragmaDeadCodeElim(c, it)
|
of wDeadCodeElimUnused: discard # deprecated, dead code elim always on
|
||||||
of wNoForward: pragmaNoForward(c, it)
|
of wNoForward: pragmaNoForward(c, it)
|
||||||
of wReorder: pragmaNoForward(c, it, sfReorder)
|
of wReorder: pragmaNoForward(c, it, sfReorder)
|
||||||
of wMagic: processMagic(c, it, sym)
|
of wMagic: processMagic(c, it, sym)
|
||||||
|
|
@ -960,10 +974,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
if sym.kind != skType or sym.typ == nil: invalidPragma(it)
|
if sym.kind != skType or sym.typ == nil: invalidPragma(it)
|
||||||
else:
|
else:
|
||||||
incl(sym.typ.flags, tfPartial)
|
incl(sym.typ.flags, tfPartial)
|
||||||
# .partial types can only work with dead code elimination
|
|
||||||
# to prevent the codegen from doing anything before we compiled
|
|
||||||
# the whole program:
|
|
||||||
incl gGlobalOptions, optDeadCodeElim
|
|
||||||
of wInject, wGensym:
|
of wInject, wGensym:
|
||||||
# We check for errors, but do nothing with these pragmas otherwise
|
# We check for errors, but do nothing with these pragmas otherwise
|
||||||
# as they are handled directly in 'evalTemplate'.
|
# as they are handled directly in 'evalTemplate'.
|
||||||
|
|
@ -999,11 +1009,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
else:
|
else:
|
||||||
it.sons[1] = c.semExpr(c, it.sons[1])
|
it.sons[1] = c.semExpr(c, it.sons[1])
|
||||||
of wExperimental:
|
of wExperimental:
|
||||||
noVal(it)
|
processExperimental(c, it, sym)
|
||||||
if isTopLevel(c):
|
|
||||||
c.module.flags.incl sfExperimental
|
|
||||||
else:
|
|
||||||
localError(it.info, "'experimental' pragma only valid as toplevel statement")
|
|
||||||
of wThis:
|
of wThis:
|
||||||
if it.kind in nkPragmaCallKinds and it.len == 2:
|
if it.kind in nkPragmaCallKinds and it.len == 2:
|
||||||
c.selfName = considerQuotedIdent(it[1])
|
c.selfName = considerQuotedIdent(it[1])
|
||||||
|
|
|
||||||
|
|
@ -172,32 +172,6 @@ proc put(g: var TSrcGen, kind: TTokType, s: string) =
|
||||||
else:
|
else:
|
||||||
g.pendingWhitespace = s.len
|
g.pendingWhitespace = s.len
|
||||||
|
|
||||||
proc addNimChar(dst: var string; c: char): void =
|
|
||||||
case c
|
|
||||||
of '\0': dst.add "\\x00" # not "\\0" to avoid ambiguous cases like "\\012".
|
|
||||||
of '\a': dst.add "\\a" # \x07
|
|
||||||
of '\b': dst.add "\\b" # \x08
|
|
||||||
of '\t': dst.add "\\t" # \x09
|
|
||||||
of '\L': dst.add "\\L" # \x0A
|
|
||||||
of '\v': dst.add "\\v" # \x0B
|
|
||||||
of '\f': dst.add "\\f" # \x0C
|
|
||||||
of '\c': dst.add "\\c" # \x0D
|
|
||||||
of '\e': dst.add "\\e" # \x1B
|
|
||||||
of '\x01'..'\x06', '\x0E'..'\x1A', '\x1C'..'\x1F', '\x80'..'\xFF':
|
|
||||||
dst.add "\\x"
|
|
||||||
dst.add strutils.toHex(ord(c), 2)
|
|
||||||
of '\'', '\"', '\\':
|
|
||||||
dst.add '\\'
|
|
||||||
dst.add c
|
|
||||||
else:
|
|
||||||
dst.add c
|
|
||||||
|
|
||||||
proc makeNimString(s: string): string =
|
|
||||||
result = "\""
|
|
||||||
for c in s:
|
|
||||||
result.addNimChar c
|
|
||||||
add(result, '\"')
|
|
||||||
|
|
||||||
proc putComment(g: var TSrcGen, s: string) =
|
proc putComment(g: var TSrcGen, s: string) =
|
||||||
if s.isNil: return
|
if s.isNil: return
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -365,10 +339,13 @@ proc atom(g: TSrcGen; n: PNode): string =
|
||||||
of nkEmpty: result = ""
|
of nkEmpty: result = ""
|
||||||
of nkIdent: result = n.ident.s
|
of nkIdent: result = n.ident.s
|
||||||
of nkSym: result = n.sym.name.s
|
of nkSym: result = n.sym.name.s
|
||||||
of nkStrLit: result = makeNimString(n.strVal)
|
of nkStrLit: result = ""; result.addQuoted(n.strVal)
|
||||||
of nkRStrLit: result = "r\"" & replace(n.strVal, "\"", "\"\"") & '\"'
|
of nkRStrLit: result = "r\"" & replace(n.strVal, "\"", "\"\"") & '\"'
|
||||||
of nkTripleStrLit: result = "\"\"\"" & n.strVal & "\"\"\""
|
of nkTripleStrLit: result = "\"\"\"" & n.strVal & "\"\"\""
|
||||||
of nkCharLit: result = "\'"; result.addNimChar chr(int(n.intVal)); result.add '\''
|
of nkCharLit:
|
||||||
|
result = "\'"
|
||||||
|
result.addEscapedChar(chr(int(n.intVal)));
|
||||||
|
result.add '\''
|
||||||
of nkIntLit: result = litAux(g, n, n.intVal, 4)
|
of nkIntLit: result = litAux(g, n, n.intVal, 4)
|
||||||
of nkInt8Lit: result = litAux(g, n, n.intVal, 1) & "\'i8"
|
of nkInt8Lit: result = litAux(g, n, n.intVal, 1) & "\'i8"
|
||||||
of nkInt16Lit: result = litAux(g, n, n.intVal, 2) & "\'i16"
|
of nkInt16Lit: result = litAux(g, n, n.intVal, 2) & "\'i16"
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ proc reorder*(graph: ModuleGraph, n: PNode, module: PSym, cache: IdentCache): PN
|
||||||
if n.hasForbiddenPragma:
|
if n.hasForbiddenPragma:
|
||||||
return n
|
return n
|
||||||
var includedFiles = initIntSet()
|
var includedFiles = initIntSet()
|
||||||
let mpath = module.fileIdx.FileIndex.toFullPath
|
let mpath = module.fileIdx.toFullPath
|
||||||
let n = expandIncludes(graph, module, n, mpath,
|
let n = expandIncludes(graph, module, n, mpath,
|
||||||
includedFiles, cache).splitSections
|
includedFiles, cache).splitSections
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
|
|
|
||||||
|
|
@ -915,7 +915,7 @@ proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader =
|
||||||
module.id = getID()
|
module.id = getID()
|
||||||
return nil
|
return nil
|
||||||
idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
|
idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
|
||||||
let fileIdx = FileIndex module.fileIdx
|
let fileIdx = module.fileIdx
|
||||||
discard checkDep(fileIdx, cache)
|
discard checkDep(fileIdx, cache)
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) =
|
||||||
setResult(a, result)
|
setResult(a, result)
|
||||||
|
|
||||||
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||||
config: ConfigRef = nil): PEvalContext =
|
config: ConfigRef): PEvalContext =
|
||||||
# For Nimble we need to export 'setupVM'.
|
# For Nimble we need to export 'setupVM'.
|
||||||
result = newCtx(module, cache)
|
result = newCtx(module, cache)
|
||||||
result.mode = emRepl
|
result.mode = emRepl
|
||||||
|
|
@ -128,7 +128,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||||
cbconf getCommand:
|
cbconf getCommand:
|
||||||
setResult(a, options.command)
|
setResult(a, options.command)
|
||||||
cbconf switch:
|
cbconf switch:
|
||||||
processSwitch(a.getString 0, a.getString 1, passPP, module.info)
|
processSwitch(a.getString 0, a.getString 1, passPP, module.info, config)
|
||||||
cbconf hintImpl:
|
cbconf hintImpl:
|
||||||
processSpecificNote(a.getString 0, wHint, passPP, module.info,
|
processSpecificNote(a.getString 0, wHint, passPP, module.info,
|
||||||
a.getString 1)
|
a.getString 1)
|
||||||
|
|
@ -150,7 +150,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||||
options.cppDefine(config, a.getString(0))
|
options.cppDefine(config, a.getString(0))
|
||||||
|
|
||||||
proc runNimScript*(cache: IdentCache; scriptName: string;
|
proc runNimScript*(cache: IdentCache; scriptName: string;
|
||||||
freshDefines=true; config: ConfigRef=nil) =
|
freshDefines=true; config: ConfigRef) =
|
||||||
rawMessage(hintConf, scriptName)
|
rawMessage(hintConf, scriptName)
|
||||||
passes.gIncludeFile = includeModule
|
passes.gIncludeFile = includeModule
|
||||||
passes.gImportModule = importModule
|
passes.gImportModule = importModule
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ proc newOpCall(op: PSym; x: PNode): PNode =
|
||||||
proc destructorCall(c: PContext; op: PSym; x: PNode): PNode =
|
proc destructorCall(c: PContext; op: PSym; x: PNode): PNode =
|
||||||
result = newNodeIT(nkCall, x.info, op.typ.sons[0])
|
result = newNodeIT(nkCall, x.info, op.typ.sons[0])
|
||||||
result.add(newSymNode(op))
|
result.add(newSymNode(op))
|
||||||
if newDestructors:
|
if destructor in c.features:
|
||||||
result.add genAddr(c, x)
|
result.add genAddr(c, x)
|
||||||
else:
|
else:
|
||||||
result.add x
|
result.add x
|
||||||
|
|
@ -319,7 +319,7 @@ proc liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
|
||||||
## In the semantic pass this is called in strategic places
|
## In the semantic pass this is called in strategic places
|
||||||
## to ensure we lift assignment, destructors and moves properly.
|
## to ensure we lift assignment, destructors and moves properly.
|
||||||
## The later 'destroyer' pass depends on it.
|
## The later 'destroyer' pass depends on it.
|
||||||
if not newDestructors or not hasDestructor(typ): return
|
if destructor notin c.features or not hasDestructor(typ): return
|
||||||
when false:
|
when false:
|
||||||
# do not produce wrong liftings while we're still instantiating generics:
|
# do not produce wrong liftings while we're still instantiating generics:
|
||||||
# now disabled; breaks topttree.nim!
|
# now disabled; breaks topttree.nim!
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
||||||
"Non-matching candidates for " & renderTree(n) & "\n" &
|
"Non-matching candidates for " & renderTree(n) & "\n" &
|
||||||
candidates)
|
candidates)
|
||||||
result = semResolvedCall(c, n, r)
|
result = semResolvedCall(c, n, r)
|
||||||
elif experimentalMode(c) and canDeref(n):
|
elif implicitDeref in c.features and canDeref(n):
|
||||||
# try to deref the first argument and then try overloading resolution again:
|
# try to deref the first argument and then try overloading resolution again:
|
||||||
#
|
#
|
||||||
# XXX: why is this here?
|
# XXX: why is this here?
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ type
|
||||||
signatures*: TStrTable
|
signatures*: TStrTable
|
||||||
recursiveDep*: string
|
recursiveDep*: string
|
||||||
suggestionsMade*: bool
|
suggestionsMade*: bool
|
||||||
|
features*: set[Feature]
|
||||||
inTypeContext*: int
|
inTypeContext*: int
|
||||||
typesWithOps*: seq[(PType, PType)] #\
|
typesWithOps*: seq[(PType, PType)] #\
|
||||||
# We need to instantiate the type bound ops lazily after
|
# We need to instantiate the type bound ops lazily after
|
||||||
|
|
@ -225,7 +226,7 @@ proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext
|
||||||
result.graph = graph
|
result.graph = graph
|
||||||
initStrTable(result.signatures)
|
initStrTable(result.signatures)
|
||||||
result.typesWithOps = @[]
|
result.typesWithOps = @[]
|
||||||
|
result.features = graph.config.features
|
||||||
|
|
||||||
proc inclSym(sq: var TSymSeq, s: PSym) =
|
proc inclSym(sq: var TSymSeq, s: PSym) =
|
||||||
var L = len(sq)
|
var L = len(sq)
|
||||||
|
|
@ -398,6 +399,3 @@ proc checkMinSonsLen*(n: PNode, length: int) =
|
||||||
|
|
||||||
proc isTopLevel*(c: PContext): bool {.inline.} =
|
proc isTopLevel*(c: PContext): bool {.inline.} =
|
||||||
result = c.currentScope.depthLevel <= 2
|
result = c.currentScope.depthLevel <= 2
|
||||||
|
|
||||||
proc experimentalMode*(c: PContext): bool {.inline.} =
|
|
||||||
result = gExperimentalMode or sfExperimental in c.module.flags
|
|
||||||
|
|
|
||||||
|
|
@ -663,7 +663,7 @@ proc resolveIndirectCall(c: PContext; n, nOrig: PNode;
|
||||||
matches(c, n, nOrig, result)
|
matches(c, n, nOrig, result)
|
||||||
if result.state != csMatch:
|
if result.state != csMatch:
|
||||||
# try to deref the first argument:
|
# try to deref the first argument:
|
||||||
if experimentalMode(c) and canDeref(n):
|
if implicitDeref in c.features and canDeref(n):
|
||||||
n.sons[1] = n.sons[1].tryDeref
|
n.sons[1] = n.sons[1].tryDeref
|
||||||
initCandidate(c, result, t)
|
initCandidate(c, result, t)
|
||||||
matches(c, n, nOrig, result)
|
matches(c, n, nOrig, result)
|
||||||
|
|
@ -1452,7 +1452,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
typeMismatch(n.info, lhs.typ, rhsTyp)
|
typeMismatch(n.info, lhs.typ, rhsTyp)
|
||||||
|
|
||||||
n.sons[1] = fitNode(c, le, rhs, n.info)
|
n.sons[1] = fitNode(c, le, rhs, n.info)
|
||||||
if not newDestructors:
|
if destructor notin c.features:
|
||||||
if tfHasAsgn in lhs.typ.flags and not lhsIsResult and
|
if tfHasAsgn in lhs.typ.flags and not lhsIsResult and
|
||||||
mode != noOverloadedAsgn:
|
mode != noOverloadedAsgn:
|
||||||
return overloadedAsgn(c, lhs, n.sons[1])
|
return overloadedAsgn(c, lhs, n.sons[1])
|
||||||
|
|
@ -1884,7 +1884,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||||
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
|
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
|
||||||
result.typ = getSysType(tyString)
|
result.typ = getSysType(tyString)
|
||||||
of mParallel:
|
of mParallel:
|
||||||
if not experimentalMode(c):
|
if parallel notin c.features:
|
||||||
localError(n.info, "use the {.experimental.} pragma to enable 'parallel'")
|
localError(n.info, "use the {.experimental.} pragma to enable 'parallel'")
|
||||||
result = setMs(n, s)
|
result = setMs(n, s)
|
||||||
var x = n.lastSon
|
var x = n.lastSon
|
||||||
|
|
|
||||||
|
|
@ -385,30 +385,9 @@ proc checkNilable(v: PSym) =
|
||||||
include semasgn
|
include semasgn
|
||||||
|
|
||||||
proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) =
|
proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) =
|
||||||
# consider this:
|
|
||||||
# var
|
|
||||||
# x = 0
|
|
||||||
# withOverloadedAssignment = foo()
|
|
||||||
# y = use(withOverloadedAssignment)
|
|
||||||
# We need to split this into a statement list with multiple 'var' sections
|
|
||||||
# in order for this transformation to be correct.
|
|
||||||
let L = identDefs.len
|
let L = identDefs.len
|
||||||
let value = identDefs[L-1]
|
let value = identDefs[L-1]
|
||||||
if value.typ != nil and tfHasAsgn in value.typ.flags and not newDestructors:
|
if result.kind == nkStmtList:
|
||||||
# the spec says we need to rewrite 'var x = T()' to 'var x: T; x = T()':
|
|
||||||
identDefs.sons[L-1] = emptyNode
|
|
||||||
if result.kind != nkStmtList:
|
|
||||||
let oldResult = result
|
|
||||||
oldResult.add identDefs
|
|
||||||
result = newNodeI(nkStmtList, result.info)
|
|
||||||
result.add oldResult
|
|
||||||
else:
|
|
||||||
let o = copyNode(orig)
|
|
||||||
o.add identDefs
|
|
||||||
result.add o
|
|
||||||
for i in 0 .. L-3:
|
|
||||||
result.add overloadedAsgn(c, identDefs[i], value)
|
|
||||||
elif result.kind == nkStmtList:
|
|
||||||
let o = copyNode(orig)
|
let o = copyNode(orig)
|
||||||
o.add identDefs
|
o.add identDefs
|
||||||
result.add o
|
result.add o
|
||||||
|
|
@ -1267,9 +1246,6 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
gp = newNodeI(nkGenericParams, n.info)
|
gp = newNodeI(nkGenericParams, n.info)
|
||||||
|
|
||||||
if n.sons[paramsPos].kind != nkEmpty:
|
if n.sons[paramsPos].kind != nkEmpty:
|
||||||
#if n.kind == nkDo and not experimentalMode(c):
|
|
||||||
# localError(n.sons[paramsPos].info,
|
|
||||||
# "use the {.experimental.} pragma to enable 'do' with parameters")
|
|
||||||
semParamList(c, n.sons[paramsPos], gp, s)
|
semParamList(c, n.sons[paramsPos], gp, s)
|
||||||
# paramsTypeCheck(c, s.typ)
|
# paramsTypeCheck(c, s.typ)
|
||||||
if sonsLen(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty:
|
if sonsLen(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty:
|
||||||
|
|
@ -1363,27 +1339,26 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
|
||||||
|
|
||||||
proc semOverride(c: PContext, s: PSym, n: PNode) =
|
proc semOverride(c: PContext, s: PSym, n: PNode) =
|
||||||
case s.name.s.normalize
|
case s.name.s.normalize
|
||||||
of "destroy", "=destroy":
|
of "=destroy":
|
||||||
if newDestructors:
|
let t = s.typ
|
||||||
let t = s.typ
|
var noError = false
|
||||||
var noError = false
|
if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar:
|
||||||
if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar:
|
var obj = t.sons[1].sons[0]
|
||||||
var obj = t.sons[1].sons[0]
|
while true:
|
||||||
while true:
|
incl(obj.flags, tfHasAsgn)
|
||||||
incl(obj.flags, tfHasAsgn)
|
if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon
|
||||||
if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon
|
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
|
||||||
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
|
else: break
|
||||||
else: break
|
if obj.kind in {tyObject, tyDistinct}:
|
||||||
if obj.kind in {tyObject, tyDistinct}:
|
if obj.destructor.isNil:
|
||||||
if obj.destructor.isNil:
|
obj.destructor = s
|
||||||
obj.destructor = s
|
else:
|
||||||
else:
|
localError(n.info, errGenerated,
|
||||||
localError(n.info, errGenerated,
|
"cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
|
||||||
"cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
|
noError = true
|
||||||
noError = true
|
if not noError and sfSystemModule notin s.owner.flags:
|
||||||
if not noError and sfSystemModule notin s.owner.flags:
|
localError(n.info, errGenerated,
|
||||||
localError(n.info, errGenerated,
|
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
|
||||||
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
|
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
of "deepcopy", "=deepcopy":
|
of "deepcopy", "=deepcopy":
|
||||||
if s.typ.len == 2 and
|
if s.typ.len == 2 and
|
||||||
|
|
@ -1612,9 +1587,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
s.options = gOptions
|
s.options = gOptions
|
||||||
if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n)
|
if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n)
|
||||||
if s.name.s[0] in {'.', '('}:
|
if s.name.s[0] in {'.', '('}:
|
||||||
if s.name.s in [".", ".()", ".="] and not experimentalMode(c) and not newDestructors:
|
if s.name.s in [".", ".()", ".="] and {destructor, dotOperators} * c.features == {}:
|
||||||
message(n.info, warnDeprecated, "overloaded '.' and '()' operators are now .experimental; " & s.name.s)
|
message(n.info, warnDeprecated, "overloaded '.' and '()' operators are now .experimental; " & s.name.s)
|
||||||
elif s.name.s == "()" and not experimentalMode(c):
|
elif s.name.s == "()" and callOperator notin c.features:
|
||||||
message(n.info, warnDeprecated, "overloaded '()' operators are now .experimental; " & s.name.s)
|
message(n.info, warnDeprecated, "overloaded '()' operators are now .experimental; " & s.name.s)
|
||||||
|
|
||||||
if n.sons[bodyPos].kind != nkEmpty:
|
if n.sons[bodyPos].kind != nkEmpty:
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||||
assert newbody.kind in {tyRef, tyPtr}
|
assert newbody.kind in {tyRef, tyPtr}
|
||||||
assert newbody.lastSon.typeInst == nil
|
assert newbody.lastSon.typeInst == nil
|
||||||
newbody.lastSon.typeInst = result
|
newbody.lastSon.typeInst = result
|
||||||
if newDestructors:
|
if destructor in cl.c.features:
|
||||||
cl.c.typesWithOps.add((newbody, result))
|
cl.c.typesWithOps.add((newbody, result))
|
||||||
else:
|
else:
|
||||||
typeBound(cl.c, newbody, result, assignment, cl.info)
|
typeBound(cl.c, newbody, result, assignment, cl.info)
|
||||||
|
|
@ -545,7 +545,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc instAllTypeBoundOp*(c: PContext, info: TLineInfo) =
|
proc instAllTypeBoundOp*(c: PContext, info: TLineInfo) =
|
||||||
if not newDestructors: return
|
if destructor notin c.features: return
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < c.typesWithOps.len:
|
while i < c.typesWithOps.len:
|
||||||
let (newty, oldty) = c.typesWithOps[i]
|
let (newty, oldty) = c.typesWithOps[i]
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ var
|
||||||
# in caas mode, the list of defines and options will be given at start-up?
|
# in caas mode, the list of defines and options will be given at start-up?
|
||||||
# it's enough to check that the previous compilation command is the same?
|
# it's enough to check that the previous compilation command is the same?
|
||||||
|
|
||||||
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
proc processCmdLine*(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||||
var p = parseopt.initOptParser(cmd)
|
var p = parseopt.initOptParser(cmd)
|
||||||
var argsCount = 0
|
var argsCount = 0
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -36,19 +36,19 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||||
of cmdLongoption, cmdShortOption:
|
of cmdLongoption, cmdShortOption:
|
||||||
if p.key == " ":
|
if p.key == " ":
|
||||||
p.key = "-"
|
p.key = "-"
|
||||||
if processArgument(pass, p, argsCount): break
|
if processArgument(pass, p, argsCount, config): break
|
||||||
else:
|
else:
|
||||||
processSwitch(pass, p)
|
processSwitch(pass, p, config)
|
||||||
of cmdArgument:
|
of cmdArgument:
|
||||||
if processArgument(pass, p, argsCount): break
|
if processArgument(pass, p, argsCount, config): break
|
||||||
if pass == passCmd2:
|
if pass == passCmd2:
|
||||||
if optRun notin gGlobalOptions and arguments != "" and options.command.normalize != "run":
|
if optRun notin gGlobalOptions and config.arguments.len > 0 and options.command.normalize != "run":
|
||||||
rawMessage(errArgsNeedRunOption, [])
|
rawMessage(errArgsNeedRunOption, [])
|
||||||
|
|
||||||
proc serve*(cache: IdentCache; action: proc (cache: IdentCache){.nimcall.}) =
|
proc serve*(cache: IdentCache; action: proc (cache: IdentCache){.nimcall.}; config: ConfigRef) =
|
||||||
template execute(cmd) =
|
template execute(cmd) =
|
||||||
curCaasCmd = cmd
|
curCaasCmd = cmd
|
||||||
processCmdLine(passCmd2, cmd)
|
processCmdLine(passCmd2, cmd, config)
|
||||||
action(cache)
|
action(cache)
|
||||||
gErrorCounter = 0
|
gErrorCounter = 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -979,7 +979,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode =
|
||||||
#result = liftLambdas(prc, result)
|
#result = liftLambdas(prc, result)
|
||||||
when useEffectSystem: trackProc(prc, result)
|
when useEffectSystem: trackProc(prc, result)
|
||||||
result = liftLocalsIfRequested(prc, result)
|
result = liftLocalsIfRequested(prc, result)
|
||||||
if c.needsDestroyPass and newDestructors:
|
if c.needsDestroyPass: #and newDestructors:
|
||||||
result = injectDestructorCalls(prc, result)
|
result = injectDestructorCalls(prc, result)
|
||||||
incl(result.flags, nfTransf)
|
incl(result.flags, nfTransf)
|
||||||
#if prc.name.s == "testbody":
|
#if prc.name.s == "testbody":
|
||||||
|
|
@ -996,7 +996,7 @@ proc transformStmt*(module: PSym, n: PNode): PNode =
|
||||||
when useEffectSystem: trackTopLevelStmt(module, result)
|
when useEffectSystem: trackTopLevelStmt(module, result)
|
||||||
#if n.info ?? "temp.nim":
|
#if n.info ?? "temp.nim":
|
||||||
# echo renderTree(result, {renderIds})
|
# echo renderTree(result, {renderIds})
|
||||||
if c.needsDestroyPass and newDestructors:
|
if c.needsDestroyPass:
|
||||||
result = injectDestructorCalls(module, result)
|
result = injectDestructorCalls(module, result)
|
||||||
incl(result.flags, nfTransf)
|
incl(result.flags, nfTransf)
|
||||||
|
|
||||||
|
|
@ -1007,6 +1007,6 @@ proc transformExpr*(module: PSym, n: PNode): PNode =
|
||||||
var c = openTransf(module, "")
|
var c = openTransf(module, "")
|
||||||
result = processTransf(c, n, module)
|
result = processTransf(c, n, module)
|
||||||
liftDefer(c, result)
|
liftDefer(c, result)
|
||||||
if c.needsDestroyPass and newDestructors:
|
if c.needsDestroyPass:
|
||||||
result = injectDestructorCalls(module, result)
|
result = injectDestructorCalls(module, result)
|
||||||
incl(result.flags, nfTransf)
|
incl(result.flags, nfTransf)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,8 @@ type
|
||||||
wFloatchecks, wNanChecks, wInfChecks, wMoveChecks,
|
wFloatchecks, wNanChecks, wInfChecks, wMoveChecks,
|
||||||
wAssertions, wPatterns, wWarnings,
|
wAssertions, wPatterns, wWarnings,
|
||||||
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
|
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
|
||||||
wDeadCodeElim, wSafecode, wPackage, wNoForward, wReorder, wNoRewrite,
|
wDeadCodeElimUnused, # deprecated, dead code elim always happens
|
||||||
|
wSafecode, wPackage, wNoForward, wReorder, wNoRewrite,
|
||||||
wPragma,
|
wPragma,
|
||||||
wCompileTime, wNoInit,
|
wCompileTime, wNoInit,
|
||||||
wPassc, wPassl, wBorrow, wDiscardable,
|
wPassc, wPassl, wBorrow, wDiscardable,
|
||||||
|
|
@ -143,7 +144,8 @@ const
|
||||||
|
|
||||||
"assertions", "patterns", "warnings", "hints",
|
"assertions", "patterns", "warnings", "hints",
|
||||||
"optimization", "raises", "writes", "reads", "size", "effects", "tags",
|
"optimization", "raises", "writes", "reads", "size", "effects", "tags",
|
||||||
"deadcodeelim", "safecode", "package", "noforward", "reorder", "norewrite",
|
"deadcodeelim", # deprecated, dead code elim always happens
|
||||||
|
"safecode", "package", "noforward", "reorder", "norewrite",
|
||||||
"pragma",
|
"pragma",
|
||||||
"compiletime", "noinit",
|
"compiletime", "noinit",
|
||||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ Advanced options:
|
||||||
--noLinking compile Nim and generated files but do not link
|
--noLinking compile Nim and generated files but do not link
|
||||||
--noMain do not generate a main procedure
|
--noMain do not generate a main procedure
|
||||||
--genScript generate a compile script (in the 'nimcache'
|
--genScript generate a compile script (in the 'nimcache'
|
||||||
subdirectory named 'compile_$project$scriptext')
|
subdirectory named 'compile_$$project$$scriptext'),
|
||||||
|
implies --compileOnly
|
||||||
--genDeps generate a '.deps' file containing the dependencies
|
--genDeps generate a '.deps' file containing the dependencies
|
||||||
--os:SYMBOL set the target operating system (cross-compilation)
|
--os:SYMBOL set the target operating system (cross-compilation)
|
||||||
--cpu:SYMBOL set the target processor (cross-compilation)
|
--cpu:SYMBOL set the target processor (cross-compilation)
|
||||||
|
|
@ -88,5 +89,6 @@ Advanced options:
|
||||||
--parallelBuild:0|1|... perform a parallel build
|
--parallelBuild:0|1|... perform a parallel build
|
||||||
value = number of processors (0 for auto-detect)
|
value = number of processors (0 for auto-detect)
|
||||||
--verbosity:0|1|2|3 set Nim's verbosity level (1 is default)
|
--verbosity:0|1|2|3 set Nim's verbosity level (1 is default)
|
||||||
--experimental enable experimental language features
|
--experimental:$1
|
||||||
|
enable experimental language feature
|
||||||
-v, --version show detailed version information
|
-v, --version show detailed version information
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ Options:
|
||||||
--nanChecks:on|off turn NaN checks on|off
|
--nanChecks:on|off turn NaN checks on|off
|
||||||
--infChecks:on|off turn Inf checks on|off
|
--infChecks:on|off turn Inf checks on|off
|
||||||
--nilChecks:on|off turn nil checks on|off
|
--nilChecks:on|off turn nil checks on|off
|
||||||
--deadCodeElim:on|off whole program dead code elimination on|off
|
|
||||||
--opt:none|speed|size optimize not at all or for speed|size
|
--opt:none|speed|size optimize not at all or for speed|size
|
||||||
Note: use -d:release for a release build!
|
Note: use -d:release for a release build!
|
||||||
--debugger:native|endb use native debugger (gdb) | ENDB (experimental)
|
--debugger:native|endb use native debugger (gdb) | ENDB (experimental)
|
||||||
|
|
|
||||||
|
|
@ -1397,10 +1397,10 @@ dereferencing operations for reference types:
|
||||||
|
|
||||||
Automatic dereferencing is also performed for the first argument of a routine
|
Automatic dereferencing is also performed for the first argument of a routine
|
||||||
call. But currently this feature has to be only enabled
|
call. But currently this feature has to be only enabled
|
||||||
via ``{.experimental.}``:
|
via ``{.experimental: "implicitDeref".}``:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
{.experimental.}
|
{.experimental: "implicitDeref".}
|
||||||
|
|
||||||
proc depth(x: NodeObj): int = ...
|
proc depth(x: NodeObj): int = ...
|
||||||
|
|
||||||
|
|
@ -5588,7 +5588,7 @@ dot operators
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
**Note**: Dot operators are still experimental and so need to be enabled
|
**Note**: Dot operators are still experimental and so need to be enabled
|
||||||
via ``{.experimental.}``.
|
via ``{.experimental: "dotOperators".}``.
|
||||||
|
|
||||||
Nim offers a special family of dot operators that can be used to
|
Nim offers a special family of dot operators that can be used to
|
||||||
intercept and rewrite proc call and field access attempts, referring
|
intercept and rewrite proc call and field access attempts, referring
|
||||||
|
|
@ -6768,22 +6768,6 @@ the created global variables within a module is not defined, but all of them
|
||||||
will be initialized after any top-level variables in their originating module
|
will be initialized after any top-level variables in their originating module
|
||||||
and before any variable in a module that imports it.
|
and before any variable in a module that imports it.
|
||||||
|
|
||||||
deadCodeElim pragma
|
|
||||||
-------------------
|
|
||||||
The ``deadCodeElim`` pragma only applies to whole modules: It tells the
|
|
||||||
compiler to activate (or deactivate) dead code elimination for the module the
|
|
||||||
pragma appears in.
|
|
||||||
|
|
||||||
The ``--deadCodeElim:on`` command line switch has the same effect as marking
|
|
||||||
every module with ``{.deadCodeElim:on}``. However, for some modules such as
|
|
||||||
the GTK wrapper it makes sense to *always* turn on dead code elimination -
|
|
||||||
no matter if it is globally active or not.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
.. code-block:: nim
|
|
||||||
{.deadCodeElim: on.}
|
|
||||||
|
|
||||||
|
|
||||||
..
|
..
|
||||||
NoForward pragma
|
NoForward pragma
|
||||||
|
|
@ -6901,17 +6885,12 @@ is uncertain (it may be removed any time).
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
{.experimental.}
|
{.experimental: "parallel".}
|
||||||
type
|
|
||||||
FooId = distinct int
|
|
||||||
BarId = distinct int
|
|
||||||
using
|
|
||||||
foo: FooId
|
|
||||||
bar: BarId
|
|
||||||
|
|
||||||
proc useUsing(bar, foo) =
|
proc useUsing(bar, foo) =
|
||||||
echo "bar is of type BarId"
|
parallel:
|
||||||
echo "foo is of type FooId"
|
for i in 0..4:
|
||||||
|
echo "echo in parallel"
|
||||||
|
|
||||||
|
|
||||||
Implementation Specific Pragmas
|
Implementation Specific Pragmas
|
||||||
|
|
@ -7933,7 +7912,7 @@ Example:
|
||||||
|
|
||||||
# Compute PI in an inefficient way
|
# Compute PI in an inefficient way
|
||||||
import strutils, math, threadpool
|
import strutils, math, threadpool
|
||||||
{.experimental.}
|
{.experimental: "parallel".}
|
||||||
|
|
||||||
proc term(k: float): float = 4 * math.pow(-1, k) / (2*k + 1)
|
proc term(k: float): float = 4 * math.pow(-1, k) / (2*k + 1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ generated; use the ``--symbolFiles:on`` command line switch to activate them.
|
||||||
|
|
||||||
Unfortunately due to technical reasons the ``--symbolFiles:on`` needs
|
Unfortunately due to technical reasons the ``--symbolFiles:on`` needs
|
||||||
to *aggregate* some generated C code. This means that the resulting executable
|
to *aggregate* some generated C code. This means that the resulting executable
|
||||||
might contain some cruft even when dead code elimination is turned on. So
|
might contain some cruft even with dead code elimination. So
|
||||||
the final release build should be done with ``--symbolFiles:off``.
|
the final release build should be done with ``--symbolFiles:off``.
|
||||||
|
|
||||||
Due to the aggregation of C code it is also recommended that each project
|
Due to the aggregation of C code it is also recommended that each project
|
||||||
|
|
@ -439,7 +439,7 @@ target.
|
||||||
|
|
||||||
For example, to generate code for an `AVR`:idx: processor use this command::
|
For example, to generate code for an `AVR`:idx: processor use this command::
|
||||||
|
|
||||||
nim c --cpu:avr --os:standalone --deadCodeElim:on --genScript x.nim
|
nim c --cpu:avr --os:standalone --genScript x.nim
|
||||||
|
|
||||||
For the ``standalone`` target one needs to provide
|
For the ``standalone`` target one needs to provide
|
||||||
a file ``panicoverride.nim``.
|
a file ``panicoverride.nim``.
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
when hostOS == "solaris":
|
when hostOS == "solaris":
|
||||||
{.passl: "-lsocket -lnsl".}
|
{.passl: "-lsocket -lnsl".}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
##
|
##
|
||||||
## theDb.close()
|
## theDb.close()
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
import strutils, sqlite3
|
import strutils, sqlite3
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
## is used. This suffices because Windows' console already provides the
|
## is used. This suffices because Windows' console already provides the
|
||||||
## wanted functionality.
|
## wanted functionality.
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
proc readLineFromStdin*(prompt: string): TaintedString {.
|
proc readLineFromStdin*(prompt: string): TaintedString {.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
from posix import SocketHandle
|
from posix import SocketHandle
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
# Get the platform-dependent flags.
|
# Get the platform-dependent flags.
|
||||||
# Structure describing an inotify event.
|
# Structure describing an inotify event.
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
|
||||||
|
|
||||||
from posix import Timespec
|
from posix import Timespec
|
||||||
|
|
||||||
when defined(macosx) or defined(freebsd) or defined(openbsd) or
|
when defined(macosx) or defined(freebsd) or defined(openbsd) or
|
||||||
|
|
@ -61,7 +59,7 @@ const
|
||||||
EV_CLEAR* = 0x0020 ## Clear event state after reporting.
|
EV_CLEAR* = 0x0020 ## Clear event state after reporting.
|
||||||
EV_RECEIPT* = 0x0040 ## Force EV_ERROR on success, data == 0
|
EV_RECEIPT* = 0x0040 ## Force EV_ERROR on success, data == 0
|
||||||
EV_DISPATCH* = 0x0080 ## Disable event after reporting.
|
EV_DISPATCH* = 0x0080 ## Disable event after reporting.
|
||||||
|
|
||||||
EV_SYSFLAGS* = 0xF000 ## Reserved by system
|
EV_SYSFLAGS* = 0xF000 ## Reserved by system
|
||||||
EV_DROP* = 0x1000 ## Not should be dropped
|
EV_DROP* = 0x1000 ## Not should be dropped
|
||||||
EV_FLAG1* = 0x2000 ## Filter-specific flag
|
EV_FLAG1* = 0x2000 ## Filter-specific flag
|
||||||
|
|
@ -87,10 +85,10 @@ when defined(macosx) or defined(freebsd) or defined(dragonfly):
|
||||||
NOTE_FFAND* = 0x40000000'u32 ## AND fflags
|
NOTE_FFAND* = 0x40000000'u32 ## AND fflags
|
||||||
NOTE_FFOR* = 0x80000000'u32 ## OR fflags
|
NOTE_FFOR* = 0x80000000'u32 ## OR fflags
|
||||||
NOTE_FFCOPY* = 0xc0000000'u32 ## copy fflags
|
NOTE_FFCOPY* = 0xc0000000'u32 ## copy fflags
|
||||||
NOTE_FFCTRLMASK* = 0xc0000000'u32 ## masks for operations
|
NOTE_FFCTRLMASK* = 0xc0000000'u32 ## masks for operations
|
||||||
NOTE_FFLAGSMASK* = 0x00ffffff'u32
|
NOTE_FFLAGSMASK* = 0x00ffffff'u32
|
||||||
|
|
||||||
NOTE_TRIGGER* = 0x01000000'u32 ## Cause the event to be triggered
|
NOTE_TRIGGER* = 0x01000000'u32 ## Cause the event to be triggered
|
||||||
## for output.
|
## for output.
|
||||||
|
|
||||||
# data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
|
# data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@
|
||||||
## resulting C code will just ``#include <XYZ.h>`` and *not* define the
|
## resulting C code will just ``#include <XYZ.h>`` and *not* define the
|
||||||
## symbols declared here.
|
## symbols declared here.
|
||||||
|
|
||||||
# This ensures that we don't accidentally generate #includes for files that
|
# Dead code elimination ensures that we don't accidentally generate #includes
|
||||||
# might not exist on a specific platform! The user will get an error only
|
# for files that might not exist on a specific platform! The user will get an
|
||||||
# if they actualy try to use the missing declaration
|
# error only if they actualy try to use the missing declaration
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
# TODO these constants don't seem to be fetched from a header file for unknown
|
# TODO these constants don't seem to be fetched from a header file for unknown
|
||||||
# platforms - where do they come from and why are they here?
|
# platforms - where do they come from and why are they here?
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
const
|
const
|
||||||
hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays
|
hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
import posix
|
import posix
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Floating-point environment. Handling of floating-point rounding and
|
## Floating-point environment. Handling of floating-point rounding and
|
||||||
## exceptions (overflow, division by zero, etc.).
|
## exceptions (overflow, division by zero, etc.).
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
when defined(Posix) and not defined(haiku):
|
when defined(Posix) and not defined(haiku):
|
||||||
{.passl: "-lm".}
|
{.passl: "-lm".}
|
||||||
|
|
@ -102,32 +102,33 @@ proc feupdateenv*(envp: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
|
||||||
## represented by object pointed to by `envp` and raise exceptions
|
## represented by object pointed to by `envp` and raise exceptions
|
||||||
## according to saved exceptions.
|
## according to saved exceptions.
|
||||||
|
|
||||||
var FP_RADIX_INTERNAL {. importc: "FLT_RADIX" header: "<float.h>" .} : int
|
const
|
||||||
|
FLT_RADIX = 2 ## the radix of the exponent representation
|
||||||
|
|
||||||
template fpRadix* : int = FP_RADIX_INTERNAL
|
FLT_MANT_DIG = 24 ## the number of base FLT_RADIX digits in the mantissa part of a float
|
||||||
|
FLT_DIG = 6 ## the number of digits of precision of a float
|
||||||
|
FLT_MIN_EXP = -125 # the minimum value of base FLT_RADIX in the exponent part of a float
|
||||||
|
FLT_MAX_EXP = 128 # the maximum value of base FLT_RADIX in the exponent part of a float
|
||||||
|
FLT_MIN_10_EXP = -37 ## the minimum value in base 10 of the exponent part of a float
|
||||||
|
FLT_MAX_10_EXP = 38 ## the maximum value in base 10 of the exponent part of a float
|
||||||
|
FLT_MIN = 1.17549435e-38'f32 ## the minimum value of a float
|
||||||
|
FLT_MAX = 3.40282347e+38'f32 ## the maximum value of a float
|
||||||
|
FLT_EPSILON = 1.19209290e-07'f32 ## the difference between 1 and the least value greater than 1 of a float
|
||||||
|
|
||||||
|
DBL_MANT_DIG = 53 ## the number of base FLT_RADIX digits in the mantissa part of a double
|
||||||
|
DBL_DIG = 15 ## the number of digits of precision of a double
|
||||||
|
DBL_MIN_EXP = -1021 ## the minimum value of base FLT_RADIX in the exponent part of a double
|
||||||
|
DBL_MAX_EXP = 1024 ## the maximum value of base FLT_RADIX in the exponent part of a double
|
||||||
|
DBL_MIN_10_EXP = -307 ## the minimum value in base 10 of the exponent part of a double
|
||||||
|
DBL_MAX_10_EXP = 308 ## the maximum value in base 10 of the exponent part of a double
|
||||||
|
DBL_MIN = 2.2250738585072014E-308 ## the minimal value of a double
|
||||||
|
DBL_MAX = 1.7976931348623157E+308 ## the minimal value of a double
|
||||||
|
DBL_EPSILON = 2.2204460492503131E-16 ## the difference between 1 and the least value greater than 1 of a double
|
||||||
|
|
||||||
|
template fpRadix* : int = FLT_RADIX
|
||||||
## The (integer) value of the radix used to represent any floating
|
## The (integer) value of the radix used to represent any floating
|
||||||
## point type on the architecture used to build the program.
|
## point type on the architecture used to build the program.
|
||||||
|
|
||||||
var FLT_MANT_DIG {. importc: "FLT_MANT_DIG" header: "<float.h>" .} : int
|
|
||||||
var FLT_DIG {. importc: "FLT_DIG" header: "<float.h>" .} : int
|
|
||||||
var FLT_MIN_EXP {. importc: "FLT_MIN_EXP" header: "<float.h>" .} : int
|
|
||||||
var FLT_MAX_EXP {. importc: "FLT_MAX_EXP" header: "<float.h>" .} : int
|
|
||||||
var FLT_MIN_10_EXP {. importc: "FLT_MIN_10_EXP" header: "<float.h>" .} : int
|
|
||||||
var FLT_MAX_10_EXP {. importc: "FLT_MAX_10_EXP" header: "<float.h>" .} : int
|
|
||||||
var FLT_MIN {. importc: "FLT_MIN" header: "<float.h>" .} : cfloat
|
|
||||||
var FLT_MAX {. importc: "FLT_MAX" header: "<float.h>" .} : cfloat
|
|
||||||
var FLT_EPSILON {. importc: "FLT_EPSILON" header: "<float.h>" .} : cfloat
|
|
||||||
|
|
||||||
var DBL_MANT_DIG {. importc: "DBL_MANT_DIG" header: "<float.h>" .} : int
|
|
||||||
var DBL_DIG {. importc: "DBL_DIG" header: "<float.h>" .} : int
|
|
||||||
var DBL_MIN_EXP {. importc: "DBL_MIN_EXP" header: "<float.h>" .} : int
|
|
||||||
var DBL_MAX_EXP {. importc: "DBL_MAX_EXP" header: "<float.h>" .} : int
|
|
||||||
var DBL_MIN_10_EXP {. importc: "DBL_MIN_10_EXP" header: "<float.h>" .} : int
|
|
||||||
var DBL_MAX_10_EXP {. importc: "DBL_MAX_10_EXP" header: "<float.h>" .} : int
|
|
||||||
var DBL_MIN {. importc: "DBL_MIN" header: "<float.h>" .} : cdouble
|
|
||||||
var DBL_MAX {. importc: "DBL_MAX" header: "<float.h>" .} : cdouble
|
|
||||||
var DBL_EPSILON {. importc: "DBL_EPSILON" header: "<float.h>" .} : cdouble
|
|
||||||
|
|
||||||
template mantissaDigits*(T : typedesc[float32]) : int = FLT_MANT_DIG
|
template mantissaDigits*(T : typedesc[float32]) : int = FLT_MANT_DIG
|
||||||
## Number of digits (in base ``floatingPointRadix``) in the mantissa
|
## Number of digits (in base ``floatingPointRadix``) in the mantissa
|
||||||
## of 32-bit floating-point numbers.
|
## of 32-bit floating-point numbers.
|
||||||
|
|
@ -179,3 +180,11 @@ template maximumPositiveValue*(T : typedesc[float64]) : float64 = DBL_MAX
|
||||||
template epsilon*(T : typedesc[float64]): float64 = DBL_EPSILON
|
template epsilon*(T : typedesc[float64]): float64 = DBL_EPSILON
|
||||||
## The difference between 1.0 and the smallest number greater than
|
## The difference between 1.0 and the smallest number greater than
|
||||||
## 1.0 that can be represented in a 64-bit floating-point type.
|
## 1.0 that can be represented in a 64-bit floating-point type.
|
||||||
|
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
func is_significant(x: float): bool =
|
||||||
|
if x > minimumPositiveValue(float) and x < maximumPositiveValue(float): true
|
||||||
|
else: false
|
||||||
|
|
||||||
|
doAssert is_significant(10.0)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
## **Warning:** This module is deprecated since version 0.14.0.
|
## **Warning:** This module is deprecated since version 0.14.0.
|
||||||
{.deprecated.}
|
{.deprecated.}
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
# of the standard library!
|
# of the standard library!
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
## ``newSocket()``. The difference is that the latter creates a new file
|
## ``newSocket()``. The difference is that the latter creates a new file
|
||||||
## descriptor.
|
## descriptor.
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
import nativesockets, os, strutils, parseutils, times, sets, options
|
import nativesockets, os, strutils, parseutils, times, sets, options
|
||||||
export Port, `$`, `==`
|
export Port, `$`, `==`
|
||||||
export Domain, SockType, Protocol
|
export Domain, SockType, Protocol
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module contains basic operating system facilities like
|
## This module contains basic operating system facilities like
|
||||||
## retrieving environment variables, reading command line arguments,
|
## retrieving environment variables, reading command line arguments,
|
||||||
## working with directories, running shell commands, etc.
|
## working with directories, running shell commands, etc.
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
{.push debugger: off.}
|
{.push debugger: off.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
##
|
##
|
||||||
## To unpack raw bytes look at the `streams <streams.html>`_ module.
|
## To unpack raw bytes look at the `streams <streams.html>`_ module.
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
# of the standard library!
|
# of the standard library!
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ when not defined(nimscript):
|
||||||
## Initializes the random number generator with a "random"
|
## Initializes the random number generator with a "random"
|
||||||
## number, i.e. a tickcount. Note: Does not work for NimScript.
|
## number, i.e. a tickcount. Note: Does not work for NimScript.
|
||||||
let now = times.getTime()
|
let now = times.getTime()
|
||||||
randomize(convert(Seconds, Nanoseconds, now.toUnix) + now.nanoseconds)
|
randomize(convert(Seconds, Nanoseconds, now.toUnix) + now.nanosecond)
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
import streams
|
import streams
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
# of the standard library!
|
# of the standard library!
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
import strutils
|
import strutils
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
proc expandTabs*(s: string, tabSize: int = 8): string {.noSideEffect,
|
proc expandTabs*(s: string, tabSize: int = 8): string {.noSideEffect,
|
||||||
procvar.} =
|
procvar.} =
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import parseutils
|
||||||
from math import pow, round, floor, log10
|
from math import pow, round, floor, log10
|
||||||
from algorithm import reverse
|
from algorithm import reverse
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
# of the standard library!
|
# of the standard library!
|
||||||
|
|
@ -1818,20 +1818,29 @@ proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect,
|
||||||
dec(L)
|
dec(L)
|
||||||
|
|
||||||
proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
||||||
rtl, extern: "nsuEscape".} =
|
rtl, extern: "nsuEscape", deprecated.} =
|
||||||
## Escapes a string `s`. See `system.addEscapedChar <system.html#addEscapedChar>`_
|
## Escapes a string `s`. See `system.addEscapedChar <system.html#addEscapedChar>`_
|
||||||
## for the escaping scheme.
|
## for the escaping scheme.
|
||||||
##
|
##
|
||||||
## The resulting string is prefixed with `prefix` and suffixed with `suffix`.
|
## The resulting string is prefixed with `prefix` and suffixed with `suffix`.
|
||||||
## Both may be empty strings.
|
## Both may be empty strings.
|
||||||
|
##
|
||||||
|
## **Warning:** This procedure is deprecated because it's to easy to missuse.
|
||||||
result = newStringOfCap(s.len + s.len shr 2)
|
result = newStringOfCap(s.len + s.len shr 2)
|
||||||
result.add(prefix)
|
result.add(prefix)
|
||||||
for c in items(s):
|
for c in items(s):
|
||||||
result.addEscapedChar(c)
|
case c
|
||||||
|
of '\0'..'\31', '\127'..'\255':
|
||||||
|
add(result, "\\x")
|
||||||
|
add(result, toHex(ord(c), 2))
|
||||||
|
of '\\': add(result, "\\\\")
|
||||||
|
of '\'': add(result, "\\'")
|
||||||
|
of '\"': add(result, "\\\"")
|
||||||
|
else: add(result, c)
|
||||||
add(result, suffix)
|
add(result, suffix)
|
||||||
|
|
||||||
proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
||||||
rtl, extern: "nsuUnescape".} =
|
rtl, extern: "nsuUnescape", deprecated.} =
|
||||||
## Unescapes a string `s`.
|
## Unescapes a string `s`.
|
||||||
##
|
##
|
||||||
## This complements `escape <#escape>`_ as it performs the opposite
|
## This complements `escape <#escape>`_ as it performs the opposite
|
||||||
|
|
@ -1839,6 +1848,8 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
||||||
##
|
##
|
||||||
## If `s` does not begin with ``prefix`` and end with ``suffix`` a
|
## If `s` does not begin with ``prefix`` and end with ``suffix`` a
|
||||||
## ValueError exception will be raised.
|
## ValueError exception will be raised.
|
||||||
|
##
|
||||||
|
## **Warning:** This procedure is deprecated because it's to easy to missuse.
|
||||||
result = newStringOfCap(s.len)
|
result = newStringOfCap(s.len)
|
||||||
var i = prefix.len
|
var i = prefix.len
|
||||||
if not s.startsWith(prefix):
|
if not s.startsWith(prefix):
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ type
|
||||||
|
|
||||||
Time* = object ## Represents a point in time.
|
Time* = object ## Represents a point in time.
|
||||||
seconds: int64
|
seconds: int64
|
||||||
nanoseconds: NanosecondRange
|
nanosecond: NanosecondRange
|
||||||
|
|
||||||
DateTime* = object of RootObj ## Represents a time in different parts.
|
DateTime* = object of RootObj ## Represents a time in different parts.
|
||||||
## Although this type can represent leap
|
## Although this type can represent leap
|
||||||
|
|
@ -159,7 +159,7 @@ type
|
||||||
## This type should be prefered over ``TimeInterval`` unless
|
## This type should be prefered over ``TimeInterval`` unless
|
||||||
## non-static time units is needed.
|
## non-static time units is needed.
|
||||||
seconds: int64
|
seconds: int64
|
||||||
nanoseconds: NanosecondRange
|
nanosecond: NanosecondRange
|
||||||
|
|
||||||
TimeUnit* = enum ## Different units of time.
|
TimeUnit* = enum ## Different units of time.
|
||||||
Nanoseconds, Microseconds, Milliseconds, Seconds, Minutes, Hours, Days, Weeks, Months, Years
|
Nanoseconds, Microseconds, Milliseconds, Seconds, Minutes, Hours, Days, Weeks, Months, Years
|
||||||
|
|
@ -223,21 +223,21 @@ proc normalize[T: Duration|Time](seconds, nanoseconds: int64): T =
|
||||||
## a ``Duration`` or ``Time``. A normalized ``Duration|Time`` has a
|
## a ``Duration`` or ``Time``. A normalized ``Duration|Time`` has a
|
||||||
## positive nanosecond part in the range ``NanosecondRange``.
|
## positive nanosecond part in the range ``NanosecondRange``.
|
||||||
result.seconds = seconds + convert(Nanoseconds, Seconds, nanoseconds)
|
result.seconds = seconds + convert(Nanoseconds, Seconds, nanoseconds)
|
||||||
var nanoseconds = nanoseconds mod convert(Seconds, Nanoseconds, 1)
|
var nanosecond = nanoseconds mod convert(Seconds, Nanoseconds, 1)
|
||||||
if nanoseconds < 0:
|
if nanosecond < 0:
|
||||||
nanoseconds += convert(Seconds, Nanoseconds, 1)
|
nanosecond += convert(Seconds, Nanoseconds, 1)
|
||||||
result.seconds -= 1
|
result.seconds -= 1
|
||||||
result.nanoseconds = nanoseconds.int
|
result.nanosecond = nanosecond.int
|
||||||
|
|
||||||
proc initTime*(unix: int64, nanoseconds: NanosecondRange): Time =
|
proc initTime*(unix: int64, nanosecond: NanosecondRange): Time =
|
||||||
## Create a ``Time`` from a unix timestamp and a nanosecond part.
|
## Create a ``Time`` from a unix timestamp and a nanosecond part.
|
||||||
result.seconds = unix
|
result.seconds = unix
|
||||||
result.nanoseconds = nanoseconds
|
result.nanosecond = nanosecond
|
||||||
|
|
||||||
proc nanoseconds*(time: Time): NanosecondRange =
|
proc nanosecond*(time: Time): NanosecondRange =
|
||||||
## Get the fractional part of a ``Time`` as the number
|
## Get the fractional part of a ``Time`` as the number
|
||||||
## of nanoseconds of the second.
|
## of nanoseconds of the second.
|
||||||
time.nanoseconds
|
time.nanosecond
|
||||||
|
|
||||||
proc initDuration*(nanoseconds, microseconds, milliseconds,
|
proc initDuration*(nanoseconds, microseconds, milliseconds,
|
||||||
seconds, minutes, hours, days, weeks: int64 = 0): Duration =
|
seconds, minutes, hours, days, weeks: int64 = 0): Duration =
|
||||||
|
|
@ -281,7 +281,7 @@ proc milliseconds*(dur: Duration): int {.inline.} =
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let dur = initDuration(seconds = 1, milliseconds = 1)
|
let dur = initDuration(seconds = 1, milliseconds = 1)
|
||||||
doAssert dur.milliseconds == 1
|
doAssert dur.milliseconds == 1
|
||||||
convert(Nanoseconds, Milliseconds, dur.nanoseconds)
|
convert(Nanoseconds, Milliseconds, dur.nanosecond)
|
||||||
|
|
||||||
proc microseconds*(dur: Duration): int {.inline.} =
|
proc microseconds*(dur: Duration): int {.inline.} =
|
||||||
## Number of whole microseconds represented by the **fractional**
|
## Number of whole microseconds represented by the **fractional**
|
||||||
|
|
@ -289,7 +289,7 @@ proc microseconds*(dur: Duration): int {.inline.} =
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let dur = initDuration(seconds = 1, microseconds = 1)
|
let dur = initDuration(seconds = 1, microseconds = 1)
|
||||||
doAssert dur.microseconds == 1
|
doAssert dur.microseconds == 1
|
||||||
convert(Nanoseconds, Microseconds, dur.nanoseconds)
|
convert(Nanoseconds, Microseconds, dur.nanosecond)
|
||||||
|
|
||||||
proc nanoseconds*(dur: Duration): int {.inline.} =
|
proc nanoseconds*(dur: Duration): int {.inline.} =
|
||||||
## Number of whole nanoseconds represented by the **fractional**
|
## Number of whole nanoseconds represented by the **fractional**
|
||||||
|
|
@ -297,14 +297,14 @@ proc nanoseconds*(dur: Duration): int {.inline.} =
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let dur = initDuration(seconds = 1, nanoseconds = 1)
|
let dur = initDuration(seconds = 1, nanoseconds = 1)
|
||||||
doAssert dur.nanoseconds == 1
|
doAssert dur.nanoseconds == 1
|
||||||
dur.nanoseconds
|
dur.nanosecond
|
||||||
|
|
||||||
proc fractional*(dur: Duration): Duration {.inline.} =
|
proc fractional*(dur: Duration): Duration {.inline.} =
|
||||||
## The fractional part of duration, as a duration.
|
## The fractional part of duration, as a duration.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let dur = initDuration(seconds = 1, nanoseconds = 5)
|
let dur = initDuration(seconds = 1, nanoseconds = 5)
|
||||||
doAssert dur.fractional == initDuration(nanoseconds = 5)
|
doAssert dur.fractional == initDuration(nanoseconds = 5)
|
||||||
initDuration(nanoseconds = dur.nanoseconds)
|
initDuration(nanoseconds = dur.nanosecond)
|
||||||
|
|
||||||
const DurationZero* = initDuration() ## Zero value for durations. Useful for comparisons.
|
const DurationZero* = initDuration() ## Zero value for durations. Useful for comparisons.
|
||||||
##
|
##
|
||||||
|
|
@ -322,7 +322,7 @@ proc `$`*(dur: Duration): string =
|
||||||
doAssert $initDuration(milliseconds = -1500) == "-1 second and -500 milliseconds"
|
doAssert $initDuration(milliseconds = -1500) == "-1 second and -500 milliseconds"
|
||||||
var parts = newSeq[string]()
|
var parts = newSeq[string]()
|
||||||
var remS = dur.seconds
|
var remS = dur.seconds
|
||||||
var remNs = dur.nanoseconds.int
|
var remNs = dur.nanosecond.int
|
||||||
|
|
||||||
# Normally ``nanoseconds`` should always be positive, but
|
# Normally ``nanoseconds`` should always be positive, but
|
||||||
# that makes no sense when printing.
|
# that makes no sense when printing.
|
||||||
|
|
@ -387,7 +387,7 @@ proc fromWinTime*(win: int64): Time =
|
||||||
|
|
||||||
proc toWinTime*(t: Time): int64 =
|
proc toWinTime*(t: Time): int64 =
|
||||||
## Convert ``t`` to a Windows file time (100-nanosecond intervals since ``1601-01-01T00:00:00Z``).
|
## Convert ``t`` to a Windows file time (100-nanosecond intervals since ``1601-01-01T00:00:00Z``).
|
||||||
result = t.seconds * rateDiff + epochDiff + t.nanoseconds div 100
|
result = t.seconds * rateDiff + epochDiff + t.nanosecond div 100
|
||||||
|
|
||||||
proc isLeapYear*(year: int): bool =
|
proc isLeapYear*(year: int): bool =
|
||||||
## Returns true if ``year`` is a leap year.
|
## Returns true if ``year`` is a leap year.
|
||||||
|
|
@ -473,21 +473,21 @@ proc localZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benig
|
||||||
{. pragma: operator, rtl, noSideEffect, benign .}
|
{. pragma: operator, rtl, noSideEffect, benign .}
|
||||||
|
|
||||||
template subImpl[T: Duration|Time](a: Duration|Time, b: Duration|Time): T =
|
template subImpl[T: Duration|Time](a: Duration|Time, b: Duration|Time): T =
|
||||||
normalize[T](a.seconds - b.seconds, a.nanoseconds - b.nanoseconds)
|
normalize[T](a.seconds - b.seconds, a.nanosecond - b.nanosecond)
|
||||||
|
|
||||||
template addImpl[T: Duration|Time](a: Duration|Time, b: Duration|Time): T =
|
template addImpl[T: Duration|Time](a: Duration|Time, b: Duration|Time): T =
|
||||||
normalize[T](a.seconds + b.seconds, a.nanoseconds + b.nanoseconds)
|
normalize[T](a.seconds + b.seconds, a.nanosecond + b.nanosecond)
|
||||||
|
|
||||||
template ltImpl(a: Duration|Time, b: Duration|Time): bool =
|
template ltImpl(a: Duration|Time, b: Duration|Time): bool =
|
||||||
a.seconds < b.seconds or (
|
a.seconds < b.seconds or (
|
||||||
a.seconds == b.seconds and a.nanoseconds < b.nanoseconds)
|
a.seconds == b.seconds and a.nanosecond < b.nanosecond)
|
||||||
|
|
||||||
template lqImpl(a: Duration|Time, b: Duration|Time): bool =
|
template lqImpl(a: Duration|Time, b: Duration|Time): bool =
|
||||||
a.seconds <= b.seconds or (
|
a.seconds < b.seconds or (
|
||||||
a.seconds == b.seconds and a.nanoseconds <= b.seconds)
|
a.seconds == b.seconds and a.nanosecond <= b.nanosecond)
|
||||||
|
|
||||||
template eqImpl(a: Duration|Time, b: Duration|Time): bool =
|
template eqImpl(a: Duration|Time, b: Duration|Time): bool =
|
||||||
a.seconds == b.seconds and a.nanoseconds == b.nanoseconds
|
a.seconds == b.seconds and a.nanosecond == b.nanosecond
|
||||||
|
|
||||||
proc `+`*(a, b: Duration): Duration {.operator.} =
|
proc `+`*(a, b: Duration): Duration {.operator.} =
|
||||||
## Add two durations together.
|
## Add two durations together.
|
||||||
|
|
@ -507,7 +507,7 @@ proc `-`*(a: Duration): Duration {.operator.} =
|
||||||
## Reverse a duration.
|
## Reverse a duration.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
doAssert -initDuration(seconds = 1) == initDuration(seconds = -1)
|
doAssert -initDuration(seconds = 1) == initDuration(seconds = -1)
|
||||||
normalize[Duration](-a.seconds, -a.nanoseconds)
|
normalize[Duration](-a.seconds, -a.nanosecond)
|
||||||
|
|
||||||
proc `<`*(a, b: Duration): bool {.operator.} =
|
proc `<`*(a, b: Duration): bool {.operator.} =
|
||||||
## Note that a duration can be negative,
|
## Note that a duration can be negative,
|
||||||
|
|
@ -530,7 +530,7 @@ proc `*`*(a: int64, b: Duration): Duration {.operator} =
|
||||||
## Multiply a duration by some scalar.
|
## Multiply a duration by some scalar.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
doAssert 5 * initDuration(seconds = 1) == initDuration(seconds = 5)
|
doAssert 5 * initDuration(seconds = 1) == initDuration(seconds = 5)
|
||||||
normalize[Duration](a * b.seconds, a * b.nanoseconds)
|
normalize[Duration](a * b.seconds, a * b.nanosecond)
|
||||||
|
|
||||||
proc `*`*(a: Duration, b: int64): Duration {.operator} =
|
proc `*`*(a: Duration, b: int64): Duration {.operator} =
|
||||||
## Multiply a duration by some scalar.
|
## Multiply a duration by some scalar.
|
||||||
|
|
@ -544,7 +544,7 @@ proc `div`*(a: Duration, b: int64): Duration {.operator} =
|
||||||
doAssert initDuration(seconds = 3) div 2 == initDuration(milliseconds = 1500)
|
doAssert initDuration(seconds = 3) div 2 == initDuration(milliseconds = 1500)
|
||||||
doAssert initDuration(nanoseconds = 3) div 2 == initDuration(nanoseconds = 1)
|
doAssert initDuration(nanoseconds = 3) div 2 == initDuration(nanoseconds = 1)
|
||||||
let carryOver = convert(Seconds, Nanoseconds, a.seconds mod b)
|
let carryOver = convert(Seconds, Nanoseconds, a.seconds mod b)
|
||||||
normalize[Duration](a.seconds div b, (a.nanoseconds + carryOver) div b)
|
normalize[Duration](a.seconds div b, (a.nanosecond + carryOver) div b)
|
||||||
|
|
||||||
proc `-`*(a, b: Time): Duration {.operator, extern: "ntDiffTime".} =
|
proc `-`*(a, b: Time): Duration {.operator, extern: "ntDiffTime".} =
|
||||||
## Computes the duration between two points in time.
|
## Computes the duration between two points in time.
|
||||||
|
|
@ -600,7 +600,7 @@ proc abs*(a: Duration): Duration =
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
doAssert initDuration(milliseconds = -1500).abs ==
|
doAssert initDuration(milliseconds = -1500).abs ==
|
||||||
initDuration(milliseconds = 1500)
|
initDuration(milliseconds = 1500)
|
||||||
initDuration(seconds = abs(a.seconds), nanoseconds = -a.nanoseconds)
|
initDuration(seconds = abs(a.seconds), nanoseconds = -a.nanosecond)
|
||||||
|
|
||||||
proc toTime*(dt: DateTime): Time {.tags: [], raises: [], benign.} =
|
proc toTime*(dt: DateTime): Time {.tags: [], raises: [], benign.} =
|
||||||
## Converts a broken-down time structure to
|
## Converts a broken-down time structure to
|
||||||
|
|
@ -650,7 +650,7 @@ proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime =
|
||||||
hour: hour,
|
hour: hour,
|
||||||
minute: minute,
|
minute: minute,
|
||||||
second: second,
|
second: second,
|
||||||
nanosecond: zt.adjTime.nanoseconds,
|
nanosecond: zt.adjTime.nanosecond,
|
||||||
weekday: getDayOfWeek(d, m, y),
|
weekday: getDayOfWeek(d, m, y),
|
||||||
yearday: getDayOfYear(d, m, y),
|
yearday: getDayOfYear(d, m, y),
|
||||||
isDst: zt.isDst,
|
isDst: zt.isDst,
|
||||||
|
|
@ -809,7 +809,7 @@ else:
|
||||||
# as a result of offset changes (normally due to dst)
|
# as a result of offset changes (normally due to dst)
|
||||||
let utcUnix = adjTime.seconds + utcOffset
|
let utcUnix = adjTime.seconds + utcOffset
|
||||||
let (finalOffset, dst) = getLocalOffsetAndDst(utcUnix)
|
let (finalOffset, dst) = getLocalOffsetAndDst(utcUnix)
|
||||||
result.adjTime = initTime(utcUnix - finalOffset, adjTime.nanoseconds)
|
result.adjTime = initTime(utcUnix - finalOffset, adjTime.nanosecond)
|
||||||
result.utcOffset = finalOffset
|
result.utcOffset = finalOffset
|
||||||
result.isDst = dst
|
result.isDst = dst
|
||||||
|
|
||||||
|
|
@ -1806,7 +1806,7 @@ proc toSeconds*(time: Time): float {.tags: [], raises: [], benign, deprecated.}
|
||||||
## Returns the time in seconds since the unix epoch.
|
## Returns the time in seconds since the unix epoch.
|
||||||
##
|
##
|
||||||
## **Deprecated since v0.18.0:** use ``fromUnix`` instead
|
## **Deprecated since v0.18.0:** use ``fromUnix`` instead
|
||||||
time.seconds.float + time.nanoseconds / convert(Seconds, Nanoseconds, 1)
|
time.seconds.float + time.nanosecond / convert(Seconds, Nanoseconds, 1)
|
||||||
|
|
||||||
proc getLocalTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
|
proc getLocalTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
|
||||||
## Converts the calendar time `time` to broken-time representation,
|
## Converts the calendar time `time` to broken-time representation,
|
||||||
|
|
@ -1853,7 +1853,7 @@ when defined(JS):
|
||||||
## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead.
|
## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead.
|
||||||
let dur = getTime() - start
|
let dur = getTime() - start
|
||||||
result = (convert(Seconds, Milliseconds, dur.seconds) +
|
result = (convert(Seconds, Milliseconds, dur.seconds) +
|
||||||
convert(Nanoseconds, Milliseconds, dur.nanoseconds)).int
|
convert(Nanoseconds, Milliseconds, dur.nanosecond)).int
|
||||||
else:
|
else:
|
||||||
proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} =
|
proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} =
|
||||||
when defined(macosx):
|
when defined(macosx):
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## This module provides support to handle the Unicode UTF-8 encoding.
|
## This module provides support to handle the Unicode UTF-8 encoding.
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@
|
||||||
import macros, strtabs
|
import macros, strtabs
|
||||||
|
|
||||||
type
|
type
|
||||||
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s.
|
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``XmlNode``'s.
|
||||||
|
|
||||||
XmlNodeKind* = enum ## different kinds of ``PXmlNode``'s
|
XmlNodeKind* = enum ## different kinds of ``XmlNode``'s
|
||||||
xnText, ## a text element
|
xnText, ## a text element
|
||||||
xnElement, ## an element with 0 or more children
|
xnElement, ## an element with 0 or more children
|
||||||
xnCData, ## a CDATA node
|
xnCData, ## a CDATA node
|
||||||
|
|
@ -315,9 +315,7 @@ proc newXmlTree*(tag: string, children: openArray[XmlNode],
|
||||||
for i in 0..children.len-1: result.s[i] = children[i]
|
for i in 0..children.len-1: result.s[i] = children[i]
|
||||||
result.fAttr = attributes
|
result.fAttr = attributes
|
||||||
|
|
||||||
proc xmlConstructor(e: NimNode): NimNode {.compileTime.} =
|
proc xmlConstructor(a: NimNode): NimNode {.compileTime.} =
|
||||||
expectLen(e, 2)
|
|
||||||
var a = e[1]
|
|
||||||
if a.kind == nnkCall:
|
if a.kind == nnkCall:
|
||||||
result = newCall("newXmlTree", toStrLit(a[0]))
|
result = newCall("newXmlTree", toStrLit(a[0]))
|
||||||
var attrs = newNimNode(nnkBracket, a)
|
var attrs = newNimNode(nnkBracket, a)
|
||||||
|
|
@ -348,7 +346,6 @@ macro `<>`*(x: untyped): untyped =
|
||||||
##
|
##
|
||||||
## <a href="http://nim-lang.org">Nim rules.</a>
|
## <a href="http://nim-lang.org">Nim rules.</a>
|
||||||
##
|
##
|
||||||
let x = callsite()
|
|
||||||
result = xmlConstructor(x)
|
result = xmlConstructor(x)
|
||||||
|
|
||||||
proc child*(n: XmlNode, name: string): XmlNode =
|
proc child*(n: XmlNode, name: string): XmlNode =
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ proc declared*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
||||||
## # missing it.
|
## # missing it.
|
||||||
|
|
||||||
when defined(useNimRtl):
|
when defined(useNimRtl):
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
proc definedInScope*(x: untyped): bool {.
|
proc definedInScope*(x: untyped): bool {.
|
||||||
magic: "DefinedInScope", noSideEffect, deprecated, compileTime.}
|
magic: "DefinedInScope", noSideEffect, deprecated, compileTime.}
|
||||||
|
|
@ -3933,29 +3933,48 @@ proc addEscapedChar*(s: var string, c: char) {.noSideEffect, inline.} =
|
||||||
## * replaces any ``\`` by ``\\``
|
## * replaces any ``\`` by ``\\``
|
||||||
## * replaces any ``'`` by ``\'``
|
## * replaces any ``'`` by ``\'``
|
||||||
## * replaces any ``"`` by ``\"``
|
## * replaces any ``"`` by ``\"``
|
||||||
## * replaces any other character in the set ``{'\0'..'\31', '\127'..'\255'}``
|
## * replaces any ``\a`` by ``\\a``
|
||||||
|
## * replaces any ``\b`` by ``\\b``
|
||||||
|
## * replaces any ``\t`` by ``\\t``
|
||||||
|
## * replaces any ``\n`` by ``\\n``
|
||||||
|
## * replaces any ``\v`` by ``\\v``
|
||||||
|
## * replaces any ``\f`` by ``\\f``
|
||||||
|
## * replaces any ``\c`` by ``\\c``
|
||||||
|
## * replaces any ``\e`` by ``\\e``
|
||||||
|
## * replaces any other character not in the set ``{'\21..'\126'}
|
||||||
## by ``\xHH`` where ``HH`` is its hexadecimal value.
|
## by ``\xHH`` where ``HH`` is its hexadecimal value.
|
||||||
##
|
##
|
||||||
## The procedure has been designed so that its output is usable for many
|
## The procedure has been designed so that its output is usable for many
|
||||||
## different common syntaxes.
|
## different common syntaxes.
|
||||||
## **Note**: This is not correct for producing Ansi C code!
|
## **Note**: This is not correct for producing Ansi C code!
|
||||||
case c
|
case c
|
||||||
of '\0'..'\31', '\127'..'\255':
|
of '\a': s.add "\\a" # \x07
|
||||||
add(s, "\\x")
|
of '\b': s.add "\\b" # \x08
|
||||||
|
of '\t': s.add "\\t" # \x09
|
||||||
|
of '\n': s.add "\\n" # \x0A
|
||||||
|
of '\v': s.add "\\v" # \x0B
|
||||||
|
of '\f': s.add "\\f" # \x0C
|
||||||
|
of '\c': s.add "\\c" # \x0D
|
||||||
|
of '\e': s.add "\\e" # \x1B
|
||||||
|
of '\\': s.add("\\\\")
|
||||||
|
of '\'': s.add("\\'")
|
||||||
|
of '\"': s.add("\\\"")
|
||||||
|
of {'\32'..'\126'} - {'\\', '\'', '\"'}: s.add(c)
|
||||||
|
else:
|
||||||
|
s.add("\\x")
|
||||||
const HexChars = "0123456789ABCDEF"
|
const HexChars = "0123456789ABCDEF"
|
||||||
let n = ord(c)
|
let n = ord(c)
|
||||||
s.add(HexChars[int((n and 0xF0) shr 4)])
|
s.add(HexChars[int((n and 0xF0) shr 4)])
|
||||||
s.add(HexChars[int(n and 0xF)])
|
s.add(HexChars[int(n and 0xF)])
|
||||||
of '\\': add(s, "\\\\")
|
|
||||||
of '\'': add(s, "\\'")
|
|
||||||
of '\"': add(s, "\\\"")
|
|
||||||
else: add(s, c)
|
|
||||||
|
|
||||||
proc addQuoted*[T](s: var string, x: T) =
|
proc addQuoted*[T](s: var string, x: T) =
|
||||||
## Appends `x` to string `s` in place, applying quoting and escaping
|
## Appends `x` to string `s` in place, applying quoting and escaping
|
||||||
## if `x` is a string or char. See
|
## if `x` is a string or char. See
|
||||||
## `addEscapedChar <system.html#addEscapedChar>`_
|
## `addEscapedChar <system.html#addEscapedChar>`_
|
||||||
## for the escaping scheme.
|
## for the escaping scheme. When `x` is a string, characters in the
|
||||||
|
## range ``{\128..\255}`` are never escaped so that multibyte UTF-8
|
||||||
|
## characters are untouched (note that this behavior is different from
|
||||||
|
## ``addEscapedChar``).
|
||||||
##
|
##
|
||||||
## The Nim standard library uses this function on the elements of
|
## The Nim standard library uses this function on the elements of
|
||||||
## collections when producing a string representation of a collection.
|
## collections when producing a string representation of a collection.
|
||||||
|
|
@ -3974,7 +3993,12 @@ proc addQuoted*[T](s: var string, x: T) =
|
||||||
when T is string:
|
when T is string:
|
||||||
s.add("\"")
|
s.add("\"")
|
||||||
for c in x:
|
for c in x:
|
||||||
s.addEscapedChar(c)
|
# Only ASCII chars are escaped to avoid butchering
|
||||||
|
# multibyte UTF-8 characters.
|
||||||
|
if c <= 127.char:
|
||||||
|
s.addEscapedChar(c)
|
||||||
|
else:
|
||||||
|
s.add c
|
||||||
s.add("\"")
|
s.add("\"")
|
||||||
elif T is char:
|
elif T is char:
|
||||||
s.add("'")
|
s.add("'")
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module implements a small wrapper for some needed Win API procedures,
|
## This module implements a small wrapper for some needed Win API procedures,
|
||||||
## so that the Nim compiler does not depend on the huge Windows module.
|
## so that the Nim compiler does not depend on the huge Windows module.
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
import dynlib
|
import dynlib
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
# ****************************************************************************
|
# ****************************************************************************
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
const dllname = "iup(|30|27|26|25|24).dll"
|
const dllname = "iup(|30|27|26|25|24).dll"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
{.push, callconv: cdecl.}
|
{.push, callconv: cdecl.}
|
||||||
|
|
||||||
when defined(Unix):
|
when defined(Unix):
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
when not defined(ODBCVER):
|
when not defined(ODBCVER):
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
## ./bin/nim c -d:ssl -p:. -r tests/untestable/tssl.nim
|
## ./bin/nim c -d:ssl -p:. -r tests/untestable/tssl.nim
|
||||||
## ./bin/nim c -d:ssl -p:. --dynlibOverride:ssl --passL:-lcrypto --passL:-lssl -r tests/untestable/tssl.nim
|
## ./bin/nim c -d:ssl -p:. --dynlibOverride:ssl --passL:-lcrypto --passL:-lssl -r tests/untestable/tssl.nim
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
const useWinVersion = defined(Windows) or defined(nimdoc)
|
const useWinVersion = defined(Windows) or defined(nimdoc)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
# The current PCRE version information.
|
# The current PCRE version information.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
# connection-protocol.
|
# connection-protocol.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.} # dce option deprecated
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
when defined(nimOldDlls):
|
when defined(nimOldDlls):
|
||||||
const Lib = "sqlite3.dll"
|
const Lib = "sqlite3.dll"
|
||||||
|
|
|
||||||
|
|
@ -518,7 +518,7 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
|
||||||
close(requests)
|
close(requests)
|
||||||
close(results)
|
close(results)
|
||||||
|
|
||||||
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
proc processCmdLine*(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||||
var p = parseopt.initOptParser(cmd)
|
var p = parseopt.initOptParser(cmd)
|
||||||
while true:
|
while true:
|
||||||
parseopt.next(p)
|
parseopt.next(p)
|
||||||
|
|
@ -562,7 +562,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||||
gRefresh = true
|
gRefresh = true
|
||||||
of "maxresults":
|
of "maxresults":
|
||||||
suggestMaxResults = parseInt(p.val)
|
suggestMaxResults = parseInt(p.val)
|
||||||
else: processSwitch(pass, p)
|
else: processSwitch(pass, p, config)
|
||||||
of cmdArgument:
|
of cmdArgument:
|
||||||
let a = unixToNativePath(p.key)
|
let a = unixToNativePath(p.key)
|
||||||
if dirExists(a) and not fileExists(a.addFileExt("nim")):
|
if dirExists(a) and not fileExists(a.addFileExt("nim")):
|
||||||
|
|
@ -577,7 +577,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
if paramCount() == 0:
|
if paramCount() == 0:
|
||||||
stdout.writeline(Usage)
|
stdout.writeline(Usage)
|
||||||
else:
|
else:
|
||||||
processCmdLine(passCmd1, "")
|
processCmdLine(passCmd1, "", config)
|
||||||
if gMode != mstdin:
|
if gMode != mstdin:
|
||||||
msgs.writelnHook = proc (msg: string) = discard
|
msgs.writelnHook = proc (msg: string) = discard
|
||||||
if gProjectName != "":
|
if gProjectName != "":
|
||||||
|
|
@ -616,7 +616,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
runNimScript(cache, gProjectPath / "config.nims", freshDefines=false, config)
|
runNimScript(cache, gProjectPath / "config.nims", freshDefines=false, config)
|
||||||
|
|
||||||
extccomp.initVars()
|
extccomp.initVars()
|
||||||
processCmdLine(passCmd2, "")
|
processCmdLine(passCmd2, "", config)
|
||||||
|
|
||||||
let graph = newModuleGraph(config)
|
let graph = newModuleGraph(config)
|
||||||
graph.suggestMode = true
|
graph.suggestMode = true
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ GenericT[T] '=' bool
|
||||||
GenericT[T] '=' bool
|
GenericT[T] '=' bool
|
||||||
GenericT[T] '=' bool
|
GenericT[T] '=' bool
|
||||||
GenericT[T] '=' bool'''
|
GenericT[T] '=' bool'''
|
||||||
|
disabled: "true"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import typetraits
|
import typetraits
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''i value 88
|
output: '''i value 88
|
||||||
2aa'''
|
2aa'''
|
||||||
|
disabled: "true"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import moverload_asgn2
|
import moverload_asgn2
|
||||||
|
|
|
||||||
|
|
@ -85,14 +85,20 @@ block:
|
||||||
s.addQuoted('\0')
|
s.addQuoted('\0')
|
||||||
s.addQuoted('\31')
|
s.addQuoted('\31')
|
||||||
s.addQuoted('\127')
|
s.addQuoted('\127')
|
||||||
s.addQuoted('\255')
|
doAssert s == "'\\x00''\\x1F''\\x7F'"
|
||||||
doAssert s == "'\\x00''\\x1F''\\x7F''\\xFF'"
|
|
||||||
block:
|
block:
|
||||||
var s = ""
|
var s = ""
|
||||||
s.addQuoted('\\')
|
s.addQuoted('\\')
|
||||||
s.addQuoted('\'')
|
s.addQuoted('\'')
|
||||||
s.addQuoted('\"')
|
s.addQuoted('\"')
|
||||||
doAssert s == """'\\''\'''\"'"""
|
doAssert s == """'\\''\'''\"'"""
|
||||||
|
block:
|
||||||
|
var s = ""
|
||||||
|
s.addQuoted("å")
|
||||||
|
s.addQuoted("ä")
|
||||||
|
s.addQuoted("ö")
|
||||||
|
s.addEscapedChar('\xFF')
|
||||||
|
doAssert s == """"å""ä""ö"\xFF"""
|
||||||
|
|
||||||
# Test customized element representation
|
# Test customized element representation
|
||||||
type CustomString = object
|
type CustomString = object
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ type
|
||||||
TOption = enum
|
TOption = enum
|
||||||
optNone, optForceFullMake, optBoehmGC, optRefcGC, optRangeCheck,
|
optNone, optForceFullMake, optBoehmGC, optRefcGC, optRangeCheck,
|
||||||
optBoundsCheck, optOverflowCheck, optNilCheck, optAssert, optLineDir,
|
optBoundsCheck, optOverflowCheck, optNilCheck, optAssert, optLineDir,
|
||||||
optWarns, optHints, optDeadCodeElim, optListCmd, optCompileOnly,
|
optWarns, optHints, optListCmd, optCompileOnly,
|
||||||
optSafeCode, # only allow safe code
|
optSafeCode, # only allow safe code
|
||||||
optStyleCheck, optOptimizeSpeed, optOptimizeSize, optGenDynLib,
|
optStyleCheck, optOptimizeSpeed, optOptimizeSize, optGenDynLib,
|
||||||
optGenGuiApp, optStackTrace
|
optGenGuiApp, optStackTrace
|
||||||
|
|
|
||||||
5
tests/flags/tgenscript.nim
Normal file
5
tests/flags/tgenscript.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
discard """
|
||||||
|
file: "tgenscript.nim"
|
||||||
|
"""
|
||||||
|
|
||||||
|
echo "--genscript"
|
||||||
|
|
@ -4,8 +4,6 @@ discard """
|
||||||
|
|
||||||
# bug #2023
|
# bug #2023
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Obj = object
|
Obj = object
|
||||||
iter: iterator (): int8 {.closure.}
|
iter: iterator (): int8 {.closure.}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ const Lib = "libchipmunk.so.6.1.1"
|
||||||
|
|
||||||
when defined(MoreNim):
|
when defined(MoreNim):
|
||||||
{.hint: "MoreNim defined; some Chipmunk functions replaced in Nim".}
|
{.hint: "MoreNim defined; some Chipmunk functions replaced in Nim".}
|
||||||
{.deadCodeElim: on.}
|
|
||||||
from math import sqrt, sin, cos, arctan2
|
from math import sqrt, sin, cos, arctan2
|
||||||
when defined(CpUseFloat):
|
when defined(CpUseFloat):
|
||||||
{.hint: "CpUseFloat defined; using float32 as float".}
|
{.hint: "CpUseFloat defined; using float32 as float".}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
const Lib = "libenet.so.1(|.0.3)"
|
const Lib = "libenet.so.1(|.0.3)"
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
|
||||||
const
|
const
|
||||||
ENET_VERSION_MAJOR* = 1
|
ENET_VERSION_MAJOR* = 1
|
||||||
ENET_VERSION_MINOR* = 3
|
ENET_VERSION_MINOR* = 3
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import macros
|
import macros
|
||||||
{.deadCodeElim: on.}
|
|
||||||
#Inline macro.add() to allow for easier nesting
|
#Inline macro.add() to allow for easier nesting
|
||||||
proc und*(a: NimNode; b: NimNode): NimNode {.compileTime.} =
|
proc und*(a: NimNode; b: NimNode): NimNode {.compileTime.} =
|
||||||
a.add(b)
|
a.add(b)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ else:
|
||||||
LibS = "libcsfml-system.so.2.0"
|
LibS = "libcsfml-system.so.2.0"
|
||||||
LibW = "libcsfml-window.so.2.0"
|
LibW = "libcsfml-window.so.2.0"
|
||||||
#{.error: "Platform unsupported".}
|
#{.error: "Platform unsupported".}
|
||||||
{.deadCodeElim: on.}
|
|
||||||
{.pragma: pf, pure, final.}
|
{.pragma: pf, pure, final.}
|
||||||
type
|
type
|
||||||
PClock* = ptr TClock
|
PClock* = ptr TClock
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import sfml
|
import sfml
|
||||||
{.deadCodeElim: on.}
|
|
||||||
let
|
let
|
||||||
Black*: TColor = color(0, 0, 0)
|
Black*: TColor = color(0, 0, 0)
|
||||||
White*: TColor = color(255, 255, 255)
|
White*: TColor = color(255, 255, 255)
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
import sfml, math, strutils
|
import sfml, math, strutils
|
||||||
{.deadCodeElim: on.}
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import
|
||||||
sg_gui, sg_assets, sound_buffer, enet_client
|
sg_gui, sg_assets, sound_buffer, enet_client
|
||||||
when defined(profiler):
|
when defined(profiler):
|
||||||
import nimprof
|
import nimprof
|
||||||
{.deadCodeElim: on.}
|
|
||||||
type
|
type
|
||||||
PPlayer* = ref TPlayer
|
PPlayer* = ref TPlayer
|
||||||
TPlayer* = object
|
TPlayer* = object
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import
|
||||||
sfml, sfml_colors,
|
sfml, sfml_colors,
|
||||||
input_helpers, sg_packets
|
input_helpers, sg_packets
|
||||||
from strutils import countlines
|
from strutils import countlines
|
||||||
{.deadCodeElim: on.}
|
|
||||||
type
|
type
|
||||||
PGuiContainer* = ref TGuiContainer
|
PGuiContainer* = ref TGuiContainer
|
||||||
TGuiContainer* = object of TObject
|
TGuiContainer* = object of TObject
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
debugger = off
|
debugger = off
|
||||||
deadCodeElim = on
|
|
||||||
path = ".."
|
path = ".."
|
||||||
path = "../genpacket"
|
path = "../genpacket"
|
||||||
path = "../helpers"
|
path = "../helpers"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const
|
||||||
ExeName = "keineschweine"
|
ExeName = "keineschweine"
|
||||||
ServerDefines = "-d:NoSFML -d:NoChipmunk"
|
ServerDefines = "-d:NoSFML -d:NoChipmunk"
|
||||||
TestBuildDefines = "-d:escapeMenuTest -d:debugWeps -d:showFPS -d:moreNim -d:debugKeys -d:foo -d:recordMode --forceBuild"
|
TestBuildDefines = "-d:escapeMenuTest -d:debugWeps -d:showFPS -d:moreNim -d:debugKeys -d:foo -d:recordMode --forceBuild"
|
||||||
ReleaseDefines = "-d:release --deadCodeElim:on"
|
ReleaseDefines = "-d:release"
|
||||||
ReleaseTestDefines = "-d:debugWeps -d:debugKeys --forceBuild"
|
ReleaseTestDefines = "-d:debugWeps -d:debugKeys --forceBuild"
|
||||||
|
|
||||||
task "testprofile", "..":
|
task "testprofile", "..":
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
--os:standalone
|
--os:standalone
|
||||||
--deadCodeElim:on
|
|
||||||
--gc:none
|
--gc:none
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ discard """
|
||||||
|
|
||||||
import threadpool, sequtils
|
import threadpool, sequtils
|
||||||
|
|
||||||
{.experimental.}
|
{.experimental: "parallel".}
|
||||||
|
|
||||||
proc linearFind(a: openArray[int]; x, offset: int): int =
|
proc linearFind(a: openArray[int]; x, offset: int): int =
|
||||||
for i, y in a:
|
for i, y in a:
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@ discard """
|
||||||
ccodeCheck: "\\i @'__attribute__((noreturn))' .*"
|
ccodeCheck: "\\i @'__attribute__((noreturn))' .*"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc noret1*(i: int) {.noreturn.} =
|
proc noret1*(i: int) {.noreturn.} =
|
||||||
echo i
|
echo i
|
||||||
|
|
||||||
|
|
||||||
proc noret2*(i: int): void {.noreturn.} =
|
proc noret2*(i: int): void {.noreturn.} =
|
||||||
echo i
|
echo i
|
||||||
|
|
||||||
|
noret1(1)
|
||||||
|
noret2(2)
|
||||||
|
|
||||||
var p {.used.}: proc(i: int): int
|
var p {.used.}: proc(i: int): int
|
||||||
doAssert(not compiles(
|
doAssert(not compiles(
|
||||||
p = proc(i: int): int {.noreturn.} = i # noreturn lambda returns int
|
p = proc(i: int): int {.noreturn.} = i # noreturn lambda returns int
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
|
||||||
|
|
||||||
proc p1*(x, y: int): int =
|
proc p1*(x, y: int): int =
|
||||||
result = x + y
|
result = x + y
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -367,6 +367,10 @@ suite "ttimes":
|
||||||
check d(seconds = 0) - d(milliseconds = 1500) == d(milliseconds = -1500)
|
check d(seconds = 0) - d(milliseconds = 1500) == d(milliseconds = -1500)
|
||||||
check d(milliseconds = -1500) == d(seconds = -1, milliseconds = -500)
|
check d(milliseconds = -1500) == d(seconds = -1, milliseconds = -500)
|
||||||
check d(seconds = -1, milliseconds = 500) == d(milliseconds = -500)
|
check d(seconds = -1, milliseconds = 500) == d(milliseconds = -500)
|
||||||
|
check initDuration(seconds = 1, nanoseconds = 2) <=
|
||||||
|
initDuration(seconds = 1, nanoseconds = 3)
|
||||||
|
check (initDuration(seconds = 1, nanoseconds = 3) <=
|
||||||
|
initDuration(seconds = 1, nanoseconds = 1)).not
|
||||||
|
|
||||||
test "large/small dates":
|
test "large/small dates":
|
||||||
discard initDateTime(1, mJan, -35_000, 12, 00, 00, utc())
|
discard initDateTime(1, mJan, -35_000, 12, 00, 00, utc())
|
||||||
|
|
@ -413,7 +417,7 @@ suite "ttimes":
|
||||||
|
|
||||||
test "fromWinTime/toWinTime":
|
test "fromWinTime/toWinTime":
|
||||||
check 0.fromUnix.toWinTime.fromWinTime.toUnix == 0
|
check 0.fromUnix.toWinTime.fromWinTime.toUnix == 0
|
||||||
check (-1).fromWinTime.nanoseconds == convert(Seconds, Nanoseconds, 1) - 100
|
check (-1).fromWinTime.nanosecond == convert(Seconds, Nanoseconds, 1) - 100
|
||||||
check -1.fromWinTime.toWinTime == -1
|
check -1.fromWinTime.toWinTime == -1
|
||||||
# One nanosecond is discarded due to differences in time resolution
|
# One nanosecond is discarded due to differences in time resolution
|
||||||
check initTime(0, 101).toWinTime.fromWinTime.nanoseconds == 100
|
check initTime(0, 101).toWinTime.fromWinTime.nanosecond == 100
|
||||||
|
|
@ -13,7 +13,7 @@ type
|
||||||
CommitId = distinct string
|
CommitId = distinct string
|
||||||
|
|
||||||
proc `$`*(id: MachineId): string {.borrow.}
|
proc `$`*(id: MachineId): string {.borrow.}
|
||||||
proc `$`(id: CommitId): string {.borrow.}
|
#proc `$`(id: CommitId): string {.borrow.} # not used
|
||||||
|
|
||||||
var
|
var
|
||||||
thisMachine: MachineId
|
thisMachine: MachineId
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,26 @@ proc compileRodFiles(r: var TResults, cat: Category, options: string) =
|
||||||
test "gtkex1", true
|
test "gtkex1", true
|
||||||
test "gtkex2"
|
test "gtkex2"
|
||||||
|
|
||||||
|
# --------------------- flags tests -------------------------------------------
|
||||||
|
|
||||||
|
proc flagTests(r: var TResults, cat: Category, options: string) =
|
||||||
|
# --genscript
|
||||||
|
const filename = "tests"/"flags"/"tgenscript"
|
||||||
|
const genopts = " --genscript"
|
||||||
|
let nimcache = nimcacheDir(filename, genopts, targetC)
|
||||||
|
testSpec r, makeTest(filename, genopts, cat)
|
||||||
|
|
||||||
|
when defined(windows):
|
||||||
|
testExec r, makeTest(filename, " cmd /c cd " & nimcache &
|
||||||
|
" && compile_tgenscript.bat", cat)
|
||||||
|
|
||||||
|
when defined(linux):
|
||||||
|
testExec r, makeTest(filename, " sh -c \"cd " & nimcache &
|
||||||
|
" && sh compile_tgenscript.sh\"", cat)
|
||||||
|
|
||||||
|
# Run
|
||||||
|
testExec r, makeTest(filename, " " & nimcache / "tgenscript", cat)
|
||||||
|
|
||||||
# --------------------- DLL generation tests ----------------------------------
|
# --------------------- DLL generation tests ----------------------------------
|
||||||
|
|
||||||
proc safeCopyFile(src, dest: string) =
|
proc safeCopyFile(src, dest: string) =
|
||||||
|
|
@ -323,7 +343,7 @@ var nimbleDir = getEnv("NIMBLE_DIR").string
|
||||||
if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble"
|
if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble"
|
||||||
let
|
let
|
||||||
nimbleExe = findExe("nimble")
|
nimbleExe = findExe("nimble")
|
||||||
packageDir = nimbleDir / "pkgs"
|
#packageDir = nimbleDir / "pkgs" # not used
|
||||||
packageIndex = nimbleDir / "packages.json"
|
packageIndex = nimbleDir / "packages.json"
|
||||||
|
|
||||||
proc waitForExitEx(p: Process): int =
|
proc waitForExitEx(p: Process): int =
|
||||||
|
|
@ -407,9 +427,9 @@ proc `&.?`(a, b: string): string =
|
||||||
# candidate for the stdlib?
|
# candidate for the stdlib?
|
||||||
result = if b.startswith(a): b else: a & b
|
result = if b.startswith(a): b else: a & b
|
||||||
|
|
||||||
proc `&?.`(a, b: string): string =
|
#proc `&?.`(a, b: string): string = # not used
|
||||||
# candidate for the stdlib?
|
# candidate for the stdlib?
|
||||||
result = if a.endswith(b): a else: a & b
|
#result = if a.endswith(b): a else: a & b
|
||||||
|
|
||||||
proc processSingleTest(r: var TResults, cat: Category, options, test: string) =
|
proc processSingleTest(r: var TResults, cat: Category, options, test: string) =
|
||||||
let test = "tests" & DirSep &.? cat.string / test
|
let test = "tests" & DirSep &.? cat.string / test
|
||||||
|
|
@ -429,6 +449,8 @@ proc processCategory(r: var TResults, cat: Category, options: string) =
|
||||||
jsTests(r, cat, options)
|
jsTests(r, cat, options)
|
||||||
of "dll":
|
of "dll":
|
||||||
dllTests(r, cat, options)
|
dllTests(r, cat, options)
|
||||||
|
of "flags":
|
||||||
|
flagTests(r, cat, options)
|
||||||
of "gc":
|
of "gc":
|
||||||
gcTests(r, cat, options)
|
gcTests(r, cat, options)
|
||||||
of "longgc":
|
of "longgc":
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ proc generateAllTestsContent(outfile: File, allResults: AllTests,
|
||||||
|
|
||||||
proc generateHtml*(filename: string, onlyFailing: bool) =
|
proc generateHtml*(filename: string, onlyFailing: bool) =
|
||||||
let
|
let
|
||||||
currentTime = getTime().getLocalTime()
|
currentTime = getTime().local()
|
||||||
timestring = htmlQuote format(currentTime, "yyyy-MM-dd HH:mm:ss 'UTC'zzz")
|
timestring = htmlQuote format(currentTime, "yyyy-MM-dd HH:mm:ss 'UTC'zzz")
|
||||||
var outfile = open(filename, fmWrite)
|
var outfile = open(filename, fmWrite)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import
|
||||||
|
|
||||||
const
|
const
|
||||||
resultsFile = "testresults.html"
|
resultsFile = "testresults.html"
|
||||||
jsonFile = "testresults.json"
|
#jsonFile = "testresults.json" # not used
|
||||||
Usage = """Usage:
|
Usage = """Usage:
|
||||||
tester [options] command [arguments]
|
tester [options] command [arguments]
|
||||||
|
|
||||||
|
|
@ -150,11 +150,11 @@ proc initResults: TResults =
|
||||||
result.skipped = 0
|
result.skipped = 0
|
||||||
result.data = ""
|
result.data = ""
|
||||||
|
|
||||||
proc readResults(filename: string): TResults =
|
#proc readResults(filename: string): TResults = # not used
|
||||||
result = marshal.to[TResults](readFile(filename).string)
|
# result = marshal.to[TResults](readFile(filename).string)
|
||||||
|
|
||||||
proc writeResults(filename: string, r: TResults) =
|
#proc writeResults(filename: string, r: TResults) = # not used
|
||||||
writeFile(filename, $$r)
|
# writeFile(filename, $$r)
|
||||||
|
|
||||||
proc `$`(x: TResults): string =
|
proc `$`(x: TResults): string =
|
||||||
result = ("Tests passed: $1 / $3 <br />\n" &
|
result = ("Tests passed: $1 / $3 <br />\n" &
|
||||||
|
|
@ -404,6 +404,21 @@ proc testC(r: var TResults, test: TTest) =
|
||||||
if exitCode != 0: given.err = reExitCodesDiffer
|
if exitCode != 0: given.err = reExitCodesDiffer
|
||||||
if given.err == reSuccess: inc(r.passed)
|
if given.err == reSuccess: inc(r.passed)
|
||||||
|
|
||||||
|
proc testExec(r: var TResults, test: TTest) =
|
||||||
|
# runs executable or script, just goes by exit code
|
||||||
|
inc(r.total)
|
||||||
|
let (outp, errC) = execCmdEx(test.options.strip())
|
||||||
|
var given: TSpec
|
||||||
|
specDefaults(given)
|
||||||
|
if errC == 0:
|
||||||
|
given.err = reSuccess
|
||||||
|
else:
|
||||||
|
given.err = reExitCodesDiffer
|
||||||
|
given.msg = outp.string
|
||||||
|
|
||||||
|
if given.err == reSuccess: inc(r.passed)
|
||||||
|
r.addResult(test, targetC, "", given.msg, given.err)
|
||||||
|
|
||||||
proc makeTest(test, options: string, cat: Category, action = actionCompile,
|
proc makeTest(test, options: string, cat: Category, action = actionCompile,
|
||||||
env: string = ""): TTest =
|
env: string = ""): TTest =
|
||||||
# start with 'actionCompile', will be overwritten in the spec:
|
# start with 'actionCompile', will be overwritten in the spec:
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ _nim()
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
case $prev in
|
case $prev in
|
||||||
--stackTrace|--lineTrace|--threads|-x|--checks|--objChecks|--fieldChecks|--rangeChecks|--boundChecks|--overflowChecks|-a|--assertions|--floatChecks|--nanChecks|--infChecks|--deadCodeElim)
|
--stackTrace|--lineTrace|--threads|-x|--checks|--objChecks|--fieldChecks|--rangeChecks|--boundChecks|--overflowChecks|-a|--assertions|--floatChecks|--nanChecks|--infChecks)
|
||||||
# Options that require on/off
|
# Options that require on/off
|
||||||
[[ "$cur" == "=" ]] && cur=""
|
[[ "$cur" == "=" ]] && cur=""
|
||||||
COMPREPLY=( $(compgen -W 'on off' -- "$cur") )
|
COMPREPLY=( $(compgen -W 'on off' -- "$cur") )
|
||||||
|
|
@ -32,7 +32,7 @@ _nim()
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
kw="-r -p= --path= -d= --define= -u= --undef= -f --forceBuild --opt= --app= --stackTrace= --lineTrace= --threads= -x= --checks= --objChecks= --fieldChecks= --rangeChecks= --boundChecks= --overflowChecks= -a= --assertions= --floatChecks= --nanChecks= --infChecks= --deadCodeElim="
|
kw="-r -p= --path= -d= --define= -u= --undef= -f --forceBuild --opt= --app= --stackTrace= --lineTrace= --threads= -x= --checks= --objChecks= --fieldChecks= --rangeChecks= --boundChecks= --overflowChecks= -a= --assertions= --floatChecks= --nanChecks= --infChecks="
|
||||||
COMPREPLY=( $( compgen -W "${kw}" -- $cur ) )
|
COMPREPLY=( $( compgen -W "${kw}" -- $cur ) )
|
||||||
_filedir '@(nim)'
|
_filedir '@(nim)'
|
||||||
#$split
|
#$split
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,6 @@ _nim() {
|
||||||
'*--infChecks=off[turn Inf checks off]' \
|
'*--infChecks=off[turn Inf checks off]' \
|
||||||
'*--nilChecks=on[turn nil checks on]' \
|
'*--nilChecks=on[turn nil checks on]' \
|
||||||
'*--nilChecks=off[turn nil checks off]' \
|
'*--nilChecks=off[turn nil checks off]' \
|
||||||
'*--deadCodeElim=on[whole program dead code elimination on]' \
|
|
||||||
'*--deadCodeElim=off[whole program dead code elimination off]' \
|
|
||||||
'*--opt=none[do not optimize]' \
|
'*--opt=none[do not optimize]' \
|
||||||
'*--opt=speed[optimize for speed|size - use -d:release for a release build]' \
|
'*--opt=speed[optimize for speed|size - use -d:release for a release build]' \
|
||||||
'*--opt=size[optimize for size]' \
|
'*--opt=size[optimize for size]' \
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import
|
||||||
os, strutils, parseopt, pegs, re, terminal
|
os, strutils, parseopt, pegs, re, terminal
|
||||||
|
|
||||||
const
|
const
|
||||||
Version = "1.1"
|
Version = "1.2"
|
||||||
Usage = "nimgrep - Nim Grep Utility Version " & Version & """
|
Usage = "nimgrep - Nim Grep Utility Version " & Version & """
|
||||||
|
|
||||||
(c) 2012 Andreas Rumpf
|
(c) 2012 Andreas Rumpf
|
||||||
|
|
@ -35,6 +35,8 @@ Options:
|
||||||
--nocolor output will be given without any colours.
|
--nocolor output will be given without any colours.
|
||||||
--oneline show file on each matched line
|
--oneline show file on each matched line
|
||||||
--verbose be verbose: list every processed file
|
--verbose be verbose: list every processed file
|
||||||
|
--filenames find the pattern in the filenames, not in the contents
|
||||||
|
of the file
|
||||||
--help, -h shows this help
|
--help, -h shows this help
|
||||||
--version, -v shows the version
|
--version, -v shows the version
|
||||||
"""
|
"""
|
||||||
|
|
@ -42,7 +44,7 @@ Options:
|
||||||
type
|
type
|
||||||
TOption = enum
|
TOption = enum
|
||||||
optFind, optReplace, optPeg, optRegex, optRecursive, optConfirm, optStdin,
|
optFind, optReplace, optPeg, optRegex, optRecursive, optConfirm, optStdin,
|
||||||
optWord, optIgnoreCase, optIgnoreStyle, optVerbose
|
optWord, optIgnoreCase, optIgnoreStyle, optVerbose, optFilenames
|
||||||
TOptions = set[TOption]
|
TOptions = set[TOption]
|
||||||
TConfirmEnum = enum
|
TConfirmEnum = enum
|
||||||
ceAbort, ceYes, ceAll, ceNo, ceNone
|
ceAbort, ceYes, ceAll, ceNo, ceNone
|
||||||
|
|
@ -135,11 +137,14 @@ proc processFile(pattern; filename: string) =
|
||||||
filenameShown = true
|
filenameShown = true
|
||||||
|
|
||||||
var buffer: string
|
var buffer: string
|
||||||
try:
|
if optFilenames in options:
|
||||||
buffer = system.readFile(filename)
|
buffer = filename
|
||||||
except IOError:
|
else:
|
||||||
echo "cannot open file: ", filename
|
try:
|
||||||
return
|
buffer = system.readFile(filename)
|
||||||
|
except IOError:
|
||||||
|
echo "cannot open file: ", filename
|
||||||
|
return
|
||||||
if optVerbose in options:
|
if optVerbose in options:
|
||||||
stdout.writeLine(filename)
|
stdout.writeLine(filename)
|
||||||
stdout.flushFile()
|
stdout.flushFile()
|
||||||
|
|
@ -293,6 +298,7 @@ for kind, key, val in getopt():
|
||||||
of "nocolor": useWriteStyled = false
|
of "nocolor": useWriteStyled = false
|
||||||
of "oneline": oneline = true
|
of "oneline": oneline = true
|
||||||
of "verbose": incl(options, optVerbose)
|
of "verbose": incl(options, optVerbose)
|
||||||
|
of "filenames": incl(options, optFilenames)
|
||||||
of "help", "h": writeHelp()
|
of "help", "h": writeHelp()
|
||||||
of "version", "v": writeVersion()
|
of "version", "v": writeVersion()
|
||||||
else: writeHelp()
|
else: writeHelp()
|
||||||
|
|
@ -304,6 +310,7 @@ when defined(posix):
|
||||||
checkOptions({optFind, optReplace}, "find", "replace")
|
checkOptions({optFind, optReplace}, "find", "replace")
|
||||||
checkOptions({optPeg, optRegex}, "peg", "re")
|
checkOptions({optPeg, optRegex}, "peg", "re")
|
||||||
checkOptions({optIgnoreCase, optIgnoreStyle}, "ignore_case", "ignore_style")
|
checkOptions({optIgnoreCase, optIgnoreStyle}, "ignore_case", "ignore_style")
|
||||||
|
checkOptions({optFilenames, optReplace}, "filenames", "replace")
|
||||||
|
|
||||||
if optStdin in options:
|
if optStdin in options:
|
||||||
pattern = ask("pattern [ENTER to exit]: ")
|
pattern = ask("pattern [ENTER to exit]: ")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue