diff options
Diffstat (limited to 'compiler/scriptconfig.nim')
-rw-r--r-- | compiler/scriptconfig.nim | 211 |
1 files changed, 147 insertions, 64 deletions
diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index 0c31eadbe..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 + 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,11 +32,12 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) = setResult(a, result) proc setupVM*(module: PSym; cache: IdentCache; scriptName: string; - config: ConfigRef = nil): PEvalContext = + graph: ModuleGraph; idgen: IdGenerator): PEvalContext = # For Nimble we need to export 'setupVM'. - result = newCtx(module, cache) + result = newCtx(module, cache, graph, idgen) result.mode = emRepl registerAdditionalOps(result) + let conf = graph.config # captured vars: var errorMsg: string @@ -41,62 +48,104 @@ 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: + 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: + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + os.copyDir(getString(a, 0), getString(a, 1)) cbos getLastModificationTime: - setResult(a, toSeconds(getLastModificationTime(getString(a, 0)))) + 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)) + setResult(a, os.getEnv(a.getString 0, a.getString 1)) cbconf existsEnv: 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: - options.setConfigVar(getString(a, 0), getString(a, 1)) + options.setConfigVar(conf, getString(a, 0), getString(a, 1)) cbconf get: - setResult(a, options.getConfigVar(a.getString 0)) + setResult(a, options.getConfigVar(conf, a.getString 0)) cbconf exists: - setResult(a, options.existsConfigVar(a.getString 0)) + setResult(a, options.existsConfigVar(conf, a.getString 0)) cbconf nimcacheDir: - setResult(a, options.getNimcacheDir()) + setResult(a, options.getNimcacheDir(conf).string) cbconf paramStr: setResult(a, os.paramStr(int a.getInt 0)) cbconf paramCount: @@ -106,66 +155,100 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string; cbconf cmpIgnoreCase: setResult(a, strutils.cmpIgnoreCase(a.getString 0, a.getString 1)) cbconf setCommand: - options.command = a.getString 0 + conf.setCommandEarly(a.getString 0) let arg = a.getString 1 - if arg.len > 0: - gProjectName = arg - let path = - if gProjectName.isAbsolute: gProjectName - else: gProjectPath / gProjectName - try: - gProjectFull = canonicalizePath(path) - except OSError: - gProjectFull = path + incl(conf.globalOptions, optWasNimscript) + if arg.len > 0: setFromProjectName(conf, arg) cbconf getCommand: - setResult(a, options.command) + setResult(a, conf.command) cbconf switch: - processSwitch(a.getString 0, a.getString 1, passPP, module.info) + conf.currentConfigDir = vthisDir + processSwitch(a.getString 0, a.getString 1, passPP, module.info, conf) cbconf hintImpl: processSpecificNote(a.getString 0, wHint, passPP, module.info, - a.getString 1) + a.getString 1, conf) cbconf warningImpl: processSpecificNote(a.getString 0, wWarning, passPP, module.info, - a.getString 1) + a.getString 1, conf) cbconf patchFile: let key = a.getString(0) & "_" & a.getString(1) var val = a.getString(2).addFileExt(NimExt) if {'$', '~'} in val: - val = pathSubs(val, vthisDir) + val = pathSubs(conf, val, vthisDir) elif not isAbsolute(val): val = vthisDir / val - gModuleOverrides[key] = val + conf.moduleOverrides[key] = val cbconf selfExe: setResult(a, os.getAppFilename()) cbconf cppDefine: - if config != nil: - options.cppDefine(config, a.getString(0)) - -proc runNimScript*(cache: IdentCache; scriptName: string; - freshDefines=true; config: ConfigRef=nil) = - passes.gIncludeFile = includeModule - passes.gImportModule = importModule - let graph = newModuleGraph(config) - if freshDefines: initDefines() - - defineSymbol("nimscript") - defineSymbol("nimconfig") - registerPass(semPass) - registerPass(evalPass) - - searchPaths.add(options.libpath) + options.cppDefine(conf, a.getString(0)) + 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) + connectPipelineCallbacks(graph) + if freshDefines: initDefines(conf.symbols) + + defineSymbol(conf.symbols, "nimscript") + defineSymbol(conf.symbols, "nimconfig") + + 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) - vm.globalCtx = setupVM(m, cache, scriptName, config) - - graph.compileSystemModule(cache) - discard graph.processModule(m, llStreamOpen(scriptName, fmRead), nil, cache) + 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() - vm.globalCtx = nil + resetSystemArtifacts(graph) # do not remove the defined symbols #initDefines() - undefSymbol("nimscript") - undefSymbol("nimconfig") + undefSymbol(conf.symbols, "nimscript") + undefSymbol(conf.symbols, "nimconfig") + conf.symbolFiles = oldSymbolFiles |