cmdline: improve command processing (#16056)
This commit is contained in:
parent
9f1c5f64c5
commit
52829fc8d1
18 changed files with 144 additions and 137 deletions
|
|
@ -765,7 +765,7 @@ type
|
||||||
locOther # location is something other
|
locOther # location is something other
|
||||||
TLocFlag* = enum
|
TLocFlag* = enum
|
||||||
lfIndirect, # backend introduced a pointer
|
lfIndirect, # backend introduced a pointer
|
||||||
lfFullExternalName, # only used when 'conf.cmd == cmdPretty': Indicates
|
lfFullExternalName, # only used when 'conf.cmd == cmdNimfix': Indicates
|
||||||
# that the symbol has been imported via 'importc: "fullname"' and
|
# that the symbol has been imported via 'importc: "fullname"' and
|
||||||
# no format string.
|
# no format string.
|
||||||
lfNoDeepCopy, # no need for a deep copy
|
lfNoDeepCopy, # no need for a deep copy
|
||||||
|
|
|
||||||
|
|
@ -1986,7 +1986,7 @@ proc writeModule(m: BModule, pending: bool) =
|
||||||
var code = genModule(m, cf)
|
var code = genModule(m, cf)
|
||||||
if code != nil or m.config.symbolFiles != disabledSf:
|
if code != nil or m.config.symbolFiles != disabledSf:
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
if m.config.cmd == cmdRun:
|
if m.config.cmd == cmdTcc:
|
||||||
tccgen.compileCCode($code, m.config)
|
tccgen.compileCCode($code, m.config)
|
||||||
onExit()
|
onExit()
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ import
|
||||||
options, idents, nimconf, extccomp, commands, msgs,
|
options, idents, nimconf, extccomp, commands, msgs,
|
||||||
lineinfos, modulegraphs, condsyms, os, pathutils, parseopt
|
lineinfos, modulegraphs, condsyms, os, pathutils, parseopt
|
||||||
|
|
||||||
from strutils import normalize
|
|
||||||
|
|
||||||
proc prependCurDir*(f: AbsoluteFile): AbsoluteFile =
|
proc prependCurDir*(f: AbsoluteFile): AbsoluteFile =
|
||||||
when defined(unix):
|
when defined(unix):
|
||||||
if os.isAbsolute(f.string): result = f
|
if os.isAbsolute(f.string): result = f
|
||||||
|
|
@ -60,8 +58,8 @@ proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
|
||||||
proc loadConfigsAndProcessCmdLine*(self: NimProg, cache: IdentCache; conf: ConfigRef;
|
proc loadConfigsAndProcessCmdLine*(self: NimProg, cache: IdentCache; conf: ConfigRef;
|
||||||
graph: ModuleGraph): bool =
|
graph: ModuleGraph): bool =
|
||||||
if self.suggestMode:
|
if self.suggestMode:
|
||||||
conf.command = "nimsuggest"
|
conf.setCmd cmdIdeTools
|
||||||
if conf.command == "e":
|
if conf.cmd == cmdNimscript:
|
||||||
incl(conf.globalOptions, optWasNimscript)
|
incl(conf.globalOptions, optWasNimscript)
|
||||||
loadConfigs(DefaultConfig, cache, conf, graph.idgen) # load all config files
|
loadConfigs(DefaultConfig, cache, conf, graph.idgen) # load all config files
|
||||||
|
|
||||||
|
|
@ -69,17 +67,13 @@ proc loadConfigsAndProcessCmdLine*(self: NimProg, cache: IdentCache; conf: Confi
|
||||||
let scriptFile = conf.projectFull.changeFileExt("nims")
|
let scriptFile = conf.projectFull.changeFileExt("nims")
|
||||||
# 'nim foo.nims' means to just run the NimScript file and do nothing more:
|
# 'nim foo.nims' means to just run the NimScript file and do nothing more:
|
||||||
if fileExists(scriptFile) and scriptFile == conf.projectFull:
|
if fileExists(scriptFile) and scriptFile == conf.projectFull:
|
||||||
if conf.command == "":
|
if conf.cmd == cmdNone: conf.setCmd cmdNimscript
|
||||||
conf.command = "e"
|
if conf.cmd == cmdNimscript: return false
|
||||||
return false
|
|
||||||
elif conf.command.normalize == "e":
|
|
||||||
return false
|
|
||||||
|
|
||||||
# now process command line arguments again, because some options in the
|
# now process command line arguments again, because some options in the
|
||||||
# command line can overwrite the config file's settings
|
# command line can overwrite the config file's settings
|
||||||
extccomp.initVars(conf)
|
extccomp.initVars(conf)
|
||||||
self.processCmdLine(passCmd2, "", conf)
|
self.processCmdLine(passCmd2, "", conf)
|
||||||
if conf.command == "":
|
if conf.cmd == cmdNone:
|
||||||
rawMessage(conf, errGenerated, "command missing")
|
rawMessage(conf, errGenerated, "command missing")
|
||||||
|
|
||||||
graph.suggestMode = self.suggestMode
|
graph.suggestMode = self.suggestMode
|
||||||
|
|
|
||||||
|
|
@ -398,6 +398,48 @@ proc handleCmdInput*(conf: ConfigRef) =
|
||||||
conf.projectName = "cmdfile"
|
conf.projectName = "cmdfile"
|
||||||
handleStdinOrCmdInput()
|
handleStdinOrCmdInput()
|
||||||
|
|
||||||
|
proc parseCommand*(command: string): Command =
|
||||||
|
case command.normalize
|
||||||
|
of "c", "cc", "compile", "compiletoc": cmdCompileToC
|
||||||
|
of "cpp", "compiletocpp": cmdCompileToCpp
|
||||||
|
of "objc", "compiletooc": cmdCompileToOC
|
||||||
|
of "js", "compiletojs": cmdCompileToJS
|
||||||
|
of "r": cmdCrun
|
||||||
|
of "run": cmdTcc
|
||||||
|
of "check": cmdCheck
|
||||||
|
of "e": cmdNimscript
|
||||||
|
of "doc0": cmdDoc0
|
||||||
|
of "doc2", "doc": cmdDoc2
|
||||||
|
of "rst2html": cmdRst2html
|
||||||
|
of "rst2tex": cmdRst2tex
|
||||||
|
of "jsondoc0": cmdJsondoc0
|
||||||
|
of "jsondoc2", "jsondoc": cmdJsondoc
|
||||||
|
of "ctags": cmdCtags
|
||||||
|
of "buildindex": cmdBuildindex
|
||||||
|
of "gendepend": cmdGendepend
|
||||||
|
of "dump": cmdDump
|
||||||
|
of "parse": cmdParse
|
||||||
|
of "scan": cmdScan
|
||||||
|
of "secret": cmdInteractive
|
||||||
|
of "nop", "help": cmdNop
|
||||||
|
of "jsonscript": cmdJsonscript
|
||||||
|
else: cmdUnknown
|
||||||
|
|
||||||
|
proc setCmd*(conf: ConfigRef, cmd: Command) =
|
||||||
|
## sets cmd, backend so subsequent flags can query it (e.g. so --gc:arc can be ignored for backendJs)
|
||||||
|
# Note that `--backend` can override the backend, so the logic here must remain reversible.
|
||||||
|
conf.cmd = cmd
|
||||||
|
case cmd
|
||||||
|
of cmdCompileToC, cmdCrun, cmdTcc: conf.backend = backendC
|
||||||
|
of cmdCompileToCpp: conf.backend = backendCpp
|
||||||
|
of cmdCompileToOC: conf.backend = backendObjc
|
||||||
|
of cmdCompileToJS: conf.backend = backendJs
|
||||||
|
else: discard
|
||||||
|
|
||||||
|
proc setCommandEarly*(conf: ConfigRef, command: string) =
|
||||||
|
conf.command = command
|
||||||
|
setCmd(conf, command.parseCommand)
|
||||||
|
|
||||||
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
conf: ConfigRef) =
|
conf: ConfigRef) =
|
||||||
var
|
var
|
||||||
|
|
@ -407,8 +449,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
expectArg(conf, switch, arg, pass, info)
|
expectArg(conf, switch, arg, pass, info)
|
||||||
conf.projectIsCmd = true
|
conf.projectIsCmd = true
|
||||||
conf.cmdInput = arg # can be empty (a nim file with empty content is valid too)
|
conf.cmdInput = arg # can be empty (a nim file with empty content is valid too)
|
||||||
if conf.command == "":
|
if conf.cmd == cmdNone:
|
||||||
conf.command = "e" # better than "r" as a default
|
conf.setCmd cmdNimscript # better than `cmdCrun` as a default
|
||||||
conf.implicitCmd = true
|
conf.implicitCmd = true
|
||||||
of "path", "p":
|
of "path", "p":
|
||||||
expectArg(conf, switch, arg, pass, info)
|
expectArg(conf, switch, arg, pass, info)
|
||||||
|
|
@ -499,11 +541,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
of "project":
|
of "project":
|
||||||
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
|
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
|
||||||
of "gc":
|
of "gc":
|
||||||
if conf.backend == backendJs or conf.command == "js":
|
if conf.backend == backendJs: return # for: bug #16033
|
||||||
# for: bug #16033
|
|
||||||
# This might still be imperfect, in rarse corner cases
|
|
||||||
# (where command is reset in nimscript, maybe).
|
|
||||||
return
|
|
||||||
expectArg(conf, switch, arg, pass, info)
|
expectArg(conf, switch, arg, pass, info)
|
||||||
if pass in {passCmd2, passPP}:
|
if pass in {passCmd2, passPP}:
|
||||||
case arg.normalize
|
case arg.normalize
|
||||||
|
|
@ -955,13 +993,12 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
||||||
if argsCount == 0:
|
if argsCount == 0:
|
||||||
# nim filename.nims is the same as "nim e filename.nims":
|
# nim filename.nims is the same as "nim e filename.nims":
|
||||||
if p.key.endsWith(".nims"):
|
if p.key.endsWith(".nims"):
|
||||||
config.command = "e"
|
config.setCmd cmdNimscript
|
||||||
incl(config.globalOptions, optWasNimscript)
|
incl(config.globalOptions, optWasNimscript)
|
||||||
config.projectName = unixToNativePath(p.key)
|
config.projectName = unixToNativePath(p.key)
|
||||||
config.arguments = cmdLineRest(p)
|
config.arguments = cmdLineRest(p)
|
||||||
result = true
|
result = true
|
||||||
elif pass != passCmd2:
|
elif pass != passCmd2: setCommandEarly(config, p.key)
|
||||||
config.command = p.key
|
|
||||||
else:
|
else:
|
||||||
if pass == passCmd1: config.commandArgs.add p.key
|
if pass == passCmd1: config.commandArgs.add p.key
|
||||||
if argsCount == 1:
|
if argsCount == 1:
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ proc skipAlias*(s: PSym; n: PNode; conf: ConfigRef): PSym =
|
||||||
result = s
|
result = s
|
||||||
else:
|
else:
|
||||||
result = s.owner
|
result = s.owner
|
||||||
if conf.cmd == cmdPretty:
|
if conf.cmd == cmdNimfix:
|
||||||
prettybase.replaceDeprecated(conf, n.info, s, result)
|
prettybase.replaceDeprecated(conf, n.info, s, result)
|
||||||
else:
|
else:
|
||||||
message(conf, n.info, warnDeprecated, "use " & result.name.s & " instead; " &
|
message(conf, n.info, warnDeprecated, "use " & result.name.s & " instead; " &
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ proc commandCompileToC(graph: ModuleGraph) =
|
||||||
if graph.config.errorCounter > 0:
|
if graph.config.errorCounter > 0:
|
||||||
return # issue #9933
|
return # issue #9933
|
||||||
cgenWriteModules(graph.backend, conf)
|
cgenWriteModules(graph.backend, conf)
|
||||||
if conf.cmd != cmdRun:
|
if conf.cmd != cmdTcc:
|
||||||
extccomp.callCCompiler(conf)
|
extccomp.callCCompiler(conf)
|
||||||
# for now we do not support writing out a .json file with the build instructions when HCR is on
|
# for now we do not support writing out a .json file with the build instructions when HCR is on
|
||||||
if not conf.hcrOn:
|
if not conf.hcrOn:
|
||||||
|
|
@ -195,12 +195,8 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||||
if conf.selectedGC in {gcArc, gcOrc} and conf.backend != backendCpp:
|
if conf.selectedGC in {gcArc, gcOrc} and conf.backend != backendCpp:
|
||||||
conf.exc = excGoto
|
conf.exc = excGoto
|
||||||
|
|
||||||
var commandAlreadyProcessed = false
|
proc compileToBackend() =
|
||||||
|
customizeForBackend(conf.backend)
|
||||||
proc compileToBackend(backend: TBackend, cmd = cmdCompileToBackend) =
|
|
||||||
commandAlreadyProcessed = true
|
|
||||||
conf.cmd = cmd
|
|
||||||
customizeForBackend(backend)
|
|
||||||
case conf.backend
|
case conf.backend
|
||||||
of backendC: commandCompileToC(graph)
|
of backendC: commandCompileToC(graph)
|
||||||
of backendCpp: commandCompileToC(graph)
|
of backendCpp: commandCompileToC(graph)
|
||||||
|
|
@ -213,18 +209,13 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||||
quit "compiler wasn't built with documentation generator"
|
quit "compiler wasn't built with documentation generator"
|
||||||
else:
|
else:
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
conf.cmd = cmdDoc
|
|
||||||
loadConfigs(DocConfig, cache, conf, graph.idgen)
|
loadConfigs(DocConfig, cache, conf, graph.idgen)
|
||||||
defineSymbol(conf.symbols, "nimdoc")
|
defineSymbol(conf.symbols, "nimdoc")
|
||||||
body
|
body
|
||||||
|
|
||||||
block: ## command prepass
|
block: ## command prepass
|
||||||
var docLikeCmd2 = false # includes what calls `docLikeCmd` + some more
|
if conf.cmd == cmdCrun: conf.globalOptions.incl {optRun, optUseNimcache}
|
||||||
case conf.command.normalize
|
if conf.cmd notin cmdBackends + {cmdTcc}: customizeForBackend(backendC)
|
||||||
of "r": conf.globalOptions.incl {optRun, optUseNimcache}
|
|
||||||
of "doc0", "doc2", "doc", "rst2html", "rst2tex", "jsondoc0", "jsondoc2",
|
|
||||||
"jsondoc", "ctags", "buildindex": docLikeCmd2 = true
|
|
||||||
else: discard
|
|
||||||
if conf.outDir.isEmpty:
|
if conf.outDir.isEmpty:
|
||||||
# doc like commands can generate a lot of files (especially with --project)
|
# doc like commands can generate a lot of files (especially with --project)
|
||||||
# so by default should not end up in $PWD nor in $projectPath.
|
# so by default should not end up in $PWD nor in $projectPath.
|
||||||
|
|
@ -232,30 +223,22 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||||
var ret = if optUseNimcache in conf.globalOptions: getNimcacheDir(conf)
|
var ret = if optUseNimcache in conf.globalOptions: getNimcacheDir(conf)
|
||||||
else: conf.projectPath
|
else: conf.projectPath
|
||||||
doAssert ret.string.isAbsolute # `AbsoluteDir` is not a real guarantee
|
doAssert ret.string.isAbsolute # `AbsoluteDir` is not a real guarantee
|
||||||
if docLikeCmd2: ret = ret / htmldocsDir
|
if conf.cmd in cmdDocLike + {cmdRst2html, cmdRst2tex}: ret = ret / htmldocsDir
|
||||||
ret
|
ret
|
||||||
|
|
||||||
## process all backend commands
|
## process all commands
|
||||||
case conf.command.normalize
|
case conf.cmd
|
||||||
of "c", "cc", "compile", "compiletoc": compileToBackend(backendC) # compile means compileToC currently
|
of cmdBackends: compileToBackend()
|
||||||
of "cpp", "compiletocpp": compileToBackend(backendCpp)
|
of cmdTcc:
|
||||||
of "objc", "compiletooc": compileToBackend(backendObjc)
|
|
||||||
of "js", "compiletojs": compileToBackend(backendJs)
|
|
||||||
of "r": compileToBackend(backendC) # different from `"run"`!
|
|
||||||
of "run":
|
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
extccomp.setCC(conf, "tcc", unknownLineInfo)
|
extccomp.setCC(conf, "tcc", unknownLineInfo)
|
||||||
if conf.backend notin {backendC, backendInvalid}:
|
if conf.backend != backendC:
|
||||||
rawMessage(conf, errGenerated, "'run' requires c backend, got: '$1'" % $conf.backend)
|
rawMessage(conf, errGenerated, "'run' requires c backend, got: '$1'" % $conf.backend)
|
||||||
compileToBackend(backendC, cmd = cmdRun)
|
compileToBackend()
|
||||||
else:
|
else:
|
||||||
rawMessage(conf, errGenerated, "'run' command not available; rebuild with -d:tinyc")
|
rawMessage(conf, errGenerated, "'run' command not available; rebuild with -d:tinyc")
|
||||||
else: customizeForBackend(backendC) # fallback for other commands
|
of cmdDoc0: docLikeCmd commandDoc(cache, conf)
|
||||||
|
of cmdDoc2:
|
||||||
## process all other commands
|
|
||||||
case conf.command.normalize # synchronize with `cmdUsingHtmlDocs`
|
|
||||||
of "doc0": docLikeCmd commandDoc(cache, conf)
|
|
||||||
of "doc2", "doc":
|
|
||||||
docLikeCmd():
|
docLikeCmd():
|
||||||
conf.setNoteDefaults(warnLockLevel, false) # issue #13218
|
conf.setNoteDefaults(warnLockLevel, false) # issue #13218
|
||||||
conf.setNoteDefaults(warnRedefinitionOfLabel, false) # issue #13218
|
conf.setNoteDefaults(warnRedefinitionOfLabel, false) # issue #13218
|
||||||
|
|
@ -266,30 +249,25 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||||
commandDoc2(graph, false)
|
commandDoc2(graph, false)
|
||||||
if optGenIndex in conf.globalOptions and optWholeProject in conf.globalOptions:
|
if optGenIndex in conf.globalOptions and optWholeProject in conf.globalOptions:
|
||||||
commandBuildIndex(conf, $conf.outDir)
|
commandBuildIndex(conf, $conf.outDir)
|
||||||
of "rst2html":
|
of cmdRst2html:
|
||||||
conf.setNoteDefaults(warnRedefinitionOfLabel, false) # similar to issue #13218
|
conf.setNoteDefaults(warnRedefinitionOfLabel, false) # similar to issue #13218
|
||||||
when defined(leanCompiler):
|
when defined(leanCompiler):
|
||||||
quit "compiler wasn't built with documentation generator"
|
quit "compiler wasn't built with documentation generator"
|
||||||
else:
|
else:
|
||||||
conf.cmd = cmdRst2html
|
|
||||||
loadConfigs(DocConfig, cache, conf, graph.idgen)
|
loadConfigs(DocConfig, cache, conf, graph.idgen)
|
||||||
commandRst2Html(cache, conf)
|
commandRst2Html(cache, conf)
|
||||||
of "rst2tex":
|
of cmdRst2tex:
|
||||||
when defined(leanCompiler):
|
when defined(leanCompiler):
|
||||||
quit "compiler wasn't built with documentation generator"
|
quit "compiler wasn't built with documentation generator"
|
||||||
else:
|
else:
|
||||||
conf.cmd = cmdRst2tex
|
|
||||||
loadConfigs(DocTexConfig, cache, conf, graph.idgen)
|
loadConfigs(DocTexConfig, cache, conf, graph.idgen)
|
||||||
commandRst2TeX(cache, conf)
|
commandRst2TeX(cache, conf)
|
||||||
of "jsondoc0": docLikeCmd commandJson(cache, conf)
|
of cmdJsondoc0: docLikeCmd commandJson(cache, conf)
|
||||||
of "jsondoc2", "jsondoc": docLikeCmd commandDoc2(graph, true)
|
of cmdJsondoc: docLikeCmd commandDoc2(graph, true)
|
||||||
of "ctags": docLikeCmd commandTags(cache, conf)
|
of cmdCtags: docLikeCmd commandTags(cache, conf)
|
||||||
of "buildindex": docLikeCmd commandBuildIndex(conf, $conf.projectFull, conf.outFile)
|
of cmdBuildindex: docLikeCmd commandBuildIndex(conf, $conf.projectFull, conf.outFile)
|
||||||
of "gendepend":
|
of cmdGendepend: commandGenDepend(graph)
|
||||||
conf.cmd = cmdGenDepend
|
of cmdDump:
|
||||||
commandGenDepend(graph)
|
|
||||||
of "dump":
|
|
||||||
conf.cmd = cmdDump
|
|
||||||
if getConfigVar(conf, "dump.format") == "json":
|
if getConfigVar(conf, "dump.format") == "json":
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
|
|
||||||
|
|
@ -332,41 +310,30 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||||
msgWriteln(conf, "-- end of list --", {msgStdout, msgSkipHook})
|
msgWriteln(conf, "-- end of list --", {msgStdout, msgSkipHook})
|
||||||
|
|
||||||
for it in conf.searchPaths: msgWriteln(conf, it.string)
|
for it in conf.searchPaths: msgWriteln(conf, it.string)
|
||||||
of "check":
|
of cmdCheck: commandCheck(graph)
|
||||||
conf.cmd = cmdCheck
|
of cmdParse:
|
||||||
commandCheck(graph)
|
|
||||||
of "parse":
|
|
||||||
conf.cmd = cmdParse
|
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
discard parseFile(conf.projectMainIdx, cache, conf)
|
discard parseFile(conf.projectMainIdx, cache, conf)
|
||||||
of "scan":
|
of cmdScan:
|
||||||
conf.cmd = cmdScan
|
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
commandScan(cache, conf)
|
commandScan(cache, conf)
|
||||||
msgWriteln(conf, "Beware: Indentation tokens depend on the parser's state!")
|
msgWriteln(conf, "Beware: Indentation tokens depend on the parser's state!")
|
||||||
of "secret":
|
of cmdInteractive: commandInteractive(graph)
|
||||||
conf.cmd = cmdInteractive
|
of cmdNimscript:
|
||||||
commandInteractive(graph)
|
|
||||||
of "e":
|
|
||||||
if conf.projectIsCmd or conf.projectIsStdin: discard
|
if conf.projectIsCmd or conf.projectIsStdin: discard
|
||||||
elif not fileExists(conf.projectFull):
|
elif not fileExists(conf.projectFull):
|
||||||
rawMessage(conf, errGenerated, "NimScript file does not exist: " & conf.projectFull.string)
|
rawMessage(conf, errGenerated, "NimScript file does not exist: " & conf.projectFull.string)
|
||||||
elif not conf.projectFull.string.endsWith(".nims"):
|
elif not conf.projectFull.string.endsWith(".nims"):
|
||||||
rawMessage(conf, errGenerated, "not a NimScript file: " & conf.projectFull.string)
|
rawMessage(conf, errGenerated, "not a NimScript file: " & conf.projectFull.string)
|
||||||
# main NimScript logic handled in `loadConfigs`.
|
# main NimScript logic handled in `loadConfigs`.
|
||||||
of "nop", "help":
|
of cmdNop: discard
|
||||||
# prevent the "success" message:
|
of cmdJsonscript:
|
||||||
conf.cmd = cmdDump
|
|
||||||
of "jsonscript":
|
|
||||||
conf.cmd = cmdJsonScript
|
|
||||||
setOutFile(graph.config)
|
setOutFile(graph.config)
|
||||||
commandJsonScript(graph)
|
commandJsonScript(graph)
|
||||||
elif commandAlreadyProcessed: discard # already handled
|
of cmdUnknown, cmdNone, cmdIdeTools, cmdNimfix:
|
||||||
else:
|
|
||||||
rawMessage(conf, errGenerated, "invalid command: " & conf.command)
|
rawMessage(conf, errGenerated, "invalid command: " & conf.command)
|
||||||
|
|
||||||
if conf.errorCounter == 0 and
|
if conf.errorCounter == 0 and conf.cmd notin {cmdTcc, cmdDump, cmdNop}:
|
||||||
conf.cmd notin {cmdInterpret, cmdRun, cmdDump}:
|
|
||||||
let mem =
|
let mem =
|
||||||
when declared(system.getMaxMem): formatSize(getMaxMem()) & " peakmem"
|
when declared(system.getMaxMem): formatSize(getMaxMem()) & " peakmem"
|
||||||
else: formatSize(getTotalMem()) & " totmem"
|
else: formatSize(getTotalMem()) & " totmem"
|
||||||
|
|
@ -378,9 +345,9 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||||
let project = if optListFullPaths in conf.globalOptions: $conf.projectFull else: $conf.projectName
|
let project = if optListFullPaths in conf.globalOptions: $conf.projectFull else: $conf.projectName
|
||||||
|
|
||||||
var output: string
|
var output: string
|
||||||
if optCompileOnly in conf.globalOptions and conf.cmd != cmdJsonScript:
|
if optCompileOnly in conf.globalOptions and conf.cmd != cmdJsonscript:
|
||||||
output = $conf.jsonBuildFile
|
output = $conf.jsonBuildFile
|
||||||
elif conf.outFile.isEmpty and conf.cmd notin {cmdJsonScript, cmdCompileToBackend, cmdDoc}:
|
elif conf.outFile.isEmpty and conf.cmd notin {cmdJsonscript} + cmdDocLike + cmdBackends:
|
||||||
# for some cmd we expect a valid absOutFile
|
# for some cmd we expect a valid absOutFile
|
||||||
output = "unknownOutput"
|
output = "unknownOutput"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||||
if processArgument(pass, p, argsCount, config): break
|
if processArgument(pass, p, argsCount, config): break
|
||||||
if pass == passCmd2:
|
if pass == passCmd2:
|
||||||
if {optRun, optWasNimscript} * config.globalOptions == {} and
|
if {optRun, optWasNimscript} * config.globalOptions == {} and
|
||||||
config.arguments.len > 0 and config.command.normalize notin ["run", "e", "r"]:
|
config.arguments.len > 0 and config.cmd notin {cmdTcc, cmdNimscript, cmdCrun}:
|
||||||
rawMessage(config, errGenerated, errArgsNeedRunOption)
|
rawMessage(config, errGenerated, errArgsNeedRunOption)
|
||||||
|
|
||||||
proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
||||||
|
|
@ -86,19 +86,19 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
||||||
#echo(GC_getStatistics())
|
#echo(GC_getStatistics())
|
||||||
if conf.errorCounter != 0: return
|
if conf.errorCounter != 0: return
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
if conf.cmd == cmdRun:
|
if conf.cmd == cmdTcc:
|
||||||
tccgen.run(conf, conf.arguments)
|
tccgen.run(conf, conf.arguments)
|
||||||
if optRun in conf.globalOptions:
|
if optRun in conf.globalOptions:
|
||||||
let output = conf.absOutFile
|
let output = conf.absOutFile
|
||||||
case conf.cmd
|
case conf.cmd
|
||||||
of cmdCompileToBackend:
|
of cmdBackends, cmdTcc:
|
||||||
var cmdPrefix = ""
|
var cmdPrefix = ""
|
||||||
case conf.backend
|
case conf.backend
|
||||||
of backendC, backendCpp, backendObjc: discard
|
of backendC, backendCpp, backendObjc: discard
|
||||||
of backendJs: cmdPrefix = findNodeJs() & " "
|
of backendJs: cmdPrefix = findNodeJs() & " "
|
||||||
else: doAssert false, $conf.backend
|
else: doAssert false, $conf.backend
|
||||||
execExternalProgram(conf, cmdPrefix & output.quoteShell & ' ' & conf.arguments)
|
execExternalProgram(conf, cmdPrefix & output.quoteShell & ' ' & conf.arguments)
|
||||||
of cmdDoc, cmdRst2html:
|
of cmdDocLike, cmdRst2html, cmdRst2tex: # bugfix(cmdRst2tex was missing)
|
||||||
if conf.arguments.len > 0:
|
if conf.arguments.len > 0:
|
||||||
# reserved for future use
|
# reserved for future use
|
||||||
rawMessage(conf, errGenerated, "'$1 cannot handle arguments" % [$conf.cmd])
|
rawMessage(conf, errGenerated, "'$1 cannot handle arguments" % [$conf.cmd])
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef; idgen:
|
||||||
if scriptIsProj:
|
if scriptIsProj:
|
||||||
showHintConf()
|
showHintConf()
|
||||||
configFiles.setLen 0
|
configFiles.setLen 0
|
||||||
if conf.command != "nimsuggest":
|
if conf.cmd != cmdIdeTools:
|
||||||
runNimScriptIfExists(scriptFile, isMain = true)
|
runNimScriptIfExists(scriptFile, isMain = true)
|
||||||
else:
|
else:
|
||||||
if not scriptIsProj:
|
if not scriptIsProj:
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## exposes the Nim VM to clients.
|
## exposes the Nim VM to clients.
|
||||||
import
|
import
|
||||||
ast, astalgo, modules, passes, condsyms,
|
ast, astalgo, modules, passes, condsyms,
|
||||||
options, sem, semdata, llstream, lineinfos, vm,
|
options, sem, llstream, lineinfos, vm,
|
||||||
vmdef, modulegraphs, idents, os, pathutils,
|
vmdef, modulegraphs, idents, os, pathutils,
|
||||||
passaux, scriptconfig
|
passaux, scriptconfig
|
||||||
|
|
||||||
|
|
@ -153,7 +153,7 @@ proc runRepl*(r: TLLRepl;
|
||||||
conf.searchPaths.add(AbsoluteDir p)
|
conf.searchPaths.add(AbsoluteDir p)
|
||||||
if conf.libpath.isEmpty: conf.libpath = AbsoluteDir p
|
if conf.libpath.isEmpty: conf.libpath = AbsoluteDir p
|
||||||
|
|
||||||
conf.cmd = cmdInteractive
|
conf.cmd = cmdInteractive # see also `setCmd`
|
||||||
conf.setErrorMaxHighMaybe
|
conf.setErrorMaxHighMaybe
|
||||||
initDefines(conf.symbols)
|
initDefines(conf.symbols)
|
||||||
defineSymbol(conf.symbols, "nimscript")
|
defineSymbol(conf.symbols, "nimscript")
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ In addition, all command line options of Nim are supported.
|
||||||
proc mainCommand =
|
proc mainCommand =
|
||||||
registerPass verbosePass
|
registerPass verbosePass
|
||||||
registerPass semPass
|
registerPass semPass
|
||||||
conf.cmd = cmdPretty
|
conf.setCmd cmdNimfix
|
||||||
searchPaths.add options.libpath
|
searchPaths.add options.libpath
|
||||||
if gProjectFull.len != 0:
|
if gProjectFull.len != 0:
|
||||||
# current path is always looked first for modules
|
# current path is always looked first for modules
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ type # please make sure we have under 32 options
|
||||||
TOptions* = set[TOption]
|
TOptions* = set[TOption]
|
||||||
TGlobalOption* = enum # **keep binary compatible**
|
TGlobalOption* = enum # **keep binary compatible**
|
||||||
gloptNone, optForceFullMake,
|
gloptNone, optForceFullMake,
|
||||||
optWasNimscript,
|
optWasNimscript, # redundant with `cmdNimscript`, could be removed
|
||||||
optListCmd, optCompileOnly, optNoLinking,
|
optListCmd, optCompileOnly, optNoLinking,
|
||||||
optCDebug, # turn on debugging information
|
optCDebug, # turn on debugging information
|
||||||
optGenDynLib, # generate a dynamic library
|
optGenDynLib, # generate a dynamic library
|
||||||
|
|
@ -110,34 +110,44 @@ type
|
||||||
TBackend* = enum
|
TBackend* = enum
|
||||||
backendInvalid = "" # for parseEnum
|
backendInvalid = "" # for parseEnum
|
||||||
backendC = "c"
|
backendC = "c"
|
||||||
backendCpp = "cpp" # was cmdCompileToCpp
|
backendCpp = "cpp"
|
||||||
backendJs = "js" # was cmdCompileToJS
|
backendJs = "js"
|
||||||
backendObjc = "objc" # was cmdCompileToOC
|
backendObjc = "objc"
|
||||||
# backendNimscript = "nimscript" # this could actually work
|
# backendNimscript = "nimscript" # this could actually work
|
||||||
# backendLlvm = "llvm" # probably not well supported; was cmdCompileToLLVM
|
# backendLlvm = "llvm" # probably not well supported; was cmdCompileToLLVM
|
||||||
|
|
||||||
|
Command* = enum ## Nim's commands
|
||||||
|
cmdNone # not yet processed command
|
||||||
|
cmdUnknown # command unmapped
|
||||||
|
cmdCompileToC, cmdCompileToCpp, cmdCompileToOC, cmdCompileToJS
|
||||||
|
cmdCrun # compile and run in nimache
|
||||||
|
cmdTcc # run the project via TCC backend
|
||||||
|
cmdCheck # semantic checking for whole project
|
||||||
|
cmdParse # parse a single file (for debugging)
|
||||||
|
cmdScan # scan a single file (for debugging)
|
||||||
|
cmdIdeTools # ide tools (e.g. nimsuggest)
|
||||||
|
cmdNimscript # evaluate nimscript
|
||||||
|
cmdDoc0
|
||||||
|
cmdDoc2
|
||||||
|
cmdRst2html # convert a reStructuredText file to HTML
|
||||||
|
cmdRst2tex # convert a reStructuredText file to TeX
|
||||||
|
cmdJsondoc0
|
||||||
|
cmdJsondoc
|
||||||
|
cmdCtags
|
||||||
|
cmdBuildindex
|
||||||
|
cmdGendepend
|
||||||
|
cmdDump
|
||||||
|
cmdInteractive # start interactive session
|
||||||
|
cmdNop
|
||||||
|
cmdJsonscript # compile a .json build file
|
||||||
|
cmdNimfix
|
||||||
|
# old unused: cmdInterpret, cmdDef: def feature (find definition for IDEs)
|
||||||
|
|
||||||
|
const
|
||||||
|
cmdBackends* = {cmdCompileToC, cmdCompileToCpp, cmdCompileToOC, cmdCompileToJS, cmdCrun}
|
||||||
|
cmdDocLike* = {cmdDoc0, cmdDoc2, cmdJsondoc0, cmdJsondoc, cmdCtags, cmdBuildindex}
|
||||||
|
|
||||||
type
|
type
|
||||||
TCommands* = enum # Nim's commands
|
|
||||||
# **keep binary compatible**
|
|
||||||
cmdNone,
|
|
||||||
cmdCompileToC, # deadcode
|
|
||||||
cmdCompileToCpp, # deadcode
|
|
||||||
cmdCompileToOC, # deadcode
|
|
||||||
cmdCompileToJS, # deadcode
|
|
||||||
cmdCompileToLLVM, # deadcode
|
|
||||||
cmdInterpret, cmdPretty, cmdDoc,
|
|
||||||
cmdGenDepend, cmdDump,
|
|
||||||
cmdCheck, # semantic checking for whole project
|
|
||||||
cmdParse, # parse a single file (for debugging)
|
|
||||||
cmdScan, # scan a single file (for debugging)
|
|
||||||
cmdIdeTools, # ide tools
|
|
||||||
cmdDef, # def feature (find definition for IDEs)
|
|
||||||
cmdRst2html, # convert a reStructuredText file to HTML
|
|
||||||
cmdRst2tex, # convert a reStructuredText file to TeX
|
|
||||||
cmdInteractive, # start interactive session
|
|
||||||
cmdRun, # run the project via TCC backend
|
|
||||||
cmdJsonScript # compile a .json build file
|
|
||||||
cmdCompileToBackend, # compile to backend in TBackend
|
|
||||||
TStringSeq* = seq[string]
|
TStringSeq* = seq[string]
|
||||||
TGCMode* = enum # the selected GC
|
TGCMode* = enum # the selected GC
|
||||||
gcUnselected, gcNone, gcBoehm, gcRegions, gcArc, gcOrc,
|
gcUnselected, gcNone, gcBoehm, gcRegions, gcArc, gcOrc,
|
||||||
|
|
@ -245,7 +255,7 @@ type
|
||||||
evalTemplateCounter*: int
|
evalTemplateCounter*: int
|
||||||
evalMacroCounter*: int
|
evalMacroCounter*: int
|
||||||
exitcode*: int8
|
exitcode*: int8
|
||||||
cmd*: TCommands # the command
|
cmd*: Command # raw command parsed as enum
|
||||||
cmdInput*: string # input command
|
cmdInput*: string # input command
|
||||||
projectIsCmd*: bool # whether we're compiling from a command input
|
projectIsCmd*: bool # whether we're compiling from a command input
|
||||||
implicitCmd*: bool # whether some flag triggered an implicit `command`
|
implicitCmd*: bool # whether some flag triggered an implicit `command`
|
||||||
|
|
@ -531,7 +541,7 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
|
||||||
osDragonfly, osMacosx}
|
osDragonfly, osMacosx}
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc importantComments*(conf: ConfigRef): bool {.inline.} = conf.cmd in {cmdDoc, cmdIdeTools}
|
proc importantComments*(conf: ConfigRef): bool {.inline.} = conf.cmd notin cmdDocLike + {cmdIdeTools}
|
||||||
proc usesWriteBarrier*(conf: ConfigRef): bool {.inline.} = conf.selectedGC >= gcRefc
|
proc usesWriteBarrier*(conf: ConfigRef): bool {.inline.} = conf.selectedGC >= gcRefc
|
||||||
|
|
||||||
template compilationCachePresent*(conf: ConfigRef): untyped =
|
template compilationCachePresent*(conf: ConfigRef): untyped =
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ proc setExternName(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||||
localError(c.config, info, "invalid extern name: '" & extname & "'. (Forgot to escape '$'?)")
|
localError(c.config, info, "invalid extern name: '" & extname & "'. (Forgot to escape '$'?)")
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
s.cname = $s.loc.r
|
s.cname = $s.loc.r
|
||||||
if c.config.cmd == cmdPretty and '$' notin extname:
|
if c.config.cmd == cmdNimfix and '$' notin extname:
|
||||||
# note that '{.importc.}' is transformed into '{.importc: "$1".}'
|
# note that '{.importc.}' is transformed into '{.importc: "$1".}'
|
||||||
s.loc.flags.incl(lfFullExternalName)
|
s.loc.flags.incl(lfFullExternalName)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,8 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||||
cbconf cmpIgnoreCase:
|
cbconf cmpIgnoreCase:
|
||||||
setResult(a, strutils.cmpIgnoreCase(a.getString 0, a.getString 1))
|
setResult(a, strutils.cmpIgnoreCase(a.getString 0, a.getString 1))
|
||||||
cbconf setCommand:
|
cbconf setCommand:
|
||||||
conf.command = a.getString 0
|
conf.setCommandEarly(a.getString 0)
|
||||||
|
# xxx move remaining logic to commands.nim or other
|
||||||
let arg = a.getString 1
|
let arg = a.getString 1
|
||||||
incl(conf.globalOptions, optWasNimscript)
|
incl(conf.globalOptions, optWasNimscript)
|
||||||
if arg.len > 0:
|
if arg.len > 0:
|
||||||
|
|
|
||||||
|
|
@ -2280,7 +2280,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||||
result = magicsAfterOverloadResolution(c, result, flags)
|
result = magicsAfterOverloadResolution(c, result, flags)
|
||||||
of mRunnableExamples:
|
of mRunnableExamples:
|
||||||
markUsed(c, n.info, s)
|
markUsed(c, n.info, s)
|
||||||
if c.config.cmd == cmdDoc and n.len >= 2 and n.lastSon.kind == nkStmtList:
|
if c.config.cmd in cmdDocLike and n.len >= 2 and n.lastSon.kind == nkStmtList:
|
||||||
when false:
|
when false:
|
||||||
# some of this dead code was moved to `prepareExamples`
|
# some of this dead code was moved to `prepareExamples`
|
||||||
if sfMainModule in c.module.flags:
|
if sfMainModule in c.module.flags:
|
||||||
|
|
@ -2724,7 +2724,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
let mode = if nfDotField in n.flags: {} else: {checkUndeclared}
|
let mode = if nfDotField in n.flags: {} else: {checkUndeclared}
|
||||||
var s = qualifiedLookUp(c, n[0], mode)
|
var s = qualifiedLookUp(c, n[0], mode)
|
||||||
if s != nil:
|
if s != nil:
|
||||||
#if c.config.cmd == cmdPretty and n[0].kind == nkDotExpr:
|
#if c.config.cmd == cmdNimfix and n[0].kind == nkDotExpr:
|
||||||
# pretty.checkUse(n[0][1].info, s)
|
# pretty.checkUse(n[0][1].info, s)
|
||||||
case s.kind
|
case s.kind
|
||||||
of skMacro, skTemplate:
|
of skMacro, skTemplate:
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||||
e.position = int(counter)
|
e.position = int(counter)
|
||||||
let symNode = newSymNode(e)
|
let symNode = newSymNode(e)
|
||||||
if optNimV1Emulation notin c.config.globalOptions and identToReplace != nil and
|
if optNimV1Emulation notin c.config.globalOptions and identToReplace != nil and
|
||||||
c.config.cmd != cmdDoc: # A hack to produce documentation for enum fields.
|
c.config.cmd notin cmdDocLike: # A hack to produce documentation for enum fields.
|
||||||
identToReplace[] = symNode
|
identToReplace[] = symNode
|
||||||
if e.position == 0: hasNull = true
|
if e.position == 0: hasNull = true
|
||||||
if result.sym != nil and sfExported in result.sym.flags:
|
if result.sym != nil and sfExported in result.sym.flags:
|
||||||
|
|
|
||||||
|
|
@ -1223,9 +1223,7 @@ proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||||
var argsCount = 1
|
var argsCount = 1
|
||||||
|
|
||||||
config.commandLine.setLen 0
|
config.commandLine.setLen 0
|
||||||
config.command = "check"
|
config.setCmd cmdCheck
|
||||||
config.cmd = cmdCheck
|
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
parseopt.next(p)
|
parseopt.next(p)
|
||||||
case p.kind
|
case p.kind
|
||||||
|
|
@ -1253,7 +1251,7 @@ proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||||
if processArgument(pass, p, argsCount, config): break
|
if processArgument(pass, p, argsCount, config): break
|
||||||
if pass == passCmd2:
|
if pass == passCmd2:
|
||||||
if {optRun, optWasNimscript} * config.globalOptions == {} and
|
if {optRun, optWasNimscript} * config.globalOptions == {} and
|
||||||
config.arguments.len > 0 and config.command.normalize notin ["run", "e"]:
|
config.arguments.len > 0 and config.cmd notin {cmdTcc, cmdNimscript}:
|
||||||
rawMessage(config, errGenerated, errArgsNeedRunOption)
|
rawMessage(config, errGenerated, errArgsNeedRunOption)
|
||||||
|
|
||||||
proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
||||||
|
|
|
||||||
|
|
@ -517,7 +517,7 @@ proc mainCommand(graph: ModuleGraph) =
|
||||||
clearPasses(graph)
|
clearPasses(graph)
|
||||||
registerPass graph, verbosePass
|
registerPass graph, verbosePass
|
||||||
registerPass graph, semPass
|
registerPass graph, semPass
|
||||||
conf.cmd = cmdIdeTools
|
conf.setCmd cmdIdeTools
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
|
|
||||||
if not fileExists(conf.projectFull):
|
if not fileExists(conf.projectFull):
|
||||||
|
|
@ -666,7 +666,7 @@ else:
|
||||||
clearPasses(graph)
|
clearPasses(graph)
|
||||||
registerPass graph, verbosePass
|
registerPass graph, verbosePass
|
||||||
registerPass graph, semPass
|
registerPass graph, semPass
|
||||||
conf.cmd = cmdIdeTools
|
conf.setCmd cmdIdeTools
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
|
|
||||||
if not fileExists(conf.projectFull):
|
if not fileExists(conf.projectFull):
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ proc mainCommand(graph: ModuleGraph) =
|
||||||
clearPasses(graph)
|
clearPasses(graph)
|
||||||
registerPass graph, verbosePass
|
registerPass graph, verbosePass
|
||||||
registerPass graph, semPass
|
registerPass graph, semPass
|
||||||
conf.cmd = cmdIdeTools
|
conf.setCmd cmdIdeTools
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
setupDb(graph, dbfile)
|
setupDb(graph, dbfile)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue