summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/cmdlinehelper.nim6
-rw-r--r--compiler/commands.nim25
-rw-r--r--compiler/extccomp.nim11
-rw-r--r--compiler/main.nim5
-rw-r--r--compiler/modules.nim13
-rw-r--r--compiler/msgs.nim1
-rw-r--r--compiler/nim.nim3
-rw-r--r--compiler/nimconf.nim21
-rw-r--r--compiler/options.nim5
-rw-r--r--compiler/scriptconfig.nim4
-rw-r--r--compiler/vm.nim3
11 files changed, 71 insertions, 26 deletions
diff --git a/compiler/cmdlinehelper.nim b/compiler/cmdlinehelper.nim
index a415afce9..d5a26717d 100644
--- a/compiler/cmdlinehelper.nim
+++ b/compiler/cmdlinehelper.nim
@@ -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:
diff --git a/compiler/commands.nim b/compiler/commands.nim
index cb7517f06..7a94fb612 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -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"):
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 11b001f9d..d97f9a887 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -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:
diff --git a/compiler/main.nim b/compiler/main.nim
index af9102414..242bc0719 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -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
diff --git a/compiler/modules.nim b/compiler/modules.nim
index 87a6bc507..748b74953 100644
--- a/compiler/modules.nim
+++ b/compiler/modules.nim
@@ -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 =
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 0f5879ff6..7b691323f 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -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)
diff --git a/compiler/nim.nim b/compiler/nim.nim
index 15aeccb33..9ff0eedbc 100644
--- a/compiler/nim.nim
+++ b/compiler/nim.nim
@@ -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())
diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim
index 05f234ce6..b6ec1bbc8 100644
--- a/compiler/nimconf.nim
+++ b/compiler/nimconf.nim
@@ -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
diff --git a/compiler/options.nim b/compiler/options.nim
index 872ab9582..58d09938c 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -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},
diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim
index ab7e5e0b5..a353278d6 100644
--- a/compiler/scriptconfig.nim
+++ b/compiler/scriptconfig.nim
@@ -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:
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 761186dc3..8aac11ff7 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -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