mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
* new: `nim -i cmd` * rename -i to -e (for eval); consistent with majority of other programing languages * `nim e -e:cmd` now works; bugfix: `echo cmd | nim e -` now works * honor --betterRun * address comments * --eval alias for -e (replaces undocumented --eval which was a noop) * --eval now defaults to e (nimscript) instead of r * address comment: remove -e, only keep --eval * address comment * fixup * Update compiler/nimconf.nim Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
|
||||
- Added `--declaredlocs` to show symbol declaration location in messages.
|
||||
- Source+Edit links now appear on top of every docgen'd page when `nim doc --git.url:url ...` is given.
|
||||
- Added `nim --eval:cmd` to evaluate a command directly, see `nim --help`
|
||||
|
||||
|
||||
## Tool changes
|
||||
|
||||
@@ -41,7 +41,9 @@ proc initDefinesProg*(self: NimProg, conf: ConfigRef, name: string) =
|
||||
|
||||
proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
|
||||
self.processCmdLine(passCmd1, "", conf)
|
||||
if self.supportsStdinFile and conf.projectName == "-":
|
||||
if conf.projectIsCmd and conf.projectName in ["-", ""]:
|
||||
handleCmdInput(conf)
|
||||
elif self.supportsStdinFile and conf.projectName == "-":
|
||||
handleStdinInput(conf)
|
||||
elif conf.projectName != "":
|
||||
try:
|
||||
@@ -59,6 +61,8 @@ proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: Confi
|
||||
graph: ModuleGraph): bool =
|
||||
if self.suggestMode:
|
||||
conf.command = "nimsuggest"
|
||||
if conf.command == "e":
|
||||
incl(conf.globalOptions, optWasNimscript)
|
||||
loadConfigs(DefaultConfig, cache, conf, graph.idgen) # load all config files
|
||||
|
||||
if not self.suggestMode:
|
||||
|
||||
@@ -383,19 +383,33 @@ proc dynlibOverride(conf: ConfigRef; switch, arg: string, pass: TCmdLinePass, in
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
options.inclDynlibOverride(conf, arg)
|
||||
|
||||
proc handleStdinInput*(conf: ConfigRef) =
|
||||
conf.projectName = "stdinfile"
|
||||
template handleStdinOrCmdInput =
|
||||
conf.projectFull = conf.projectName.AbsoluteFile
|
||||
conf.projectPath = AbsoluteDir getCurrentDir()
|
||||
conf.projectIsStdin = true
|
||||
if conf.outDir.isEmpty:
|
||||
conf.outDir = getNimcacheDir(conf)
|
||||
|
||||
proc handleStdinInput*(conf: ConfigRef) =
|
||||
conf.projectName = "stdinfile"
|
||||
conf.projectIsStdin = true
|
||||
handleStdinOrCmdInput()
|
||||
|
||||
proc handleCmdInput*(conf: ConfigRef) =
|
||||
conf.projectName = "cmdfile"
|
||||
handleStdinOrCmdInput()
|
||||
|
||||
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
conf: ConfigRef) =
|
||||
var
|
||||
key, val: string
|
||||
case switch.normalize
|
||||
of "eval":
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
conf.projectIsCmd = true
|
||||
conf.cmdInput = arg # can be empty (a nim file with empty content is valid too)
|
||||
if conf.command == "":
|
||||
conf.command = "e" # better than "r" as a default
|
||||
conf.implicitCmd = true
|
||||
of "path", "p":
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
for path in nimbleSubs(conf, arg):
|
||||
@@ -781,9 +795,6 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
of "def":
|
||||
expectNoArg(conf, switch, arg, pass, info)
|
||||
conf.ideCmd = ideDef
|
||||
of "eval":
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
conf.evalExpr = arg
|
||||
of "context":
|
||||
expectNoArg(conf, switch, arg, pass, info)
|
||||
conf.ideCmd = ideCon
|
||||
@@ -936,6 +947,8 @@ proc processSwitch*(pass: TCmdLinePass; p: OptParser; config: ConfigRef) =
|
||||
|
||||
proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
||||
argsCount: var int; config: ConfigRef): bool =
|
||||
if argsCount == 0 and config.implicitCmd:
|
||||
argsCount.inc
|
||||
if argsCount == 0:
|
||||
# nim filename.nims is the same as "nim e filename.nims":
|
||||
if p.key.endsWith(".nims"):
|
||||
|
||||
@@ -1022,6 +1022,10 @@ proc writeJsonBuildInstructions*(conf: ConfigRef) =
|
||||
|
||||
lit ",\L\"stdinInput\": "
|
||||
lit $(%* conf.projectIsStdin)
|
||||
lit ",\L\"projectIsCmd\": "
|
||||
lit $(%* conf.projectIsCmd)
|
||||
lit ",\L\"cmdInput\": "
|
||||
lit $(%* conf.cmdInput)
|
||||
|
||||
if optRun in conf.globalOptions or isDefined(conf, "nimBetterRun"):
|
||||
lit ",\L\"cmdline\": "
|
||||
@@ -1051,11 +1055,18 @@ proc changeDetectedViaJsonBuildInstructions*(conf: ConfigRef; projectfile: Absol
|
||||
return true
|
||||
if not data.hasKey("stdinInput"): return true
|
||||
let stdinInput = data["stdinInput"].getBool
|
||||
let projectIsCmd = data["projectIsCmd"].getBool
|
||||
if conf.projectIsStdin or stdinInput:
|
||||
# could optimize by returning false if stdin input was the same,
|
||||
# but I'm not sure how to get full stding input
|
||||
return true
|
||||
|
||||
if conf.projectIsCmd or projectIsCmd:
|
||||
if not (conf.projectIsCmd and projectIsCmd): return true
|
||||
if not data.hasKey("cmdInput"): return true
|
||||
let cmdInput = data["cmdInput"].getStr
|
||||
if cmdInput != conf.cmdInput: return true
|
||||
|
||||
let depfilesPairs = data["depfiles"]
|
||||
doAssert depfilesPairs.kind == JArray
|
||||
for p in depfilesPairs:
|
||||
|
||||
@@ -348,11 +348,12 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||
conf.cmd = cmdInteractive
|
||||
commandInteractive(graph)
|
||||
of "e":
|
||||
if not fileExists(conf.projectFull):
|
||||
if conf.projectIsCmd or conf.projectIsStdin: discard
|
||||
elif not fileExists(conf.projectFull):
|
||||
rawMessage(conf, errGenerated, "NimScript file does not exist: " & conf.projectFull.string)
|
||||
elif not conf.projectFull.string.endsWith(".nims"):
|
||||
rawMessage(conf, errGenerated, "not a NimScript file: " & conf.projectFull.string)
|
||||
# main NimScript logic handled in cmdlinehelper.nim.
|
||||
# main NimScript logic handled in `loadConfigs`.
|
||||
of "nop", "help":
|
||||
# prevent the "success" message:
|
||||
conf.cmd = cmdDump
|
||||
|
||||
@@ -82,6 +82,13 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P
|
||||
var flags = flags
|
||||
if fileIdx == graph.config.projectMainIdx2: flags.incl sfMainModule
|
||||
result = graph.getModule(fileIdx)
|
||||
|
||||
template processModuleAux =
|
||||
var s: PLLStream
|
||||
if sfMainModule in flags:
|
||||
if graph.config.projectIsStdin: s = stdin.llStreamOpen
|
||||
elif graph.config.projectIsCmd: s = llStreamOpen(graph.config.cmdInput)
|
||||
discard processModule(graph, result, idGeneratorFromModule(result), s)
|
||||
if result == nil:
|
||||
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
|
||||
result = loadModuleSym(graph, fileIdx, filename)
|
||||
@@ -91,15 +98,13 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P
|
||||
registerModule(graph, result)
|
||||
else:
|
||||
partialInitModule(result, graph, fileIdx, filename)
|
||||
discard processModule(graph, result, idGeneratorFromModule(result),
|
||||
if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil)
|
||||
processModuleAux()
|
||||
elif graph.isDirty(result):
|
||||
result.flags.excl sfDirty
|
||||
# reset module fields:
|
||||
initStrTable(result.tab)
|
||||
result.ast = nil
|
||||
discard processModule(graph, result, idGeneratorFromModule(result),
|
||||
if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil)
|
||||
processModuleAux()
|
||||
graph.markClientsDirty(fileIdx)
|
||||
|
||||
proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PSym =
|
||||
|
||||
@@ -523,6 +523,7 @@ proc liMessage*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
|
||||
let s = if isRaw: arg else: getMessageStr(msg, arg)
|
||||
if not ignoreMsg:
|
||||
let loc = if info != unknownLineInfo: conf.toFileLineCol(info) & " " else: ""
|
||||
# we could also show `conf.cmdInput` here for `projectIsCmd`
|
||||
var kindmsg = if kind.len > 0: KindFormat % kind else: ""
|
||||
if conf.structuredErrorHook != nil:
|
||||
conf.structuredErrorHook(conf, info, s & kindmsg, sev)
|
||||
|
||||
@@ -79,7 +79,8 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
||||
|
||||
self.processCmdLineAndProjectPath(conf)
|
||||
var graph = newModuleGraph(cache, conf)
|
||||
if not self.loadConfigsAndRunMainCommand(cache, conf, graph): return
|
||||
if not self.loadConfigsAndRunMainCommand(cache, conf, graph):
|
||||
return
|
||||
mainCommand(graph)
|
||||
if conf.hasHint(hintGCStats): echo(GC_getStatistics())
|
||||
#echo(GC_getStatistics())
|
||||
|
||||
@@ -248,11 +248,16 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef; idgen:
|
||||
if readConfigFile(configPath, cache, conf):
|
||||
configFiles.add(configPath)
|
||||
|
||||
template runNimScriptIfExists(path: AbsoluteFile) =
|
||||
template runNimScriptIfExists(path: AbsoluteFile, isMain = false) =
|
||||
let p = path # eval once
|
||||
if fileExists(p):
|
||||
var s: PLLStream
|
||||
if isMain and optWasNimscript in conf.globalOptions:
|
||||
if conf.projectIsStdin: s = stdin.llStreamOpen
|
||||
elif conf.projectIsCmd: s = llStreamOpen(conf.cmdInput)
|
||||
if s == nil and fileExists(p): s = llStreamOpen(p, fmRead)
|
||||
if s != nil:
|
||||
configFiles.add(p)
|
||||
runNimScript(cache, p, idgen, freshDefines = false, conf)
|
||||
runNimScript(cache, p, idgen, freshDefines = false, conf, s)
|
||||
|
||||
if optSkipSystemConfigFile notin conf.globalOptions:
|
||||
readConfigFile(getSystemConfigPath(conf, cfg))
|
||||
@@ -288,19 +293,19 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef; idgen:
|
||||
runNimScriptIfExists(pd / DefaultConfigNims)
|
||||
|
||||
let scriptFile = conf.projectFull.changeFileExt("nims")
|
||||
let isMain = scriptFile == conf.projectFull
|
||||
let scriptIsProj = scriptFile == conf.projectFull
|
||||
template showHintConf =
|
||||
for filename in configFiles:
|
||||
# delayed to here so that `hintConf` is honored
|
||||
rawMessage(conf, hintConf, filename.string)
|
||||
if isMain:
|
||||
if scriptIsProj:
|
||||
showHintConf()
|
||||
configFiles.setLen 0
|
||||
if conf.command != "nimsuggest":
|
||||
runNimScriptIfExists(scriptFile)
|
||||
runNimScriptIfExists(scriptFile, isMain = true)
|
||||
else:
|
||||
if not isMain:
|
||||
runNimScriptIfExists(scriptFile)
|
||||
if not scriptIsProj:
|
||||
runNimScriptIfExists(scriptFile, isMain = true)
|
||||
else:
|
||||
# 'nimsuggest foo.nims' means to just auto-complete the NimScript file
|
||||
discard
|
||||
|
||||
@@ -246,11 +246,13 @@ type
|
||||
evalMacroCounter*: int
|
||||
exitcode*: int8
|
||||
cmd*: TCommands # the command
|
||||
cmdInput*: string # input command
|
||||
projectIsCmd*: bool # whether we're compiling from a command input
|
||||
implicitCmd*: bool # whether some flag triggered an implicit `command`
|
||||
selectedGC*: TGCMode # the selected GC (+)
|
||||
exc*: ExceptionSystem
|
||||
verbosity*: int # how verbose the compiler is
|
||||
numberOfProcessors*: int # number of processors
|
||||
evalExpr*: string # expression for idetools --eval
|
||||
lastCmdTime*: float # when caas is enabled, we measure each command
|
||||
symbolFiles*: SymbolFilesOption
|
||||
|
||||
@@ -418,7 +420,6 @@ proc newConfigRef*(): ConfigRef =
|
||||
macrosToExpand: newStringTable(modeStyleInsensitive),
|
||||
arcToExpand: newStringTable(modeStyleInsensitive),
|
||||
m: initMsgConfig(),
|
||||
evalExpr: "",
|
||||
cppDefines: initHashSet[string](),
|
||||
headerFile: "", features: {}, legacyFeatures: {}, foreignPackageNotes: {hintProcessing, warnUnknownMagic,
|
||||
hintQuitCalled, hintExecuting},
|
||||
|
||||
@@ -199,7 +199,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||
|
||||
proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
|
||||
idgen: IdGenerator;
|
||||
freshDefines=true; conf: ConfigRef) =
|
||||
freshDefines=true; conf: ConfigRef, stream: PLLStream) =
|
||||
let oldSymbolFiles = conf.symbolFiles
|
||||
conf.symbolFiles = disabledSf
|
||||
|
||||
@@ -226,7 +226,7 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
|
||||
graph.vm = vm
|
||||
|
||||
graph.compileSystemModule()
|
||||
discard graph.processModule(m, vm.idgen, llStreamOpen(scriptName, fmRead))
|
||||
discard graph.processModule(m, vm.idgen, stream)
|
||||
|
||||
# watch out, "newruntime" can be set within NimScript itself and then we need
|
||||
# to remember this:
|
||||
|
||||
@@ -2114,6 +2114,9 @@ proc evalStmt*(c: PCtx, n: PNode) =
|
||||
discard execute(c, start)
|
||||
|
||||
proc evalExpr*(c: PCtx, n: PNode): PNode =
|
||||
# deadcode
|
||||
# `nim --eval:"expr"` might've used it at some point for idetools; could
|
||||
# be revived for nimsuggest
|
||||
let n = transformExpr(c.graph, c.idgen, c.module, n)
|
||||
let start = genExpr(c, n)
|
||||
assert c.code[start].opcode != opcEof
|
||||
|
||||
@@ -31,6 +31,9 @@ Options:
|
||||
--app:console|gui|lib|staticlib
|
||||
generate a console app|GUI app|DLL|static library
|
||||
-r, --run run the compiled program with given arguments
|
||||
--eval:cmd evaluates nim code directly; e.g.: `nim --eval:"echo 1"`
|
||||
defaults to `e` (nimscript) but customizable:
|
||||
`nim r --eval:'for a in stdin.lines: echo a'`
|
||||
--fullhelp show all command line switches
|
||||
-h, --help show this help
|
||||
-v, --version show detailed version information
|
||||
|
||||
Reference in New Issue
Block a user