mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
.experimental can now be used to enable specific features
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -276,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)
|
||||
|
||||
@@ -339,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
|
||||
@@ -694,8 +699,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)
|
||||
@@ -706,7 +716,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)
|
||||
@@ -716,10 +727,10 @@ 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
|
||||
@@ -727,19 +738,19 @@ var
|
||||
# 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"):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -103,13 +103,23 @@ 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]
|
||||
|
||||
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
|
||||
@@ -146,8 +156,6 @@ var
|
||||
gListFullPaths*: bool
|
||||
gPreciseStack*: bool = false
|
||||
gNoNimblePath* = false
|
||||
gExperimentalMode*: bool
|
||||
newDestructors*: bool
|
||||
gDynlibOverrideAll*: bool
|
||||
useNimNamespace*: bool
|
||||
|
||||
|
||||
@@ -680,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]
|
||||
@@ -993,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])
|
||||
|
||||
@@ -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":
|
||||
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)
|
||||
|
||||
@@ -35,7 +35,7 @@ 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')
|
||||
--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 +88,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
|
||||
|
||||
@@ -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
|
||||
@@ -6885,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
|
||||
@@ -7917,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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user