mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-21 03:50:43 +00:00
@@ -102,4 +102,10 @@
|
||||
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual
|
||||
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
|
||||
|
||||
@@ -262,7 +262,8 @@ type
|
||||
# variable is a thread variable
|
||||
sfCompileTime, # proc can be evaluated at compile time
|
||||
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
|
||||
sfInfixCall, # symbol needs infix call syntax in target language;
|
||||
# for interfacing with C++, JS
|
||||
@@ -275,10 +276,9 @@ type
|
||||
TSymFlags* = set[TSymFlag]
|
||||
|
||||
const
|
||||
sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher
|
||||
sfNoInit* = sfMainModule # don't generate code to init the variable
|
||||
|
||||
sfImmediate* = sfDeadCodeElim
|
||||
sfImmediate* = sfDispatcher
|
||||
# macro or template is immediately expanded
|
||||
# without considering any possible overloads
|
||||
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]
|
||||
|
||||
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.} =
|
||||
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 nkWhileStmt: genWhileStmt(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 nkCaseStmt: genCase(p, n, d)
|
||||
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
|
||||
# by ensuring it's no inner proc (owner is a module):
|
||||
if prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags:
|
||||
if (not emitLazily(prc)) or
|
||||
({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
|
||||
if ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
|
||||
(sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
|
||||
(prc.kind == skMethod):
|
||||
# we have not only the header:
|
||||
|
||||
@@ -280,20 +280,6 @@ proc genVarStmt(p: BProc, n: PNode) =
|
||||
else:
|
||||
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) =
|
||||
#
|
||||
# { if (!expr1) goto L1;
|
||||
@@ -587,7 +573,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||
genLineDir(p, t)
|
||||
if isImportedException(typ):
|
||||
lineF(p, cpsStmts, "throw $1;$n", [e])
|
||||
else:
|
||||
else:
|
||||
lineCg(p, cpsStmts, "#raiseException((#Exception*)$1, $2);$n",
|
||||
[e, makeCString(typ.sym.name.s)])
|
||||
else:
|
||||
@@ -836,7 +822,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||
else:
|
||||
for j in 0..t[i].len-2:
|
||||
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)
|
||||
startBlock(p, "catch ($1& $2) {$n", getTypeDesc(p.module, t[i][j][1].typ), rdLoc(exvar.sym.loc))
|
||||
else:
|
||||
|
||||
@@ -211,8 +211,4 @@ proc mangle*(name: string): string =
|
||||
if requiresUnderscore:
|
||||
result.add "_"
|
||||
|
||||
proc emitLazily*(s: PSym): bool {.inline.} =
|
||||
result = optDeadCodeElim in gGlobalOptions or
|
||||
sfDeadCodeElim in getModule(s).flags
|
||||
|
||||
initTypeTables()
|
||||
|
||||
@@ -1309,10 +1309,6 @@ proc newModule(g: BModuleList; module: PSym): BModule =
|
||||
growCache g.modules, module.position
|
||||
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.} =
|
||||
if graph.backend == nil:
|
||||
graph.backend = newModuleList(config)
|
||||
|
||||
@@ -46,9 +46,9 @@ type
|
||||
passCmd2, # second pass over the command line
|
||||
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;
|
||||
config: ConfigRef = nil)
|
||||
config: ConfigRef)
|
||||
|
||||
# implementation
|
||||
|
||||
@@ -58,7 +58,13 @@ const
|
||||
|
||||
const
|
||||
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 =
|
||||
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 "linedir": result = contains(gOptions, optLineDir)
|
||||
of "assertions", "a": result = contains(gOptions, optAssert)
|
||||
of "deadcodeelim": result = contains(gGlobalOptions, optDeadCodeElim)
|
||||
of "run", "r": result = contains(gGlobalOptions, optRun)
|
||||
of "symbolfiles": result = gSymbolFiles != disabledSf
|
||||
of "genscript": result = contains(gGlobalOptions, optGenScript)
|
||||
@@ -277,7 +282,6 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
|
||||
of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
|
||||
of "implicitstatic": result = contains(gOptions, optImplicitStatic)
|
||||
of "patterns": result = contains(gOptions, optPatterns)
|
||||
of "experimental": result = gExperimentalMode
|
||||
of "excessivestacktrace": result = contains(gGlobalOptions, optExcessiveStackTrace)
|
||||
else: invalidCmdLineOption(passCmd1, switch, info)
|
||||
|
||||
@@ -340,7 +344,7 @@ proc dynlibOverride(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||
options.inclDynlibOverride(arg)
|
||||
|
||||
proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
config: ConfigRef = nil) =
|
||||
config: ConfigRef) =
|
||||
var
|
||||
theOS: TSystemOS
|
||||
cpu: TSystemCPU
|
||||
@@ -509,7 +513,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
of "movechecks": processOnOffSwitch({optMoveCheck}, arg, pass, info)
|
||||
of "linedir": processOnOffSwitch({optLineDir}, 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":
|
||||
processOnOffSwitchG({optThreads}, arg, pass, info)
|
||||
#if optThreads in gGlobalOptions: incl(gNotes, warnGcUnsafe)
|
||||
@@ -648,6 +652,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
of "genscript", "gendeps":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
incl(gGlobalOptions, optGenScript)
|
||||
incl(gGlobalOptions, optCompileOnly)
|
||||
of "colors": processOnOffSwitchG({optUseColors}, arg, pass, info)
|
||||
of "lib":
|
||||
expectArg(switch, arg, pass, info)
|
||||
@@ -695,8 +700,13 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
# only supported for compatibility. Does nothing.
|
||||
expectArg(switch, arg, pass, info)
|
||||
of "experimental":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
gExperimentalMode = true
|
||||
if arg.len == 0:
|
||||
config.features.incl oldExperimentalFeatures
|
||||
else:
|
||||
try:
|
||||
config.features.incl parseEnum[Feature](arg)
|
||||
except ValueError:
|
||||
localError(info, "unknown experimental feature")
|
||||
of "nocppexceptions":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
incl(gGlobalOptions, optNoCppExceptions)
|
||||
@@ -707,7 +717,8 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
config.cppDefine(arg)
|
||||
of "newruntime":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
newDestructors = true
|
||||
doAssert(config != nil)
|
||||
incl(config.features, destructor)
|
||||
defineSymbol("nimNewRuntime")
|
||||
of "cppcompiletonamespace":
|
||||
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)
|
||||
else: invalidCmdLineOption(pass, switch, info)
|
||||
|
||||
proc processCommand(switch: string, pass: TCmdLinePass) =
|
||||
proc processCommand(switch: string, pass: TCmdLinePass; config: ConfigRef) =
|
||||
var cmd, arg: string
|
||||
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
|
||||
processSwitch(cmd, arg, pass, gCmdLineInfo)
|
||||
processSwitch(cmd, arg, pass, gCmdLineInfo, config)
|
||||
|
||||
|
||||
var
|
||||
arguments* = ""
|
||||
# the arguments to be passed to the program that
|
||||
# should be run
|
||||
|
||||
proc processSwitch*(pass: TCmdLinePass; p: OptParser) =
|
||||
proc processSwitch*(pass: TCmdLinePass; p: OptParser; config: ConfigRef) =
|
||||
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
|
||||
# we fix this here
|
||||
var bracketLe = strutils.find(p.key, '[')
|
||||
if bracketLe >= 0:
|
||||
var key = substr(p.key, 0, bracketLe - 1)
|
||||
var val = substr(p.key, bracketLe + 1) & ':' & p.val
|
||||
processSwitch(key, val, pass, gCmdLineInfo)
|
||||
processSwitch(key, val, pass, gCmdLineInfo, config)
|
||||
else:
|
||||
processSwitch(p.key, p.val, pass, gCmdLineInfo)
|
||||
processSwitch(p.key, p.val, pass, gCmdLineInfo, config)
|
||||
|
||||
proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
||||
argsCount: var int): bool =
|
||||
argsCount: var int; config: ConfigRef): bool =
|
||||
if argsCount == 0:
|
||||
# nim filename.nims is the same as "nim e filename.nims":
|
||||
if p.key.endswith(".nims"):
|
||||
options.command = "e"
|
||||
options.gProjectName = unixToNativePath(p.key)
|
||||
arguments = cmdLineRest(p)
|
||||
config.arguments = cmdLineRest(p)
|
||||
result = true
|
||||
elif pass != passCmd2:
|
||||
options.command = p.key
|
||||
@@ -755,6 +761,6 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
||||
if argsCount == 1:
|
||||
# support UNIX style filenames everywhere for portable build scripts:
|
||||
options.gProjectName = unixToNativePath(p.key)
|
||||
arguments = cmdLineRest(p)
|
||||
config.arguments = cmdLineRest(p)
|
||||
result = true
|
||||
inc argsCount
|
||||
|
||||
@@ -470,8 +470,9 @@ proc execExternalProgram*(cmd: string, msg = hintExecuting) =
|
||||
|
||||
proc generateScript(projectFile: string, script: Rope) =
|
||||
let (dir, name, ext) = splitFile(projectFile)
|
||||
writeRope(script, dir / addFileExt("compile_" & name,
|
||||
writeRope(script, getNimcacheDir() / addFileExt("compile_" & name,
|
||||
platform.OS[targetOS].scriptExt))
|
||||
copyFile(libpath / "nimbase.h", getNimcacheDir() / "nimbase.h")
|
||||
|
||||
proc getOptSpeed(c: TSystemCC): string =
|
||||
result = getConfigVar(c, ".options.speed")
|
||||
|
||||
@@ -42,7 +42,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||
writeCommandLineUsage()
|
||||
else:
|
||||
# Process command line arguments:
|
||||
processCmdLine(passCmd1, "")
|
||||
processCmdLine(passCmd1, "", config)
|
||||
if gProjectName == "-":
|
||||
gProjectName = "stdinfile"
|
||||
gProjectFull = "stdinfile"
|
||||
@@ -71,7 +71,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||
# now process command line arguments again, because some options in the
|
||||
# command line can overwite the config file's settings
|
||||
extccomp.initVars()
|
||||
processCmdLine(passCmd2, "")
|
||||
processCmdLine(passCmd2, "", config)
|
||||
if options.command == "":
|
||||
rawMessage(errNoCommand, command)
|
||||
mainCommand(newModuleGraph(config), cache)
|
||||
@@ -80,7 +80,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||
if msgs.gErrorCounter == 0:
|
||||
when hasTinyCBackend:
|
||||
if gCmd == cmdRun:
|
||||
tccgen.run(commands.arguments)
|
||||
tccgen.run(config.arguments)
|
||||
if optRun in gGlobalOptions:
|
||||
if gCmd == cmdCompileToJS:
|
||||
var ex: string
|
||||
@@ -89,7 +89,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||
else:
|
||||
ex = quoteShell(
|
||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||
execExternalProgram(findNodeJs() & " " & ex & ' ' & commands.arguments)
|
||||
execExternalProgram(findNodeJs() & " " & ex & ' ' & config.arguments)
|
||||
else:
|
||||
var binPath: string
|
||||
if options.outFile.len > 0:
|
||||
@@ -99,7 +99,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||
# Figure out ourselves a valid binary name.
|
||||
binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir
|
||||
var ex = quoteShell(binPath)
|
||||
execExternalProgram(ex & ' ' & commands.arguments)
|
||||
execExternalProgram(ex & ' ' & config.arguments)
|
||||
|
||||
when declared(GC_setMaxPause):
|
||||
GC_setMaxPause 2_000
|
||||
|
||||
@@ -247,10 +247,6 @@ proc loadConfigs*(cfg: string; cache: IdentCache; config: ConfigRef = nil) =
|
||||
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
|
||||
if not fileExists(projectConfig):
|
||||
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
|
||||
if not fileExists(projectConfig):
|
||||
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
|
||||
if fileExists(projectConfig):
|
||||
rawMessage(warnDeprecated, projectConfig)
|
||||
readConfigFile(projectConfig, cache, config)
|
||||
|
||||
proc loadConfigs*(cfg: string; config: ConfigRef = nil) =
|
||||
|
||||
@@ -41,7 +41,8 @@ type # please make sure we have under 32 options
|
||||
|
||||
TOptions* = set[TOption]
|
||||
TGlobalOption* = enum # **keep binary compatible**
|
||||
gloptNone, optForceFullMake, optDeadCodeElim,
|
||||
gloptNone, optForceFullMake,
|
||||
optDeadCodeElimUnused, # deprecated, always on
|
||||
optListCmd, optCompileOnly, optNoLinking,
|
||||
optCDebug, # turn on debugging information
|
||||
optGenDynLib, # generate a dynamic library
|
||||
@@ -102,13 +103,25 @@ type
|
||||
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
|
||||
ideHighlight, ideOutline, ideKnown, ideMsg
|
||||
|
||||
Feature* = enum ## experimental features
|
||||
implicitDeref,
|
||||
dotOperators,
|
||||
callOperator,
|
||||
parallel,
|
||||
destructor
|
||||
|
||||
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
||||
cppDefines*: HashSet[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 =
|
||||
result = ConfigRef(cppDefines: initSet[string](),
|
||||
headerFile: "")
|
||||
headerFile: "", features: {})
|
||||
|
||||
proc cppDefine*(c: ConfigRef; define: string) =
|
||||
c.cppDefines.incl define
|
||||
@@ -145,8 +158,6 @@ var
|
||||
gListFullPaths*: bool
|
||||
gPreciseStack*: bool = false
|
||||
gNoNimblePath* = false
|
||||
gExperimentalMode*: bool
|
||||
newDestructors*: bool
|
||||
gDynlibOverrideAll*: bool
|
||||
useNimNamespace*: bool
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||
p: TParsers
|
||||
a: TPassContextArray
|
||||
s: PLLStream
|
||||
fileIdx = FileIndex module.fileIdx
|
||||
fileIdx = module.fileIdx
|
||||
if module.id < 0:
|
||||
# new module caching mechanism:
|
||||
for i in 0..<gPassesLen:
|
||||
|
||||
@@ -44,7 +44,9 @@ const
|
||||
wWarnings, wHints,
|
||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
||||
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,
|
||||
wLinearScanEnd, wPatterns, wEffects, wNoForward, wReorder, wComputedGoto,
|
||||
wInjectStmt, wDeprecated, wExperimental, wThis}
|
||||
@@ -215,10 +217,6 @@ proc onOff(c: PContext, n: PNode, op: TOptions) =
|
||||
if isTurnedOn(c, n): 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) =
|
||||
if isTurnedOn(c, n): incl(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:
|
||||
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,
|
||||
validPragmas: TSpecialWords): bool =
|
||||
var it = n.sons[i]
|
||||
@@ -764,7 +778,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
of wThreadVar:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfThread)
|
||||
of wDeadCodeElim: pragmaDeadCodeElim(c, it)
|
||||
of wDeadCodeElimUnused: discard # deprecated, dead code elim always on
|
||||
of wNoForward: pragmaNoForward(c, it)
|
||||
of wReorder: pragmaNoForward(c, it, sfReorder)
|
||||
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)
|
||||
else:
|
||||
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:
|
||||
# We check for errors, but do nothing with these pragmas otherwise
|
||||
# as they are handled directly in 'evalTemplate'.
|
||||
@@ -999,11 +1009,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
else:
|
||||
it.sons[1] = c.semExpr(c, it.sons[1])
|
||||
of wExperimental:
|
||||
noVal(it)
|
||||
if isTopLevel(c):
|
||||
c.module.flags.incl sfExperimental
|
||||
else:
|
||||
localError(it.info, "'experimental' pragma only valid as toplevel statement")
|
||||
processExperimental(c, it, sym)
|
||||
of wThis:
|
||||
if it.kind in nkPragmaCallKinds and it.len == 2:
|
||||
c.selfName = considerQuotedIdent(it[1])
|
||||
|
||||
@@ -172,32 +172,6 @@ proc put(g: var TSrcGen, kind: TTokType, s: string) =
|
||||
else:
|
||||
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) =
|
||||
if s.isNil: return
|
||||
var i = 0
|
||||
@@ -365,10 +339,13 @@ proc atom(g: TSrcGen; n: PNode): string =
|
||||
of nkEmpty: result = ""
|
||||
of nkIdent: result = n.ident.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 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 nkInt8Lit: result = litAux(g, n, n.intVal, 1) & "\'i8"
|
||||
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:
|
||||
return n
|
||||
var includedFiles = initIntSet()
|
||||
let mpath = module.fileIdx.FileIndex.toFullPath
|
||||
let mpath = module.fileIdx.toFullPath
|
||||
let n = expandIncludes(graph, module, n, mpath,
|
||||
includedFiles, cache).splitSections
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
|
||||
@@ -915,7 +915,7 @@ proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader =
|
||||
module.id = getID()
|
||||
return nil
|
||||
idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
|
||||
let fileIdx = FileIndex module.fileIdx
|
||||
let fileIdx = module.fileIdx
|
||||
discard checkDep(fileIdx, cache)
|
||||
if gMods[fileIdx.int32].reason == rrEmpty: internalError("handleSymbolFile")
|
||||
result = gMods[fileIdx.int32].rd
|
||||
|
||||
@@ -26,7 +26,7 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) =
|
||||
setResult(a, result)
|
||||
|
||||
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||
config: ConfigRef = nil): PEvalContext =
|
||||
config: ConfigRef): PEvalContext =
|
||||
# For Nimble we need to export 'setupVM'.
|
||||
result = newCtx(module, cache)
|
||||
result.mode = emRepl
|
||||
@@ -128,7 +128,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||
cbconf getCommand:
|
||||
setResult(a, options.command)
|
||||
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:
|
||||
processSpecificNote(a.getString 0, wHint, passPP, module.info,
|
||||
a.getString 1)
|
||||
@@ -150,7 +150,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||
options.cppDefine(config, a.getString(0))
|
||||
|
||||
proc runNimScript*(cache: IdentCache; scriptName: string;
|
||||
freshDefines=true; config: ConfigRef=nil) =
|
||||
freshDefines=true; config: ConfigRef) =
|
||||
rawMessage(hintConf, scriptName)
|
||||
passes.gIncludeFile = includeModule
|
||||
passes.gImportModule = importModule
|
||||
|
||||
@@ -101,7 +101,7 @@ proc newOpCall(op: PSym; x: PNode): PNode =
|
||||
proc destructorCall(c: PContext; op: PSym; x: PNode): PNode =
|
||||
result = newNodeIT(nkCall, x.info, op.typ.sons[0])
|
||||
result.add(newSymNode(op))
|
||||
if newDestructors:
|
||||
if destructor in c.features:
|
||||
result.add genAddr(c, x)
|
||||
else:
|
||||
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
|
||||
## to ensure we lift assignment, destructors and moves properly.
|
||||
## 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:
|
||||
# do not produce wrong liftings while we're still instantiating generics:
|
||||
# now disabled; breaks topttree.nim!
|
||||
|
||||
@@ -434,7 +434,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
||||
"Non-matching candidates for " & renderTree(n) & "\n" &
|
||||
candidates)
|
||||
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:
|
||||
#
|
||||
# XXX: why is this here?
|
||||
|
||||
@@ -130,6 +130,7 @@ type
|
||||
signatures*: TStrTable
|
||||
recursiveDep*: string
|
||||
suggestionsMade*: bool
|
||||
features*: set[Feature]
|
||||
inTypeContext*: int
|
||||
typesWithOps*: seq[(PType, PType)] #\
|
||||
# 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
|
||||
initStrTable(result.signatures)
|
||||
result.typesWithOps = @[]
|
||||
|
||||
result.features = graph.config.features
|
||||
|
||||
proc inclSym(sq: var TSymSeq, s: PSym) =
|
||||
var L = len(sq)
|
||||
@@ -398,6 +399,3 @@ proc checkMinSonsLen*(n: PNode, length: int) =
|
||||
|
||||
proc isTopLevel*(c: PContext): bool {.inline.} =
|
||||
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)
|
||||
if result.state != csMatch:
|
||||
# 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
|
||||
initCandidate(c, result, t)
|
||||
matches(c, n, nOrig, result)
|
||||
@@ -1452,7 +1452,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||
typeMismatch(n.info, lhs.typ, rhsTyp)
|
||||
|
||||
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
|
||||
mode != noOverloadedAsgn:
|
||||
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.typ = getSysType(tyString)
|
||||
of mParallel:
|
||||
if not experimentalMode(c):
|
||||
if parallel notin c.features:
|
||||
localError(n.info, "use the {.experimental.} pragma to enable 'parallel'")
|
||||
result = setMs(n, s)
|
||||
var x = n.lastSon
|
||||
|
||||
@@ -385,30 +385,9 @@ proc checkNilable(v: PSym) =
|
||||
include semasgn
|
||||
|
||||
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 value = identDefs[L-1]
|
||||
if value.typ != nil and tfHasAsgn in value.typ.flags and not newDestructors:
|
||||
# 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:
|
||||
if result.kind == nkStmtList:
|
||||
let o = copyNode(orig)
|
||||
o.add identDefs
|
||||
result.add o
|
||||
@@ -1267,9 +1246,6 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
gp = newNodeI(nkGenericParams, n.info)
|
||||
|
||||
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)
|
||||
# paramsTypeCheck(c, s.typ)
|
||||
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) =
|
||||
case s.name.s.normalize
|
||||
of "destroy", "=destroy":
|
||||
if newDestructors:
|
||||
let t = s.typ
|
||||
var noError = false
|
||||
if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar:
|
||||
var obj = t.sons[1].sons[0]
|
||||
while true:
|
||||
incl(obj.flags, tfHasAsgn)
|
||||
if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon
|
||||
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
|
||||
else: break
|
||||
if obj.kind in {tyObject, tyDistinct}:
|
||||
if obj.destructor.isNil:
|
||||
obj.destructor = s
|
||||
else:
|
||||
localError(n.info, errGenerated,
|
||||
"cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
|
||||
noError = true
|
||||
if not noError and sfSystemModule notin s.owner.flags:
|
||||
localError(n.info, errGenerated,
|
||||
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
|
||||
of "=destroy":
|
||||
let t = s.typ
|
||||
var noError = false
|
||||
if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar:
|
||||
var obj = t.sons[1].sons[0]
|
||||
while true:
|
||||
incl(obj.flags, tfHasAsgn)
|
||||
if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon
|
||||
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
|
||||
else: break
|
||||
if obj.kind in {tyObject, tyDistinct}:
|
||||
if obj.destructor.isNil:
|
||||
obj.destructor = s
|
||||
else:
|
||||
localError(n.info, errGenerated,
|
||||
"cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
|
||||
noError = true
|
||||
if not noError and sfSystemModule notin s.owner.flags:
|
||||
localError(n.info, errGenerated,
|
||||
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
|
||||
incl(s.flags, sfUsed)
|
||||
of "deepcopy", "=deepcopy":
|
||||
if s.typ.len == 2 and
|
||||
@@ -1612,9 +1587,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
s.options = gOptions
|
||||
if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n)
|
||||
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)
|
||||
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)
|
||||
|
||||
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.lastSon.typeInst == nil
|
||||
newbody.lastSon.typeInst = result
|
||||
if newDestructors:
|
||||
if destructor in cl.c.features:
|
||||
cl.c.typesWithOps.add((newbody, result))
|
||||
else:
|
||||
typeBound(cl.c, newbody, result, assignment, cl.info)
|
||||
@@ -545,7 +545,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
else: discard
|
||||
|
||||
proc instAllTypeBoundOp*(c: PContext, info: TLineInfo) =
|
||||
if not newDestructors: return
|
||||
if destructor notin c.features: return
|
||||
var i = 0
|
||||
while i < c.typesWithOps.len:
|
||||
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?
|
||||
# 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 argsCount = 0
|
||||
while true:
|
||||
@@ -36,19 +36,19 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||
of cmdLongoption, cmdShortOption:
|
||||
if p.key == " ":
|
||||
p.key = "-"
|
||||
if processArgument(pass, p, argsCount): break
|
||||
if processArgument(pass, p, argsCount, config): break
|
||||
else:
|
||||
processSwitch(pass, p)
|
||||
processSwitch(pass, p, config)
|
||||
of cmdArgument:
|
||||
if processArgument(pass, p, argsCount): break
|
||||
if processArgument(pass, p, argsCount, config): break
|
||||
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, [])
|
||||
|
||||
proc serve*(cache: IdentCache; action: proc (cache: IdentCache){.nimcall.}) =
|
||||
proc serve*(cache: IdentCache; action: proc (cache: IdentCache){.nimcall.}; config: ConfigRef) =
|
||||
template execute(cmd) =
|
||||
curCaasCmd = cmd
|
||||
processCmdLine(passCmd2, cmd)
|
||||
processCmdLine(passCmd2, cmd, config)
|
||||
action(cache)
|
||||
gErrorCounter = 0
|
||||
|
||||
|
||||
@@ -979,7 +979,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode =
|
||||
#result = liftLambdas(prc, result)
|
||||
when useEffectSystem: trackProc(prc, result)
|
||||
result = liftLocalsIfRequested(prc, result)
|
||||
if c.needsDestroyPass and newDestructors:
|
||||
if c.needsDestroyPass: #and newDestructors:
|
||||
result = injectDestructorCalls(prc, result)
|
||||
incl(result.flags, nfTransf)
|
||||
#if prc.name.s == "testbody":
|
||||
@@ -996,7 +996,7 @@ proc transformStmt*(module: PSym, n: PNode): PNode =
|
||||
when useEffectSystem: trackTopLevelStmt(module, result)
|
||||
#if n.info ?? "temp.nim":
|
||||
# echo renderTree(result, {renderIds})
|
||||
if c.needsDestroyPass and newDestructors:
|
||||
if c.needsDestroyPass:
|
||||
result = injectDestructorCalls(module, result)
|
||||
incl(result.flags, nfTransf)
|
||||
|
||||
@@ -1007,6 +1007,6 @@ proc transformExpr*(module: PSym, n: PNode): PNode =
|
||||
var c = openTransf(module, "")
|
||||
result = processTransf(c, n, module)
|
||||
liftDefer(c, result)
|
||||
if c.needsDestroyPass and newDestructors:
|
||||
if c.needsDestroyPass:
|
||||
result = injectDestructorCalls(module, result)
|
||||
incl(result.flags, nfTransf)
|
||||
|
||||
@@ -55,7 +55,8 @@ type
|
||||
wFloatchecks, wNanChecks, wInfChecks, wMoveChecks,
|
||||
wAssertions, wPatterns, wWarnings,
|
||||
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,
|
||||
wCompileTime, wNoInit,
|
||||
wPassc, wPassl, wBorrow, wDiscardable,
|
||||
@@ -143,7 +144,8 @@ const
|
||||
|
||||
"assertions", "patterns", "warnings", "hints",
|
||||
"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",
|
||||
"compiletime", "noinit",
|
||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||
|
||||
@@ -35,7 +35,8 @@ Advanced options:
|
||||
--noLinking compile Nim and generated files but do not link
|
||||
--noMain do not generate a main procedure
|
||||
--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
|
||||
--os:SYMBOL set the target operating system (cross-compilation)
|
||||
--cpu:SYMBOL set the target processor (cross-compilation)
|
||||
@@ -88,5 +89,6 @@ Advanced options:
|
||||
--parallelBuild:0|1|... perform a parallel build
|
||||
value = number of processors (0 for auto-detect)
|
||||
--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
|
||||
|
||||
@@ -29,7 +29,6 @@ Options:
|
||||
--nanChecks:on|off turn NaN checks on|off
|
||||
--infChecks:on|off turn Inf 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
|
||||
Note: use -d:release for a release build!
|
||||
--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
|
||||
call. But currently this feature has to be only enabled
|
||||
via ``{.experimental.}``:
|
||||
via ``{.experimental: "implicitDeref".}``:
|
||||
|
||||
.. code-block:: nim
|
||||
{.experimental.}
|
||||
{.experimental: "implicitDeref".}
|
||||
|
||||
proc depth(x: NodeObj): int = ...
|
||||
|
||||
@@ -5588,7 +5588,7 @@ dot operators
|
||||
-------------
|
||||
|
||||
**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
|
||||
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
|
||||
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
|
||||
@@ -6901,17 +6885,12 @@ is uncertain (it may be removed any time).
|
||||
Example:
|
||||
|
||||
.. code-block:: nim
|
||||
{.experimental.}
|
||||
type
|
||||
FooId = distinct int
|
||||
BarId = distinct int
|
||||
using
|
||||
foo: FooId
|
||||
bar: BarId
|
||||
{.experimental: "parallel".}
|
||||
|
||||
proc useUsing(bar, foo) =
|
||||
echo "bar is of type BarId"
|
||||
echo "foo is of type FooId"
|
||||
parallel:
|
||||
for i in 0..4:
|
||||
echo "echo in parallel"
|
||||
|
||||
|
||||
Implementation Specific Pragmas
|
||||
@@ -7933,7 +7912,7 @@ Example:
|
||||
|
||||
# Compute PI in an inefficient way
|
||||
import strutils, math, threadpool
|
||||
{.experimental.}
|
||||
{.experimental: "parallel".}
|
||||
|
||||
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
|
||||
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``.
|
||||
|
||||
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::
|
||||
|
||||
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
|
||||
a file ``panicoverride.nim``.
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
include "system/inclrtl"
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
when hostOS == "solaris":
|
||||
{.passl: "-lsocket -lnsl".}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
##
|
||||
## theDb.close()
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
import strutils, sqlite3
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
## is used. This suffices because Windows' console already provides the
|
||||
## wanted functionality.
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
when defined(Windows):
|
||||
proc readLineFromStdin*(prompt: string): TaintedString {.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
from posix import SocketHandle
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
# Get the platform-dependent flags.
|
||||
# Structure describing an inotify event.
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
|
||||
from posix import Timespec
|
||||
|
||||
when defined(macosx) or defined(freebsd) or defined(openbsd) or
|
||||
@@ -61,7 +59,7 @@ const
|
||||
EV_CLEAR* = 0x0020 ## Clear event state after reporting.
|
||||
EV_RECEIPT* = 0x0040 ## Force EV_ERROR on success, data == 0
|
||||
EV_DISPATCH* = 0x0080 ## Disable event after reporting.
|
||||
|
||||
|
||||
EV_SYSFLAGS* = 0xF000 ## Reserved by system
|
||||
EV_DROP* = 0x1000 ## Not should be dropped
|
||||
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_FFOR* = 0x80000000'u32 ## OR 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_TRIGGER* = 0x01000000'u32 ## Cause the event to be triggered
|
||||
NOTE_TRIGGER* = 0x01000000'u32 ## Cause the event to be triggered
|
||||
## for output.
|
||||
|
||||
# data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{.deadCodeElim:on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
import posix
|
||||
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
## resulting C code will just ``#include <XYZ.h>`` and *not* define the
|
||||
## symbols declared here.
|
||||
|
||||
# This ensures that we don't accidentally generate #includes for files that
|
||||
# might not exist on a specific platform! The user will get an error only
|
||||
# if they actualy try to use the missing declaration
|
||||
{.deadCodeElim: on.}
|
||||
# Dead code elimination ensures that we don't accidentally generate #includes
|
||||
# for files that might not exist on a specific platform! The user will get an
|
||||
# error only if they actualy try to use the missing declaration
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
# 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?
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
const
|
||||
hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
import posix
|
||||
|
||||
type
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## Floating-point environment. Handling of floating-point rounding and
|
||||
## exceptions (overflow, division by zero, etc.).
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
when defined(Posix) and not defined(haiku):
|
||||
{.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
|
||||
## 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
|
||||
## 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
|
||||
## Number of digits (in base ``floatingPointRadix``) in the mantissa
|
||||
## 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
|
||||
## The difference between 1.0 and the smallest number greater than
|
||||
## 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.
|
||||
{.deprecated.}
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
## ``newSocket()``. The difference is that the latter creates a new file
|
||||
## descriptor.
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
import nativesockets, os, strutils, parseutils, times, sets, options
|
||||
export Port, `$`, `==`
|
||||
export Domain, SockType, Protocol
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## This module contains basic operating system facilities like
|
||||
## retrieving environment variables, reading command line arguments,
|
||||
## working with directories, running shell commands, etc.
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
{.push debugger: off.}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
##
|
||||
## 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
|
||||
# of the standard library!
|
||||
|
||||
@@ -192,7 +192,7 @@ when not defined(nimscript):
|
||||
## Initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount. Note: Does not work for NimScript.
|
||||
let now = times.getTime()
|
||||
randomize(convert(Seconds, Nanoseconds, now.toUnix) + now.nanoseconds)
|
||||
randomize(convert(Seconds, Nanoseconds, now.toUnix) + now.nanosecond)
|
||||
|
||||
{.pop.}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
include "system/inclrtl"
|
||||
import streams
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
import strutils
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
proc expandTabs*(s: string, tabSize: int = 8): string {.noSideEffect,
|
||||
procvar.} =
|
||||
|
||||
@@ -17,7 +17,7 @@ import parseutils
|
||||
from math import pow, round, floor, log10
|
||||
from algorithm import reverse
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
@@ -1818,20 +1818,29 @@ proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect,
|
||||
dec(L)
|
||||
|
||||
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>`_
|
||||
## for the escaping scheme.
|
||||
##
|
||||
## The resulting string is prefixed with `prefix` and suffixed with `suffix`.
|
||||
## 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.add(prefix)
|
||||
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)
|
||||
|
||||
proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
||||
rtl, extern: "nsuUnescape".} =
|
||||
rtl, extern: "nsuUnescape", deprecated.} =
|
||||
## Unescapes a string `s`.
|
||||
##
|
||||
## 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
|
||||
## ValueError exception will be raised.
|
||||
##
|
||||
## **Warning:** This procedure is deprecated because it's to easy to missuse.
|
||||
result = newStringOfCap(s.len)
|
||||
var i = prefix.len
|
||||
if not s.startsWith(prefix):
|
||||
|
||||
@@ -103,7 +103,7 @@ type
|
||||
|
||||
Time* = object ## Represents a point in time.
|
||||
seconds: int64
|
||||
nanoseconds: NanosecondRange
|
||||
nanosecond: NanosecondRange
|
||||
|
||||
DateTime* = object of RootObj ## Represents a time in different parts.
|
||||
## Although this type can represent leap
|
||||
@@ -159,7 +159,7 @@ type
|
||||
## This type should be prefered over ``TimeInterval`` unless
|
||||
## non-static time units is needed.
|
||||
seconds: int64
|
||||
nanoseconds: NanosecondRange
|
||||
nanosecond: NanosecondRange
|
||||
|
||||
TimeUnit* = enum ## Different units of time.
|
||||
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
|
||||
## positive nanosecond part in the range ``NanosecondRange``.
|
||||
result.seconds = seconds + convert(Nanoseconds, Seconds, nanoseconds)
|
||||
var nanoseconds = nanoseconds mod convert(Seconds, Nanoseconds, 1)
|
||||
if nanoseconds < 0:
|
||||
nanoseconds += convert(Seconds, Nanoseconds, 1)
|
||||
var nanosecond = nanoseconds mod convert(Seconds, Nanoseconds, 1)
|
||||
if nanosecond < 0:
|
||||
nanosecond += convert(Seconds, Nanoseconds, 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.
|
||||
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
|
||||
## of nanoseconds of the second.
|
||||
time.nanoseconds
|
||||
time.nanosecond
|
||||
|
||||
proc initDuration*(nanoseconds, microseconds, milliseconds,
|
||||
seconds, minutes, hours, days, weeks: int64 = 0): Duration =
|
||||
@@ -281,7 +281,7 @@ proc milliseconds*(dur: Duration): int {.inline.} =
|
||||
runnableExamples:
|
||||
let dur = initDuration(seconds = 1, milliseconds = 1)
|
||||
doAssert dur.milliseconds == 1
|
||||
convert(Nanoseconds, Milliseconds, dur.nanoseconds)
|
||||
convert(Nanoseconds, Milliseconds, dur.nanosecond)
|
||||
|
||||
proc microseconds*(dur: Duration): int {.inline.} =
|
||||
## Number of whole microseconds represented by the **fractional**
|
||||
@@ -289,7 +289,7 @@ proc microseconds*(dur: Duration): int {.inline.} =
|
||||
runnableExamples:
|
||||
let dur = initDuration(seconds = 1, microseconds = 1)
|
||||
doAssert dur.microseconds == 1
|
||||
convert(Nanoseconds, Microseconds, dur.nanoseconds)
|
||||
convert(Nanoseconds, Microseconds, dur.nanosecond)
|
||||
|
||||
proc nanoseconds*(dur: Duration): int {.inline.} =
|
||||
## Number of whole nanoseconds represented by the **fractional**
|
||||
@@ -297,14 +297,14 @@ proc nanoseconds*(dur: Duration): int {.inline.} =
|
||||
runnableExamples:
|
||||
let dur = initDuration(seconds = 1, nanoseconds = 1)
|
||||
doAssert dur.nanoseconds == 1
|
||||
dur.nanoseconds
|
||||
dur.nanosecond
|
||||
|
||||
proc fractional*(dur: Duration): Duration {.inline.} =
|
||||
## The fractional part of duration, as a duration.
|
||||
runnableExamples:
|
||||
let dur = initDuration(seconds = 1, 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.
|
||||
##
|
||||
@@ -322,7 +322,7 @@ proc `$`*(dur: Duration): string =
|
||||
doAssert $initDuration(milliseconds = -1500) == "-1 second and -500 milliseconds"
|
||||
var parts = newSeq[string]()
|
||||
var remS = dur.seconds
|
||||
var remNs = dur.nanoseconds.int
|
||||
var remNs = dur.nanosecond.int
|
||||
|
||||
# Normally ``nanoseconds`` should always be positive, but
|
||||
# that makes no sense when printing.
|
||||
@@ -387,7 +387,7 @@ proc fromWinTime*(win: int64): Time =
|
||||
|
||||
proc toWinTime*(t: Time): int64 =
|
||||
## 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 =
|
||||
## 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 .}
|
||||
|
||||
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 =
|
||||
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 =
|
||||
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 =
|
||||
a.seconds <= b.seconds or (
|
||||
a.seconds == b.seconds and a.nanoseconds <= b.seconds)
|
||||
a.seconds < b.seconds or (
|
||||
a.seconds == b.seconds and a.nanosecond <= b.nanosecond)
|
||||
|
||||
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.} =
|
||||
## Add two durations together.
|
||||
@@ -507,7 +507,7 @@ proc `-`*(a: Duration): Duration {.operator.} =
|
||||
## Reverse a duration.
|
||||
runnableExamples:
|
||||
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.} =
|
||||
## Note that a duration can be negative,
|
||||
@@ -530,7 +530,7 @@ proc `*`*(a: int64, b: Duration): Duration {.operator} =
|
||||
## Multiply a duration by some scalar.
|
||||
runnableExamples:
|
||||
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} =
|
||||
## 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(nanoseconds = 3) div 2 == initDuration(nanoseconds = 1)
|
||||
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".} =
|
||||
## Computes the duration between two points in time.
|
||||
@@ -600,7 +600,7 @@ proc abs*(a: Duration): Duration =
|
||||
runnableExamples:
|
||||
doAssert initDuration(milliseconds = -1500).abs ==
|
||||
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.} =
|
||||
## Converts a broken-down time structure to
|
||||
@@ -650,7 +650,7 @@ proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime =
|
||||
hour: hour,
|
||||
minute: minute,
|
||||
second: second,
|
||||
nanosecond: zt.adjTime.nanoseconds,
|
||||
nanosecond: zt.adjTime.nanosecond,
|
||||
weekday: getDayOfWeek(d, m, y),
|
||||
yearday: getDayOfYear(d, m, y),
|
||||
isDst: zt.isDst,
|
||||
@@ -809,7 +809,7 @@ else:
|
||||
# as a result of offset changes (normally due to dst)
|
||||
let utcUnix = adjTime.seconds + utcOffset
|
||||
let (finalOffset, dst) = getLocalOffsetAndDst(utcUnix)
|
||||
result.adjTime = initTime(utcUnix - finalOffset, adjTime.nanoseconds)
|
||||
result.adjTime = initTime(utcUnix - finalOffset, adjTime.nanosecond)
|
||||
result.utcOffset = finalOffset
|
||||
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.
|
||||
##
|
||||
## **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.} =
|
||||
## 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.
|
||||
let dur = getTime() - start
|
||||
result = (convert(Seconds, Milliseconds, dur.seconds) +
|
||||
convert(Nanoseconds, Milliseconds, dur.nanoseconds)).int
|
||||
convert(Nanoseconds, Milliseconds, dur.nanosecond)).int
|
||||
else:
|
||||
proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} =
|
||||
when defined(macosx):
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
## This module provides support to handle the Unicode UTF-8 encoding.
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
include "system/inclrtl"
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
import macros, strtabs
|
||||
|
||||
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
|
||||
xnElement, ## an element with 0 or more children
|
||||
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]
|
||||
result.fAttr = attributes
|
||||
|
||||
proc xmlConstructor(e: NimNode): NimNode {.compileTime.} =
|
||||
expectLen(e, 2)
|
||||
var a = e[1]
|
||||
proc xmlConstructor(a: NimNode): NimNode {.compileTime.} =
|
||||
if a.kind == nnkCall:
|
||||
result = newCall("newXmlTree", toStrLit(a[0]))
|
||||
var attrs = newNimNode(nnkBracket, a)
|
||||
@@ -348,7 +346,6 @@ macro `<>`*(x: untyped): untyped =
|
||||
##
|
||||
## <a href="http://nim-lang.org">Nim rules.</a>
|
||||
##
|
||||
let x = callsite()
|
||||
result = xmlConstructor(x)
|
||||
|
||||
proc child*(n: XmlNode, name: string): XmlNode =
|
||||
|
||||
@@ -146,7 +146,7 @@ proc declared*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
||||
## # missing it.
|
||||
|
||||
when defined(useNimRtl):
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
proc definedInScope*(x: untyped): bool {.
|
||||
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 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.
|
||||
##
|
||||
## The procedure has been designed so that its output is usable for many
|
||||
## different common syntaxes.
|
||||
## **Note**: This is not correct for producing Ansi C code!
|
||||
case c
|
||||
of '\0'..'\31', '\127'..'\255':
|
||||
add(s, "\\x")
|
||||
of '\a': s.add "\\a" # \x07
|
||||
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"
|
||||
let n = ord(c)
|
||||
s.add(HexChars[int((n and 0xF0) shr 4)])
|
||||
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) =
|
||||
## Appends `x` to string `s` in place, applying quoting and escaping
|
||||
## if `x` is a string or char. See
|
||||
## `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
|
||||
## 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:
|
||||
s.add("\"")
|
||||
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("\"")
|
||||
elif T is char:
|
||||
s.add("'")
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## 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.
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
import dynlib
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
# ****************************************************************************
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
when defined(windows):
|
||||
const dllname = "iup(|30|27|26|25|24).dll"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
{.push, callconv: cdecl.}
|
||||
|
||||
when defined(Unix):
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
when not defined(ODBCVER):
|
||||
const
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
## ./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
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
const useWinVersion = defined(Windows) or defined(nimdoc)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
# The current PCRE version information.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# connection-protocol.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
|
||||
when defined(windows):
|
||||
const
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
{.deadCodeElim: on.} # dce option deprecated
|
||||
when defined(windows):
|
||||
when defined(nimOldDlls):
|
||||
const Lib = "sqlite3.dll"
|
||||
|
||||
@@ -518,7 +518,7 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
|
||||
close(requests)
|
||||
close(results)
|
||||
|
||||
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||
proc processCmdLine*(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||
var p = parseopt.initOptParser(cmd)
|
||||
while true:
|
||||
parseopt.next(p)
|
||||
@@ -562,7 +562,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||
gRefresh = true
|
||||
of "maxresults":
|
||||
suggestMaxResults = parseInt(p.val)
|
||||
else: processSwitch(pass, p)
|
||||
else: processSwitch(pass, p, config)
|
||||
of cmdArgument:
|
||||
let a = unixToNativePath(p.key)
|
||||
if dirExists(a) and not fileExists(a.addFileExt("nim")):
|
||||
@@ -577,7 +577,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||
if paramCount() == 0:
|
||||
stdout.writeline(Usage)
|
||||
else:
|
||||
processCmdLine(passCmd1, "")
|
||||
processCmdLine(passCmd1, "", config)
|
||||
if gMode != mstdin:
|
||||
msgs.writelnHook = proc (msg: string) = discard
|
||||
if gProjectName != "":
|
||||
@@ -616,7 +616,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||
runNimScript(cache, gProjectPath / "config.nims", freshDefines=false, config)
|
||||
|
||||
extccomp.initVars()
|
||||
processCmdLine(passCmd2, "")
|
||||
processCmdLine(passCmd2, "", config)
|
||||
|
||||
let graph = newModuleGraph(config)
|
||||
graph.suggestMode = true
|
||||
|
||||
@@ -14,6 +14,7 @@ GenericT[T] '=' bool
|
||||
GenericT[T] '=' bool
|
||||
GenericT[T] '=' bool
|
||||
GenericT[T] '=' bool'''
|
||||
disabled: "true"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
output: '''i value 88
|
||||
2aa'''
|
||||
disabled: "true"
|
||||
"""
|
||||
|
||||
import moverload_asgn2
|
||||
|
||||
@@ -85,14 +85,20 @@ block:
|
||||
s.addQuoted('\0')
|
||||
s.addQuoted('\31')
|
||||
s.addQuoted('\127')
|
||||
s.addQuoted('\255')
|
||||
doAssert s == "'\\x00''\\x1F''\\x7F''\\xFF'"
|
||||
doAssert s == "'\\x00''\\x1F''\\x7F'"
|
||||
block:
|
||||
var s = ""
|
||||
s.addQuoted('\\')
|
||||
s.addQuoted('\'')
|
||||
s.addQuoted('\"')
|
||||
doAssert s == """'\\''\'''\"'"""
|
||||
block:
|
||||
var s = ""
|
||||
s.addQuoted("å")
|
||||
s.addQuoted("ä")
|
||||
s.addQuoted("ö")
|
||||
s.addEscapedChar('\xFF')
|
||||
doAssert s == """"å""ä""ö"\xFF"""
|
||||
|
||||
# Test customized element representation
|
||||
type CustomString = object
|
||||
|
||||
@@ -4,7 +4,7 @@ type
|
||||
TOption = enum
|
||||
optNone, optForceFullMake, optBoehmGC, optRefcGC, optRangeCheck,
|
||||
optBoundsCheck, optOverflowCheck, optNilCheck, optAssert, optLineDir,
|
||||
optWarns, optHints, optDeadCodeElim, optListCmd, optCompileOnly,
|
||||
optWarns, optHints, optListCmd, optCompileOnly,
|
||||
optSafeCode, # only allow safe code
|
||||
optStyleCheck, optOptimizeSpeed, optOptimizeSize, optGenDynLib,
|
||||
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
|
||||
|
||||
{.deadCodeElim:on.}
|
||||
|
||||
type
|
||||
Obj = object
|
||||
iter: iterator (): int8 {.closure.}
|
||||
|
||||
@@ -23,7 +23,6 @@ const Lib = "libchipmunk.so.6.1.1"
|
||||
|
||||
when defined(MoreNim):
|
||||
{.hint: "MoreNim defined; some Chipmunk functions replaced in Nim".}
|
||||
{.deadCodeElim: on.}
|
||||
from math import sqrt, sin, cos, arctan2
|
||||
when defined(CpUseFloat):
|
||||
{.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)"
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
const
|
||||
ENET_VERSION_MAJOR* = 1
|
||||
ENET_VERSION_MINOR* = 3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import macros
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
#Inline macro.add() to allow for easier nesting
|
||||
proc und*(a: NimNode; b: NimNode): NimNode {.compileTime.} =
|
||||
a.add(b)
|
||||
|
||||
@@ -12,7 +12,7 @@ else:
|
||||
LibS = "libcsfml-system.so.2.0"
|
||||
LibW = "libcsfml-window.so.2.0"
|
||||
#{.error: "Platform unsupported".}
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
{.pragma: pf, pure, final.}
|
||||
type
|
||||
PClock* = ptr TClock
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import sfml
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
let
|
||||
Black*: TColor = color(0, 0, 0)
|
||||
White*: TColor = color(255, 255, 255)
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
import sfml, math, strutils
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
@@ -5,7 +5,7 @@ import
|
||||
sg_gui, sg_assets, sound_buffer, enet_client
|
||||
when defined(profiler):
|
||||
import nimprof
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
type
|
||||
PPlayer* = ref TPlayer
|
||||
TPlayer* = object
|
||||
|
||||
@@ -2,7 +2,7 @@ import
|
||||
sfml, sfml_colors,
|
||||
input_helpers, sg_packets
|
||||
from strutils import countlines
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
type
|
||||
PGuiContainer* = ref TGuiContainer
|
||||
TGuiContainer* = object of TObject
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
debugger = off
|
||||
deadCodeElim = on
|
||||
path = ".."
|
||||
path = "../genpacket"
|
||||
path = "../helpers"
|
||||
|
||||
@@ -10,7 +10,7 @@ const
|
||||
ExeName = "keineschweine"
|
||||
ServerDefines = "-d:NoSFML -d:NoChipmunk"
|
||||
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"
|
||||
|
||||
task "testprofile", "..":
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
--os:standalone
|
||||
--deadCodeElim:on
|
||||
--gc:none
|
||||
|
||||
@@ -4,7 +4,7 @@ discard """
|
||||
|
||||
import threadpool, sequtils
|
||||
|
||||
{.experimental.}
|
||||
{.experimental: "parallel".}
|
||||
|
||||
proc linearFind(a: openArray[int]; x, offset: int): int =
|
||||
for i, y in a:
|
||||
|
||||
@@ -2,13 +2,16 @@ discard """
|
||||
ccodeCheck: "\\i @'__attribute__((noreturn))' .*"
|
||||
"""
|
||||
|
||||
proc noret1*(i: int) {.noreturn.} =
|
||||
proc noret1*(i: int) {.noreturn.} =
|
||||
echo i
|
||||
|
||||
|
||||
proc noret2*(i: int): void {.noreturn.} =
|
||||
proc noret2*(i: int): void {.noreturn.} =
|
||||
echo i
|
||||
|
||||
noret1(1)
|
||||
noret2(2)
|
||||
|
||||
var p {.used.}: proc(i: int): int
|
||||
doAssert(not compiles(
|
||||
p = proc(i: int): int {.noreturn.} = i # noreturn lambda returns int
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
proc p1*(x, y: int): int =
|
||||
result = x + y
|
||||
|
||||
|
||||
@@ -367,6 +367,10 @@ suite "ttimes":
|
||||
check d(seconds = 0) - d(milliseconds = 1500) == d(milliseconds = -1500)
|
||||
check d(milliseconds = -1500) == d(seconds = -1, 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":
|
||||
discard initDateTime(1, mJan, -35_000, 12, 00, 00, utc())
|
||||
@@ -413,7 +417,7 @@ suite "ttimes":
|
||||
|
||||
test "fromWinTime/toWinTime":
|
||||
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
|
||||
# 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
|
||||
|
||||
proc `$`*(id: MachineId): string {.borrow.}
|
||||
proc `$`(id: CommitId): string {.borrow.}
|
||||
#proc `$`(id: CommitId): string {.borrow.} # not used
|
||||
|
||||
var
|
||||
thisMachine: MachineId
|
||||
|
||||
@@ -63,6 +63,26 @@ proc compileRodFiles(r: var TResults, cat: Category, options: string) =
|
||||
test "gtkex1", true
|
||||
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 ----------------------------------
|
||||
|
||||
proc safeCopyFile(src, dest: string) =
|
||||
@@ -323,7 +343,7 @@ var nimbleDir = getEnv("NIMBLE_DIR").string
|
||||
if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble"
|
||||
let
|
||||
nimbleExe = findExe("nimble")
|
||||
packageDir = nimbleDir / "pkgs"
|
||||
#packageDir = nimbleDir / "pkgs" # not used
|
||||
packageIndex = nimbleDir / "packages.json"
|
||||
|
||||
proc waitForExitEx(p: Process): int =
|
||||
@@ -407,9 +427,9 @@ proc `&.?`(a, b: string): string =
|
||||
# candidate for the stdlib?
|
||||
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?
|
||||
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) =
|
||||
let test = "tests" & DirSep &.? cat.string / test
|
||||
@@ -429,6 +449,8 @@ proc processCategory(r: var TResults, cat: Category, options: string) =
|
||||
jsTests(r, cat, options)
|
||||
of "dll":
|
||||
dllTests(r, cat, options)
|
||||
of "flags":
|
||||
flagTests(r, cat, options)
|
||||
of "gc":
|
||||
gcTests(r, cat, options)
|
||||
of "longgc":
|
||||
|
||||
@@ -121,7 +121,7 @@ proc generateAllTestsContent(outfile: File, allResults: AllTests,
|
||||
|
||||
proc generateHtml*(filename: string, onlyFailing: bool) =
|
||||
let
|
||||
currentTime = getTime().getLocalTime()
|
||||
currentTime = getTime().local()
|
||||
timestring = htmlQuote format(currentTime, "yyyy-MM-dd HH:mm:ss 'UTC'zzz")
|
||||
var outfile = open(filename, fmWrite)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import
|
||||
|
||||
const
|
||||
resultsFile = "testresults.html"
|
||||
jsonFile = "testresults.json"
|
||||
#jsonFile = "testresults.json" # not used
|
||||
Usage = """Usage:
|
||||
tester [options] command [arguments]
|
||||
|
||||
@@ -150,11 +150,11 @@ proc initResults: TResults =
|
||||
result.skipped = 0
|
||||
result.data = ""
|
||||
|
||||
proc readResults(filename: string): TResults =
|
||||
result = marshal.to[TResults](readFile(filename).string)
|
||||
#proc readResults(filename: string): TResults = # not used
|
||||
# result = marshal.to[TResults](readFile(filename).string)
|
||||
|
||||
proc writeResults(filename: string, r: TResults) =
|
||||
writeFile(filename, $$r)
|
||||
#proc writeResults(filename: string, r: TResults) = # not used
|
||||
# writeFile(filename, $$r)
|
||||
|
||||
proc `$`(x: TResults): string =
|
||||
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 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,
|
||||
env: string = ""): TTest =
|
||||
# start with 'actionCompile', will be overwritten in the spec:
|
||||
|
||||
@@ -15,7 +15,7 @@ _nim()
|
||||
return 0
|
||||
fi
|
||||
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
|
||||
[[ "$cur" == "=" ]] && cur=""
|
||||
COMPREPLY=( $(compgen -W 'on off' -- "$cur") )
|
||||
@@ -32,7 +32,7 @@ _nim()
|
||||
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 ) )
|
||||
_filedir '@(nim)'
|
||||
#$split
|
||||
|
||||
@@ -60,8 +60,6 @@ _nim() {
|
||||
'*--infChecks=off[turn Inf checks off]' \
|
||||
'*--nilChecks=on[turn nil checks on]' \
|
||||
'*--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=speed[optimize for speed|size - use -d:release for a release build]' \
|
||||
'*--opt=size[optimize for size]' \
|
||||
|
||||
@@ -11,7 +11,7 @@ import
|
||||
os, strutils, parseopt, pegs, re, terminal
|
||||
|
||||
const
|
||||
Version = "1.1"
|
||||
Version = "1.2"
|
||||
Usage = "nimgrep - Nim Grep Utility Version " & Version & """
|
||||
|
||||
(c) 2012 Andreas Rumpf
|
||||
@@ -35,6 +35,8 @@ Options:
|
||||
--nocolor output will be given without any colours.
|
||||
--oneline show file on each matched line
|
||||
--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
|
||||
--version, -v shows the version
|
||||
"""
|
||||
@@ -42,7 +44,7 @@ Options:
|
||||
type
|
||||
TOption = enum
|
||||
optFind, optReplace, optPeg, optRegex, optRecursive, optConfirm, optStdin,
|
||||
optWord, optIgnoreCase, optIgnoreStyle, optVerbose
|
||||
optWord, optIgnoreCase, optIgnoreStyle, optVerbose, optFilenames
|
||||
TOptions = set[TOption]
|
||||
TConfirmEnum = enum
|
||||
ceAbort, ceYes, ceAll, ceNo, ceNone
|
||||
@@ -135,11 +137,14 @@ proc processFile(pattern; filename: string) =
|
||||
filenameShown = true
|
||||
|
||||
var buffer: string
|
||||
try:
|
||||
buffer = system.readFile(filename)
|
||||
except IOError:
|
||||
echo "cannot open file: ", filename
|
||||
return
|
||||
if optFilenames in options:
|
||||
buffer = filename
|
||||
else:
|
||||
try:
|
||||
buffer = system.readFile(filename)
|
||||
except IOError:
|
||||
echo "cannot open file: ", filename
|
||||
return
|
||||
if optVerbose in options:
|
||||
stdout.writeLine(filename)
|
||||
stdout.flushFile()
|
||||
@@ -293,6 +298,7 @@ for kind, key, val in getopt():
|
||||
of "nocolor": useWriteStyled = false
|
||||
of "oneline": oneline = true
|
||||
of "verbose": incl(options, optVerbose)
|
||||
of "filenames": incl(options, optFilenames)
|
||||
of "help", "h": writeHelp()
|
||||
of "version", "v": writeVersion()
|
||||
else: writeHelp()
|
||||
@@ -304,6 +310,7 @@ when defined(posix):
|
||||
checkOptions({optFind, optReplace}, "find", "replace")
|
||||
checkOptions({optPeg, optRegex}, "peg", "re")
|
||||
checkOptions({optIgnoreCase, optIgnoreStyle}, "ignore_case", "ignore_style")
|
||||
checkOptions({optFilenames, optReplace}, "filenames", "replace")
|
||||
|
||||
if optStdin in options:
|
||||
pattern = ask("pattern [ENTER to exit]: ")
|
||||
|
||||
Reference in New Issue
Block a user