Merge pull request #2 from nim-lang/devel

Pull 25-04-18
This commit is contained in:
Michael Voronin
2018-04-25 12:26:59 +03:00
committed by GitHub
90 changed files with 404 additions and 378 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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:

View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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")

View File

@@ -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

View File

@@ -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) =

View File

@@ -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

View File

@@ -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:

View File

@@ -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])

View File

@@ -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"

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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!

View File

@@ -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?

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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]

View File

@@ -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

View File

@@ -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)

View File

@@ -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",

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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``.

View File

@@ -32,7 +32,7 @@
include "system/inclrtl"
{.deadCodeElim: on.}
{.deadCodeElim: on.} # dce option deprecated
when hostOS == "solaris":
{.passl: "-lsocket -lnsl".}

View File

@@ -81,7 +81,7 @@
##
## theDb.close()
{.deadCodeElim:on.}
{.deadCodeElim: on.} # dce option deprecated
import strutils, sqlite3

View File

@@ -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 {.

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
{.deadCodeElim:on.}
{.deadCodeElim: on.} # dce option deprecated
from posix import SocketHandle

View File

@@ -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.

View File

@@ -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

View File

@@ -1,4 +1,4 @@
{.deadCodeElim:on.}
{.deadCodeElim: on.} # dce option deprecated
import posix

View File

@@ -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?

View File

@@ -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

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
{.deadCodeElim: on.}
{.deadCodeElim: on.} # dce option deprecated
import posix
type

View File

@@ -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)

View File

@@ -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!

View File

@@ -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

View File

@@ -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.}

View File

@@ -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!

View File

@@ -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.}

View File

@@ -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!

View File

@@ -12,7 +12,7 @@
import strutils
{.deadCodeElim: on.}
{.deadCodeElim: on.} # dce option deprecated
proc expandTabs*(s: string, tabSize: int = 8): string {.noSideEffect,
procvar.} =

View File

@@ -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):

View File

@@ -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):

View File

@@ -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"

View File

@@ -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 =

View File

@@ -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("'")

View File

@@ -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

View File

@@ -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"

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
{.deadCodeElim: on.}
{.deadCodeElim: on.} # dce option deprecated
{.push, callconv: cdecl.}
when defined(Unix):

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
{.deadCodeElim: on.}
{.deadCodeElim: on.} # dce option deprecated
when not defined(ODBCVER):
const

View File

@@ -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)

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
{.deadCodeElim: on.}
{.deadCodeElim: on.} # dce option deprecated
# The current PCRE version information.

View File

@@ -15,7 +15,7 @@
# connection-protocol.
#
{.deadCodeElim: on.}
{.deadCodeElim: on.} # dce option deprecated
when defined(windows):
const

View File

@@ -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"

View File

@@ -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

View File

@@ -14,6 +14,7 @@ GenericT[T] '=' bool
GenericT[T] '=' bool
GenericT[T] '=' bool
GenericT[T] '=' bool'''
disabled: "true"
"""
import typetraits

View File

@@ -1,6 +1,7 @@
discard """
output: '''i value 88
2aa'''
disabled: "true"
"""
import moverload_asgn2

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,5 @@
discard """
file: "tgenscript.nim"
"""
echo "--genscript"

View File

@@ -4,8 +4,6 @@ discard """
# bug #2023
{.deadCodeElim:on.}
type
Obj = object
iter: iterator (): int8 {.closure.}

View File

@@ -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".}

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -1,5 +1,5 @@
import sfml
{.deadCodeElim: on.}
let
Black*: TColor = color(0, 0, 0)
White*: TColor = color(255, 255, 255)

View File

@@ -1,2 +1 @@
import sfml, math, strutils
{.deadCodeElim: on.}

View File

@@ -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

View File

@@ -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

View File

@@ -1,5 +1,4 @@
debugger = off
deadCodeElim = on
path = ".."
path = "../genpacket"
path = "../helpers"

View File

@@ -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", "..":

View File

@@ -1,3 +1,2 @@
--os:standalone
--deadCodeElim:on
--gc:none

View File

@@ -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:

View File

@@ -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

View File

@@ -1,6 +1,3 @@
{.deadCodeElim: on.}
proc p1*(x, y: int): int =
result = x + y

View File

@@ -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

View File

@@ -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

View File

@@ -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":

View File

@@ -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)

View File

@@ -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:

View File

@@ -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

View File

@@ -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]' \

View File

@@ -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]: ")