summary refs log tree commit diff stats
path: root/compiler/scriptconfig.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/scriptconfig.nim')
-rw-r--r--compiler/scriptconfig.nim159
1 files changed, 117 insertions, 42 deletions
diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim
index ae7e030b8..e3d2bcd45 100644
--- a/compiler/scriptconfig.nim
+++ b/compiler/scriptconfig.nim
@@ -11,12 +11,18 @@
 ## language.
 
 import
-  ast, modules, idents, passes, passaux, condsyms,
-  options, nimconf, sem, semdata, llstream, vm, vmdef, commands, msgs,
-  os, times, osproc, wordrecg, strtabs, modulegraphs, lineinfos
+  ast, modules, idents, condsyms,
+  options, llstream, vm, vmdef, commands,
+  wordrecg, modulegraphs,
+  pathutils, pipelines
+
+when defined(nimPreviewSlimSystem):
+  import std/[syncio, assertions]
+
+import std/[strtabs, os, times, osproc]
 
 # we support 'cmpIgnoreStyle' natively for efficiency:
-from strutils import cmpIgnoreStyle, contains
+from std/strutils import cmpIgnoreStyle, contains
 
 proc listDirs(a: VmArgs, filter: set[PathComponent]) =
   let dir = getString(a, 0)
@@ -26,9 +32,9 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) =
   setResult(a, result)
 
 proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
-              graph: ModuleGraph): PEvalContext =
+              graph: ModuleGraph; idgen: IdGenerator): PEvalContext =
   # For Nimble we need to export 'setupVM'.
-  result = newCtx(module, cache, graph)
+  result = newCtx(module, cache, graph, idgen)
   result.mode = emRepl
   registerAdditionalOps(result)
   let conf = graph.config
@@ -42,48 +48,74 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
       proc (a: VmArgs) =
         body
 
-  template cbos(name, body) {.dirty.} =
+  template cbexc(name, exc, body) {.dirty.} =
     result.registerCallback "stdlib.system." & astToStr(name),
       proc (a: VmArgs) =
-        errorMsg = nil
+        errorMsg = ""
         try:
           body
-        except OSError:
+        except exc:
           errorMsg = getCurrentExceptionMsg()
 
+  template cbos(name, body) {.dirty.} =
+    cbexc(name, OSError, body)
+
   # Idea: Treat link to file as a file, but ignore link to directory to prevent
   # endless recursions out of the box.
-  cbos listFiles:
+  cbos listFilesImpl:
     listDirs(a, {pcFile, pcLinkToFile})
-  cbos listDirs:
+  cbos listDirsImpl:
     listDirs(a, {pcDir})
   cbos removeDir:
-    os.removeDir getString(a, 0)
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.removeDir(getString(a, 0), getBool(a, 1))
   cbos removeFile:
-    os.removeFile getString(a, 0)
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.removeFile getString(a, 0)
   cbos createDir:
     os.createDir getString(a, 0)
-  cbos getOsError:
-    setResult(a, errorMsg)
+
+  result.registerCallback "stdlib.system.getError",
+    proc (a: VmArgs) = setResult(a, errorMsg)
+
   cbos setCurrentDir:
     os.setCurrentDir getString(a, 0)
   cbos getCurrentDir:
     setResult(a, os.getCurrentDir())
   cbos moveFile:
-    os.moveFile(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.moveFile(getString(a, 0), getString(a, 1))
   cbos moveDir:
-    os.moveDir(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.moveDir(getString(a, 0), getString(a, 1))
   cbos copyFile:
-    os.copyFile(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.copyFile(getString(a, 0), getString(a, 1))
   cbos copyDir:
-    os.copyDir(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.copyDir(getString(a, 0), getString(a, 1))
   cbos getLastModificationTime:
     setResult(a, getLastModificationTime(getString(a, 0)).toUnix)
   cbos findExe:
     setResult(a, os.findExe(getString(a, 0)))
 
   cbos rawExec:
-    setResult(a, osproc.execCmd getString(a, 0))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      setResult(a, osproc.execCmd getString(a, 0))
 
   cbconf getEnv:
     setResult(a, os.getEnv(a.getString 0, a.getString 1))
@@ -91,11 +123,19 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
     setResult(a, os.existsEnv(a.getString 0))
   cbconf putEnv:
     os.putEnv(a.getString 0, a.getString 1)
+  cbconf delEnv:
+    os.delEnv(a.getString 0)
   cbconf dirExists:
     setResult(a, os.dirExists(a.getString 0))
   cbconf fileExists:
     setResult(a, os.fileExists(a.getString 0))
 
+  cbconf projectName:
+    setResult(a, conf.projectName)
+  cbconf projectDir:
+    setResult(a, conf.projectPath.string)
+  cbconf projectPath:
+    setResult(a, conf.projectFull.string)
   cbconf thisDir:
     setResult(a, vthisDir)
   cbconf put:
@@ -105,7 +145,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
   cbconf exists:
     setResult(a, options.existsConfigVar(conf, a.getString 0))
   cbconf nimcacheDir:
-    setResult(a, options.getNimcacheDir(conf))
+    setResult(a, options.getNimcacheDir(conf).string)
   cbconf paramStr:
     setResult(a, os.paramStr(int a.getInt 0))
   cbconf paramCount:
@@ -115,20 +155,14 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
   cbconf cmpIgnoreCase:
     setResult(a, strutils.cmpIgnoreCase(a.getString 0, a.getString 1))
   cbconf setCommand:
-    conf.command = a.getString 0
+    conf.setCommandEarly(a.getString 0)
     let arg = a.getString 1
-    if arg.len > 0:
-      conf.projectName = arg
-      let path =
-        if conf.projectName.isAbsolute: conf.projectName
-        else: conf.projectPath / conf.projectName
-      try:
-        conf.projectFull = canonicalizePath(conf, path)
-      except OSError:
-        conf.projectFull = path
+    incl(conf.globalOptions, optWasNimscript)
+    if arg.len > 0: setFromProjectName(conf, arg)
   cbconf getCommand:
     setResult(a, conf.command)
   cbconf switch:
+    conf.currentConfigDir = vthisDir
     processSwitch(a.getString 0, a.getString 1, passPP, module.info, conf)
   cbconf hintImpl:
     processSpecificNote(a.getString 0, wHint, passPP, module.info,
@@ -148,28 +182,68 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
     setResult(a, os.getAppFilename())
   cbconf cppDefine:
     options.cppDefine(conf, a.getString(0))
-
-proc runNimScript*(cache: IdentCache; scriptName: string;
-                   freshDefines=true; conf: ConfigRef) =
-  rawMessage(conf, hintConf, scriptName)
+  cbexc stdinReadLine, EOFError:
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      setResult(a, "")
+    else:
+      setResult(a, stdin.readLine())
+  cbexc stdinReadAll, EOFError:
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      setResult(a, "")
+    else:
+      setResult(a, stdin.readAll())
+
+proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
+                   idgen: IdGenerator;
+                   freshDefines=true; conf: ConfigRef, stream: PLLStream) =
+  let oldSymbolFiles = conf.symbolFiles
+  conf.symbolFiles = disabledSf
 
   let graph = newModuleGraph(cache, conf)
-  connectCallbacks(graph)
+  connectPipelineCallbacks(graph)
   if freshDefines: initDefines(conf.symbols)
 
   defineSymbol(conf.symbols, "nimscript")
   defineSymbol(conf.symbols, "nimconfig")
-  registerPass(graph, semPass)
-  registerPass(graph, evalPass)
 
   conf.searchPaths.add(conf.libpath)
 
+  let oldGlobalOptions = conf.globalOptions
+  let oldSelectedGC = conf.selectedGC
+  unregisterArcOrc(conf)
+  conf.globalOptions.excl optOwnedRefs
+  conf.selectedGC = gcUnselected
+
   var m = graph.makeModule(scriptName)
   incl(m.flags, sfMainModule)
-  graph.vm = setupVM(m, cache, scriptName, graph)
-
-  graph.compileSystemModule()
-  discard graph.processModule(m, llStreamOpen(scriptName, fmRead))
+  var vm = setupVM(m, cache, scriptName.string, graph, idgen)
+  graph.vm = vm
+
+  graph.setPipeLinePass(EvalPass)
+  graph.compilePipelineSystemModule()
+  discard graph.processPipelineModule(m, vm.idgen, stream)
+
+  # watch out, "newruntime" can be set within NimScript itself and then we need
+  # to remember this:
+  if conf.selectedGC == gcUnselected:
+    conf.selectedGC = oldSelectedGC
+  if optOwnedRefs in oldGlobalOptions:
+    conf.globalOptions.incl {optTinyRtti, optOwnedRefs, optSeqDestructors}
+    defineSymbol(conf.symbols, "nimv2")
+  if conf.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
+    conf.globalOptions.incl {optTinyRtti, optSeqDestructors}
+    defineSymbol(conf.symbols, "nimv2")
+    defineSymbol(conf.symbols, "gcdestructors")
+    defineSymbol(conf.symbols, "nimSeqsV2")
+    case conf.selectedGC
+    of gcArc:
+      defineSymbol(conf.symbols, "gcarc")
+    of gcOrc:
+      defineSymbol(conf.symbols, "gcorc")
+    of gcAtomicArc:
+      defineSymbol(conf.symbols, "gcatomicarc")
+    else:
+      raiseAssert "unreachable"
 
   # ensure we load 'system.nim' again for the real non-config stuff!
   resetSystemArtifacts(graph)
@@ -177,3 +251,4 @@ proc runNimScript*(cache: IdentCache; scriptName: string;
   #initDefines()
   undefSymbol(conf.symbols, "nimscript")
   undefSymbol(conf.symbols, "nimconfig")
+  conf.symbolFiles = oldSymbolFiles