refactoring: explict config state instead of globals
This commit is contained in:
parent
5565b9ef10
commit
f04d21f279
12 changed files with 110 additions and 79 deletions
|
|
@ -1221,7 +1221,7 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
injectG()
|
injectG()
|
||||||
result = newModule(g, module)
|
result = newModule(g, module)
|
||||||
if optGenIndex in gGlobalOptions and g.generatedHeader == nil:
|
if optGenIndex in gGlobalOptions and g.generatedHeader == nil:
|
||||||
let f = if headerFile.len > 0: headerFile else: gProjectFull
|
let f = if graph.config.headerFile.len > 0: graph.config.headerFile else: gProjectFull
|
||||||
g.generatedHeader = rawNewModule(g, module,
|
g.generatedHeader = rawNewModule(g, module,
|
||||||
changeFileExt(completeCFilePath(f), hExt))
|
changeFileExt(completeCFilePath(f), hExt))
|
||||||
incl g.generatedHeader.flags, isHeaderFile
|
incl g.generatedHeader.flags, isHeaderFile
|
||||||
|
|
@ -1373,11 +1373,12 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
|
for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
|
||||||
genMainProc(m)
|
genMainProc(m)
|
||||||
|
|
||||||
proc cgenWriteModules*(backend: RootRef) =
|
proc cgenWriteModules*(backend: RootRef, config: ConfigRef) =
|
||||||
let g = BModuleList(backend)
|
let g = BModuleList(backend)
|
||||||
# we need to process the transitive closure because recursive module
|
# we need to process the transitive closure because recursive module
|
||||||
# deps are allowed (and the system module is processed in the wrong
|
# deps are allowed (and the system module is processed in the wrong
|
||||||
# order anyway)
|
# order anyway)
|
||||||
|
g.config = config
|
||||||
if g.generatedHeader != nil: finishModule(g.generatedHeader)
|
if g.generatedHeader != nil: finishModule(g.generatedHeader)
|
||||||
while g.forwardedProcsCounter > 0:
|
while g.forwardedProcsCounter > 0:
|
||||||
for m in cgenModules(g):
|
for m in cgenModules(g):
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ type
|
||||||
breakPointId*: int
|
breakPointId*: int
|
||||||
breakpoints*: Rope # later the breakpoints are inserted into the main proc
|
breakpoints*: Rope # later the breakpoints are inserted into the main proc
|
||||||
typeInfoMarker*: TypeCache
|
typeInfoMarker*: TypeCache
|
||||||
|
config*: ConfigRef
|
||||||
|
|
||||||
TCGen = object of TPassContext # represents a C source file
|
TCGen = object of TPassContext # represents a C source file
|
||||||
s*: TCFileSections # sections of the C file
|
s*: TCFileSections # sections of the C file
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ type
|
||||||
passPP # preprocessor called processCommand()
|
passPP # preprocessor called processCommand()
|
||||||
|
|
||||||
proc processCommand*(switch: string, pass: TCmdLinePass)
|
proc processCommand*(switch: string, pass: TCmdLinePass)
|
||||||
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo)
|
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
|
config: ConfigRef = nil)
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
|
|
@ -312,7 +313,8 @@ proc dynlibOverride(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
options.inclDynlibOverride(arg)
|
options.inclDynlibOverride(arg)
|
||||||
|
|
||||||
proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
|
config: ConfigRef = nil) =
|
||||||
var
|
var
|
||||||
theOS: TSystemOS
|
theOS: TSystemOS
|
||||||
cpu: TSystemCPU
|
cpu: TSystemCPU
|
||||||
|
|
@ -523,7 +525,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
if pass in {passCmd2, passPP}: cLinkedLibs.add arg.processPath(info)
|
if pass in {passCmd2, passPP}: cLinkedLibs.add arg.processPath(info)
|
||||||
of "header":
|
of "header":
|
||||||
headerFile = arg
|
if config != nil: config.headerFile = arg
|
||||||
incl(gGlobalOptions, optGenIndex)
|
incl(gGlobalOptions, optGenIndex)
|
||||||
of "index":
|
of "index":
|
||||||
processOnOffSwitchG({optGenIndex}, arg, pass, info)
|
processOnOffSwitchG({optGenIndex}, arg, pass, info)
|
||||||
|
|
@ -646,6 +648,10 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
incl(gGlobalOptions, optNoCppExceptions)
|
incl(gGlobalOptions, optNoCppExceptions)
|
||||||
defineSymbol("noCppExceptions")
|
defineSymbol("noCppExceptions")
|
||||||
|
of "cppdefine":
|
||||||
|
expectArg(switch, arg, pass, info)
|
||||||
|
if config != nil:
|
||||||
|
config.cppDefine(arg)
|
||||||
else:
|
else:
|
||||||
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
||||||
else: invalidCmdLineOption(pass, switch, info)
|
else: invalidCmdLineOption(pass, switch, info)
|
||||||
|
|
|
||||||
|
|
@ -101,3 +101,4 @@ proc initDefines*() =
|
||||||
defineSymbol("nimImmediateDeprecated")
|
defineSymbol("nimImmediateDeprecated")
|
||||||
defineSymbol("nimNewShiftOps")
|
defineSymbol("nimNewShiftOps")
|
||||||
defineSymbol("nimDistros")
|
defineSymbol("nimDistros")
|
||||||
|
defineSymbol("nimHasCppDefine")
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ proc commandCompileToC(graph: ModuleGraph; cache: IdentCache) =
|
||||||
#registerPass(cleanupPass())
|
#registerPass(cleanupPass())
|
||||||
|
|
||||||
compileProject(graph, cache)
|
compileProject(graph, cache)
|
||||||
cgenWriteModules(graph.backend)
|
cgenWriteModules(graph.backend, graph.config)
|
||||||
if gCmd != cmdRun:
|
if gCmd != cmdRun:
|
||||||
let proj = changeFileExt(gProjectFull, "")
|
let proj = changeFileExt(gProjectFull, "")
|
||||||
extccomp.callCCompiler(proj)
|
extccomp.callCCompiler(proj)
|
||||||
|
|
@ -294,4 +294,4 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
|
||||||
|
|
||||||
resetAttributes()
|
resetAttributes()
|
||||||
|
|
||||||
proc mainCommand*() = mainCommand(newModuleGraph(), newIdentCache())
|
proc mainCommand*() = mainCommand(newModuleGraph(newConfigRef()), newIdentCache())
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
## - Its dependent module stays the same.
|
## - Its dependent module stays the same.
|
||||||
##
|
##
|
||||||
|
|
||||||
import ast, intsets, tables
|
import ast, intsets, tables, options
|
||||||
|
|
||||||
type
|
type
|
||||||
ModuleGraph* = ref object
|
ModuleGraph* = ref object
|
||||||
|
|
@ -39,16 +39,18 @@ type
|
||||||
importStack*: seq[int32] # The current import stack. Used for detecting recursive
|
importStack*: seq[int32] # The current import stack. Used for detecting recursive
|
||||||
# module dependencies.
|
# module dependencies.
|
||||||
backend*: RootRef # minor hack so that a backend can extend this easily
|
backend*: RootRef # minor hack so that a backend can extend this easily
|
||||||
|
config*: ConfigRef
|
||||||
|
|
||||||
{.this: g.}
|
{.this: g.}
|
||||||
|
|
||||||
proc newModuleGraph*(): ModuleGraph =
|
proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
|
||||||
result = ModuleGraph()
|
result = ModuleGraph()
|
||||||
initStrTable(result.packageSyms)
|
initStrTable(result.packageSyms)
|
||||||
result.deps = initIntSet()
|
result.deps = initIntSet()
|
||||||
result.modules = @[]
|
result.modules = @[]
|
||||||
result.importStack = @[]
|
result.importStack = @[]
|
||||||
result.inclToMod = initTable[int32, int32]()
|
result.inclToMod = initTable[int32, int32]()
|
||||||
|
result.config = config
|
||||||
|
|
||||||
proc resetAllModules*(g: ModuleGraph) =
|
proc resetAllModules*(g: ModuleGraph) =
|
||||||
initStrTable(packageSyms)
|
initStrTable(packageSyms)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ proc prependCurDir(f: string): string =
|
||||||
else:
|
else:
|
||||||
result = f
|
result = f
|
||||||
|
|
||||||
proc handleCmdLine(cache: IdentCache) =
|
proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
if paramCount() == 0:
|
if paramCount() == 0:
|
||||||
writeCommandLineUsage()
|
writeCommandLineUsage()
|
||||||
else:
|
else:
|
||||||
|
|
@ -59,22 +59,22 @@ proc handleCmdLine(cache: IdentCache) =
|
||||||
gProjectName = p.name
|
gProjectName = p.name
|
||||||
else:
|
else:
|
||||||
gProjectPath = canonicalizePath getCurrentDir()
|
gProjectPath = canonicalizePath getCurrentDir()
|
||||||
loadConfigs(DefaultConfig) # load all config files
|
loadConfigs(DefaultConfig, config) # load all config files
|
||||||
let scriptFile = gProjectFull.changeFileExt("nims")
|
let scriptFile = gProjectFull.changeFileExt("nims")
|
||||||
if fileExists(scriptFile):
|
if fileExists(scriptFile):
|
||||||
runNimScript(cache, scriptFile, freshDefines=false)
|
runNimScript(cache, scriptFile, freshDefines=false, config)
|
||||||
# '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 scriptFile == gProjectFull: return
|
if scriptFile == gProjectFull: return
|
||||||
elif fileExists(gProjectPath / "config.nims"):
|
elif fileExists(gProjectPath / "config.nims"):
|
||||||
# directory wide NimScript file
|
# directory wide NimScript file
|
||||||
runNimScript(cache, gProjectPath / "config.nims", freshDefines=false)
|
runNimScript(cache, gProjectPath / "config.nims", freshDefines=false, config)
|
||||||
# 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 overwite the config file's settings
|
# command line can overwite the config file's settings
|
||||||
extccomp.initVars()
|
extccomp.initVars()
|
||||||
processCmdLine(passCmd2, "")
|
processCmdLine(passCmd2, "")
|
||||||
if options.command == "":
|
if options.command == "":
|
||||||
rawMessage(errNoCommand, command)
|
rawMessage(errNoCommand, command)
|
||||||
mainCommand(newModuleGraph(), cache)
|
mainCommand(newModuleGraph(config), cache)
|
||||||
if optHints in gOptions and hintGCStats in gNotes: echo(GC_getStatistics())
|
if optHints in gOptions and hintGCStats in gNotes: echo(GC_getStatistics())
|
||||||
#echo(GC_getStatistics())
|
#echo(GC_getStatistics())
|
||||||
if msgs.gErrorCounter == 0:
|
if msgs.gErrorCounter == 0:
|
||||||
|
|
@ -118,5 +118,5 @@ when compileOption("gc", "v2") or compileOption("gc", "refc"):
|
||||||
condsyms.initDefines()
|
condsyms.initDefines()
|
||||||
|
|
||||||
when not defined(selftest):
|
when not defined(selftest):
|
||||||
handleCmdLine(newIdentCache())
|
handleCmdLine(newIdentCache(), newConfigRef())
|
||||||
msgQuit(int8(msgs.gErrorCounter > 0))
|
msgQuit(int8(msgs.gErrorCounter > 0))
|
||||||
|
|
|
||||||
|
|
@ -21,37 +21,37 @@ proc ppGetTok(L: var TLexer, tok: var TToken) =
|
||||||
rawGetTok(L, tok)
|
rawGetTok(L, tok)
|
||||||
while tok.tokType in {tkComment}: rawGetTok(L, tok)
|
while tok.tokType in {tkComment}: rawGetTok(L, tok)
|
||||||
|
|
||||||
proc parseExpr(L: var TLexer, tok: var TToken): bool
|
proc parseExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool
|
||||||
proc parseAtom(L: var TLexer, tok: var TToken): bool =
|
proc parseAtom(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
|
||||||
if tok.tokType == tkParLe:
|
if tok.tokType == tkParLe:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
result = parseExpr(L, tok)
|
result = parseExpr(L, tok, config)
|
||||||
if tok.tokType == tkParRi: ppGetTok(L, tok)
|
if tok.tokType == tkParRi: ppGetTok(L, tok)
|
||||||
else: lexMessage(L, errTokenExpected, "\')\'")
|
else: lexMessage(L, errTokenExpected, "\')\'")
|
||||||
elif tok.ident.id == ord(wNot):
|
elif tok.ident.id == ord(wNot):
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
result = not parseAtom(L, tok)
|
result = not parseAtom(L, tok, config)
|
||||||
else:
|
else:
|
||||||
result = isDefined(tok.ident)
|
result = isDefined(tok.ident)
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
|
|
||||||
proc parseAndExpr(L: var TLexer, tok: var TToken): bool =
|
proc parseAndExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
|
||||||
result = parseAtom(L, tok)
|
result = parseAtom(L, tok, config)
|
||||||
while tok.ident.id == ord(wAnd):
|
while tok.ident.id == ord(wAnd):
|
||||||
ppGetTok(L, tok) # skip "and"
|
ppGetTok(L, tok) # skip "and"
|
||||||
var b = parseAtom(L, tok)
|
var b = parseAtom(L, tok, config)
|
||||||
result = result and b
|
result = result and b
|
||||||
|
|
||||||
proc parseExpr(L: var TLexer, tok: var TToken): bool =
|
proc parseExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
|
||||||
result = parseAndExpr(L, tok)
|
result = parseAndExpr(L, tok, config)
|
||||||
while tok.ident.id == ord(wOr):
|
while tok.ident.id == ord(wOr):
|
||||||
ppGetTok(L, tok) # skip "or"
|
ppGetTok(L, tok) # skip "or"
|
||||||
var b = parseAndExpr(L, tok)
|
var b = parseAndExpr(L, tok, config)
|
||||||
result = result or b
|
result = result or b
|
||||||
|
|
||||||
proc evalppIf(L: var TLexer, tok: var TToken): bool =
|
proc evalppIf(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
|
||||||
ppGetTok(L, tok) # skip 'if' or 'elif'
|
ppGetTok(L, tok) # skip 'if' or 'elif'
|
||||||
result = parseExpr(L, tok)
|
result = parseExpr(L, tok, config)
|
||||||
if tok.tokType == tkColon: ppGetTok(L, tok)
|
if tok.tokType == tkColon: ppGetTok(L, tok)
|
||||||
else: lexMessage(L, errTokenExpected, "\':\'")
|
else: lexMessage(L, errTokenExpected, "\':\'")
|
||||||
|
|
||||||
|
|
@ -66,20 +66,20 @@ type
|
||||||
TJumpDest = enum
|
TJumpDest = enum
|
||||||
jdEndif, jdElseEndif
|
jdEndif, jdElseEndif
|
||||||
|
|
||||||
proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest)
|
proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest; config: ConfigRef)
|
||||||
proc doElse(L: var TLexer, tok: var TToken) =
|
proc doElse(L: var TLexer, tok: var TToken; config: ConfigRef) =
|
||||||
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
if tok.tokType == tkColon: ppGetTok(L, tok)
|
if tok.tokType == tkColon: ppGetTok(L, tok)
|
||||||
if condStack[high(condStack)]: jumpToDirective(L, tok, jdEndif)
|
if condStack[high(condStack)]: jumpToDirective(L, tok, jdEndif, config)
|
||||||
|
|
||||||
proc doElif(L: var TLexer, tok: var TToken) =
|
proc doElif(L: var TLexer, tok: var TToken; config: ConfigRef) =
|
||||||
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
||||||
var res = evalppIf(L, tok)
|
var res = evalppIf(L, tok, config)
|
||||||
if condStack[high(condStack)] or not res: jumpToDirective(L, tok, jdElseEndif)
|
if condStack[high(condStack)] or not res: jumpToDirective(L, tok, jdElseEndif, config)
|
||||||
else: condStack[high(condStack)] = true
|
else: condStack[high(condStack)] = true
|
||||||
|
|
||||||
proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) =
|
proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest; config: ConfigRef) =
|
||||||
var nestedIfs = 0
|
var nestedIfs = 0
|
||||||
while true:
|
while true:
|
||||||
if tok.ident != nil and tok.ident.s == "@":
|
if tok.ident != nil and tok.ident.s == "@":
|
||||||
|
|
@ -89,11 +89,11 @@ proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) =
|
||||||
inc(nestedIfs)
|
inc(nestedIfs)
|
||||||
of wElse:
|
of wElse:
|
||||||
if dest == jdElseEndif and nestedIfs == 0:
|
if dest == jdElseEndif and nestedIfs == 0:
|
||||||
doElse(L, tok)
|
doElse(L, tok, config)
|
||||||
break
|
break
|
||||||
of wElif:
|
of wElif:
|
||||||
if dest == jdElseEndif and nestedIfs == 0:
|
if dest == jdElseEndif and nestedIfs == 0:
|
||||||
doElif(L, tok)
|
doElif(L, tok, config)
|
||||||
break
|
break
|
||||||
of wEnd:
|
of wEnd:
|
||||||
if nestedIfs == 0:
|
if nestedIfs == 0:
|
||||||
|
|
@ -108,16 +108,16 @@ proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) =
|
||||||
else:
|
else:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
|
|
||||||
proc parseDirective(L: var TLexer, tok: var TToken) =
|
proc parseDirective(L: var TLexer, tok: var TToken; config: ConfigRef) =
|
||||||
ppGetTok(L, tok) # skip @
|
ppGetTok(L, tok) # skip @
|
||||||
case whichKeyword(tok.ident)
|
case whichKeyword(tok.ident)
|
||||||
of wIf:
|
of wIf:
|
||||||
setLen(condStack, len(condStack) + 1)
|
setLen(condStack, len(condStack) + 1)
|
||||||
let res = evalppIf(L, tok)
|
let res = evalppIf(L, tok, config)
|
||||||
condStack[high(condStack)] = res
|
condStack[high(condStack)] = res
|
||||||
if not res: jumpToDirective(L, tok, jdElseEndif)
|
if not res: jumpToDirective(L, tok, jdElseEndif, config)
|
||||||
of wElif: doElif(L, tok)
|
of wElif: doElif(L, tok, config)
|
||||||
of wElse: doElse(L, tok)
|
of wElse: doElse(L, tok, config)
|
||||||
of wEnd: doEnd(L, tok)
|
of wEnd: doEnd(L, tok)
|
||||||
of wWrite:
|
of wWrite:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
|
|
@ -146,58 +146,58 @@ proc parseDirective(L: var TLexer, tok: var TToken) =
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
else: lexMessage(L, errInvalidDirectiveX, tokToStr(tok))
|
else: lexMessage(L, errInvalidDirectiveX, tokToStr(tok))
|
||||||
|
|
||||||
proc confTok(L: var TLexer, tok: var TToken) =
|
proc confTok(L: var TLexer, tok: var TToken; config: ConfigRef) =
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
while tok.ident != nil and tok.ident.s == "@":
|
while tok.ident != nil and tok.ident.s == "@":
|
||||||
parseDirective(L, tok) # else: give the token to the parser
|
parseDirective(L, tok, config) # else: give the token to the parser
|
||||||
|
|
||||||
proc checkSymbol(L: TLexer, tok: TToken) =
|
proc checkSymbol(L: TLexer, tok: TToken) =
|
||||||
if tok.tokType notin {tkSymbol..pred(tkIntLit), tkStrLit..tkTripleStrLit}:
|
if tok.tokType notin {tkSymbol..pred(tkIntLit), tkStrLit..tkTripleStrLit}:
|
||||||
lexMessage(L, errIdentifierExpected, tokToStr(tok))
|
lexMessage(L, errIdentifierExpected, tokToStr(tok))
|
||||||
|
|
||||||
proc parseAssignment(L: var TLexer, tok: var TToken) =
|
proc parseAssignment(L: var TLexer, tok: var TToken; config: ConfigRef) =
|
||||||
if tok.ident.s == "-" or tok.ident.s == "--":
|
if tok.ident.s == "-" or tok.ident.s == "--":
|
||||||
confTok(L, tok) # skip unnecessary prefix
|
confTok(L, tok, config) # skip unnecessary prefix
|
||||||
var info = getLineInfo(L, tok) # save for later in case of an error
|
var info = getLineInfo(L, tok) # save for later in case of an error
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
var s = tokToStr(tok)
|
var s = tokToStr(tok)
|
||||||
confTok(L, tok) # skip symbol
|
confTok(L, tok, config) # skip symbol
|
||||||
var val = ""
|
var val = ""
|
||||||
while tok.tokType == tkDot:
|
while tok.tokType == tkDot:
|
||||||
add(s, '.')
|
add(s, '.')
|
||||||
confTok(L, tok)
|
confTok(L, tok, config)
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(s, tokToStr(tok))
|
add(s, tokToStr(tok))
|
||||||
confTok(L, tok)
|
confTok(L, tok, config)
|
||||||
if tok.tokType == tkBracketLe:
|
if tok.tokType == tkBracketLe:
|
||||||
# BUGFIX: val, not s!
|
# BUGFIX: val, not s!
|
||||||
# BUGFIX: do not copy '['!
|
# BUGFIX: do not copy '['!
|
||||||
confTok(L, tok)
|
confTok(L, tok, config)
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(val, tokToStr(tok))
|
add(val, tokToStr(tok))
|
||||||
confTok(L, tok)
|
confTok(L, tok, config)
|
||||||
if tok.tokType == tkBracketRi: confTok(L, tok)
|
if tok.tokType == tkBracketRi: confTok(L, tok, config)
|
||||||
else: lexMessage(L, errTokenExpected, "']'")
|
else: lexMessage(L, errTokenExpected, "']'")
|
||||||
add(val, ']')
|
add(val, ']')
|
||||||
let percent = tok.ident != nil and tok.ident.s == "%="
|
let percent = tok.ident != nil and tok.ident.s == "%="
|
||||||
if tok.tokType in {tkColon, tkEquals} or percent:
|
if tok.tokType in {tkColon, tkEquals} or percent:
|
||||||
if len(val) > 0: add(val, ':')
|
if len(val) > 0: add(val, ':')
|
||||||
confTok(L, tok) # skip ':' or '=' or '%'
|
confTok(L, tok, config) # skip ':' or '=' or '%'
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(val, tokToStr(tok))
|
add(val, tokToStr(tok))
|
||||||
confTok(L, tok) # skip symbol
|
confTok(L, tok, config) # skip symbol
|
||||||
while tok.ident != nil and tok.ident.s == "&":
|
while tok.ident != nil and tok.ident.s == "&":
|
||||||
confTok(L, tok)
|
confTok(L, tok, config)
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(val, tokToStr(tok))
|
add(val, tokToStr(tok))
|
||||||
confTok(L, tok)
|
confTok(L, tok, config)
|
||||||
if percent:
|
if percent:
|
||||||
processSwitch(s, strtabs.`%`(val, options.gConfigVars,
|
processSwitch(s, strtabs.`%`(val, options.gConfigVars,
|
||||||
{useEnvironment, useEmpty}), passPP, info)
|
{useEnvironment, useEmpty}), passPP, info, config)
|
||||||
else:
|
else:
|
||||||
processSwitch(s, val, passPP, info)
|
processSwitch(s, val, passPP, info, config)
|
||||||
|
|
||||||
proc readConfigFile(filename: string; cache: IdentCache) =
|
proc readConfigFile(filename: string; cache: IdentCache; config: ConfigRef) =
|
||||||
var
|
var
|
||||||
L: TLexer
|
L: TLexer
|
||||||
tok: TToken
|
tok: TToken
|
||||||
|
|
@ -207,8 +207,8 @@ proc readConfigFile(filename: string; cache: IdentCache) =
|
||||||
initToken(tok)
|
initToken(tok)
|
||||||
openLexer(L, filename, stream, cache)
|
openLexer(L, filename, stream, cache)
|
||||||
tok.tokType = tkEof # to avoid a pointless warning
|
tok.tokType = tkEof # to avoid a pointless warning
|
||||||
confTok(L, tok) # read in the first token
|
confTok(L, tok, config) # read in the first token
|
||||||
while tok.tokType != tkEof: parseAssignment(L, tok)
|
while tok.tokType != tkEof: parseAssignment(L, tok, config)
|
||||||
if len(condStack) > 0: lexMessage(L, errTokenExpected, "@end")
|
if len(condStack) > 0: lexMessage(L, errTokenExpected, "@end")
|
||||||
closeLexer(L)
|
closeLexer(L)
|
||||||
rawMessage(hintConf, filename)
|
rawMessage(hintConf, filename)
|
||||||
|
|
@ -225,22 +225,22 @@ proc getSystemConfigPath(filename: string): string =
|
||||||
if not existsFile(result): result = joinPath([p, "etc", filename])
|
if not existsFile(result): result = joinPath([p, "etc", filename])
|
||||||
if not existsFile(result): result = "/etc/" & filename
|
if not existsFile(result): result = "/etc/" & filename
|
||||||
|
|
||||||
proc loadConfigs*(cfg: string; cache: IdentCache) =
|
proc loadConfigs*(cfg: string; cache: IdentCache; config: ConfigRef = nil) =
|
||||||
setDefaultLibpath()
|
setDefaultLibpath()
|
||||||
|
|
||||||
if optSkipConfigFile notin gGlobalOptions:
|
if optSkipConfigFile notin gGlobalOptions:
|
||||||
readConfigFile(getSystemConfigPath(cfg), cache)
|
readConfigFile(getSystemConfigPath(cfg), cache, config)
|
||||||
|
|
||||||
if optSkipUserConfigFile notin gGlobalOptions:
|
if optSkipUserConfigFile notin gGlobalOptions:
|
||||||
readConfigFile(getUserConfigPath(cfg), cache)
|
readConfigFile(getUserConfigPath(cfg), cache, config)
|
||||||
|
|
||||||
var pd = if gProjectPath.len > 0: gProjectPath else: getCurrentDir()
|
var pd = if gProjectPath.len > 0: gProjectPath else: getCurrentDir()
|
||||||
if optSkipParentConfigFiles notin gGlobalOptions:
|
if optSkipParentConfigFiles notin gGlobalOptions:
|
||||||
for dir in parentDirs(pd, fromRoot=true, inclusive=false):
|
for dir in parentDirs(pd, fromRoot=true, inclusive=false):
|
||||||
readConfigFile(dir / cfg, cache)
|
readConfigFile(dir / cfg, cache, config)
|
||||||
|
|
||||||
if optSkipProjConfigFile notin gGlobalOptions:
|
if optSkipProjConfigFile notin gGlobalOptions:
|
||||||
readConfigFile(pd / cfg, cache)
|
readConfigFile(pd / cfg, cache, config)
|
||||||
|
|
||||||
if gProjectName.len != 0:
|
if gProjectName.len != 0:
|
||||||
# new project wide config file:
|
# new project wide config file:
|
||||||
|
|
@ -251,8 +251,8 @@ proc loadConfigs*(cfg: string; cache: IdentCache) =
|
||||||
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
|
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
|
||||||
if fileExists(projectConfig):
|
if fileExists(projectConfig):
|
||||||
rawMessage(warnDeprecated, projectConfig)
|
rawMessage(warnDeprecated, projectConfig)
|
||||||
readConfigFile(projectConfig, cache)
|
readConfigFile(projectConfig, cache, config)
|
||||||
|
|
||||||
proc loadConfigs*(cfg: string) =
|
proc loadConfigs*(cfg: string; config: ConfigRef = nil) =
|
||||||
# for backwards compatibility only.
|
# for backwards compatibility only.
|
||||||
loadConfigs(cfg, newIdentCache())
|
loadConfigs(cfg, newIdentCache(), config)
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,17 @@ type
|
||||||
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
|
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
|
||||||
ideHighlight, ideOutline
|
ideHighlight, ideOutline
|
||||||
|
|
||||||
|
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
||||||
|
cppDefines*: HashSet[string]
|
||||||
|
headerFile*: string
|
||||||
|
|
||||||
|
proc newConfigRef*(): ConfigRef =
|
||||||
|
result = ConfigRef(cppDefines: initSet[string](),
|
||||||
|
headerFile: "")
|
||||||
|
|
||||||
|
proc cppDefine*(c: ConfigRef; define: string) =
|
||||||
|
c.cppDefines.incl define
|
||||||
|
|
||||||
var
|
var
|
||||||
gIdeCmd*: IdeCmd
|
gIdeCmd*: IdeCmd
|
||||||
|
|
||||||
|
|
@ -122,7 +133,7 @@ var
|
||||||
outFile*: string = ""
|
outFile*: string = ""
|
||||||
docSeeSrcUrl*: string = "" # if empty, no seeSrc will be generated. \
|
docSeeSrcUrl*: string = "" # if empty, no seeSrc will be generated. \
|
||||||
# The string uses the formatting variables `path` and `line`.
|
# The string uses the formatting variables `path` and `line`.
|
||||||
headerFile*: string = ""
|
#headerFile*: string = ""
|
||||||
gVerbosity* = 1 # how verbose the compiler is
|
gVerbosity* = 1 # how verbose the compiler is
|
||||||
gNumberOfProcessors*: int # number of processors
|
gNumberOfProcessors*: int # number of processors
|
||||||
gWholeProject*: bool # for 'doc2': output any dependency
|
gWholeProject*: bool # for 'doc2': output any dependency
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) =
|
||||||
if kind in filter: result.add path
|
if kind in filter: result.add path
|
||||||
setResult(a, result)
|
setResult(a, result)
|
||||||
|
|
||||||
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string): PEvalContext =
|
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||||
|
config: ConfigRef = nil): PEvalContext =
|
||||||
# For Nimble we need to export 'setupVM'.
|
# For Nimble we need to export 'setupVM'.
|
||||||
result = newCtx(module, cache)
|
result = newCtx(module, cache)
|
||||||
result.mode = emRepl
|
result.mode = emRepl
|
||||||
|
|
@ -133,12 +134,15 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string): PEvalContext
|
||||||
gModuleOverrides[key] = val
|
gModuleOverrides[key] = val
|
||||||
cbconf selfExe:
|
cbconf selfExe:
|
||||||
setResult(a, os.getAppFilename())
|
setResult(a, os.getAppFilename())
|
||||||
|
cbconf cppDefine:
|
||||||
|
if config != nil:
|
||||||
|
options.cppDefine(config, a.getString(0))
|
||||||
|
|
||||||
proc runNimScript*(cache: IdentCache; scriptName: string;
|
proc runNimScript*(cache: IdentCache; scriptName: string;
|
||||||
freshDefines=true) =
|
freshDefines=true; config: ConfigRef=nil) =
|
||||||
passes.gIncludeFile = includeModule
|
passes.gIncludeFile = includeModule
|
||||||
passes.gImportModule = importModule
|
passes.gImportModule = importModule
|
||||||
let graph = newModuleGraph()
|
let graph = newModuleGraph(config)
|
||||||
if freshDefines: initDefines()
|
if freshDefines: initDefines()
|
||||||
|
|
||||||
defineSymbol("nimscript")
|
defineSymbol("nimscript")
|
||||||
|
|
@ -150,7 +154,7 @@ proc runNimScript*(cache: IdentCache; scriptName: string;
|
||||||
|
|
||||||
var m = graph.makeModule(scriptName)
|
var m = graph.makeModule(scriptName)
|
||||||
incl(m.flags, sfMainModule)
|
incl(m.flags, sfMainModule)
|
||||||
vm.globalCtx = setupVM(m, cache, scriptName)
|
vm.globalCtx = setupVM(m, cache, scriptName, config)
|
||||||
|
|
||||||
graph.compileSystemModule(cache)
|
graph.compileSystemModule(cache)
|
||||||
discard graph.processModule(m, llStreamOpen(scriptName, fmRead), nil, cache)
|
discard graph.processModule(m, llStreamOpen(scriptName, fmRead), nil, cache)
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,11 @@ template task*(name: untyped; description: string; body: untyped): untyped =
|
||||||
setCommand "nop"
|
setCommand "nop"
|
||||||
`name Task`()
|
`name Task`()
|
||||||
|
|
||||||
|
proc cppDefine*(define: string) =
|
||||||
|
## tell Nim that ``define`` is a C preprocessor ``#define`` and so always
|
||||||
|
## needs to be mangled.
|
||||||
|
builtin
|
||||||
|
|
||||||
when not defined(nimble):
|
when not defined(nimble):
|
||||||
# nimble has its own implementation for these things.
|
# nimble has its own implementation for these things.
|
||||||
var
|
var
|
||||||
|
|
|
||||||
|
|
@ -418,7 +418,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||||
options.gProjectName = unixToNativePath(p.key)
|
options.gProjectName = unixToNativePath(p.key)
|
||||||
# if processArgument(pass, p, argsCount): break
|
# if processArgument(pass, p, argsCount): break
|
||||||
|
|
||||||
proc handleCmdLine(cache: IdentCache) =
|
proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
if paramCount() == 0:
|
if paramCount() == 0:
|
||||||
stdout.writeline(Usage)
|
stdout.writeline(Usage)
|
||||||
else:
|
else:
|
||||||
|
|
@ -444,23 +444,23 @@ proc handleCmdLine(cache: IdentCache) =
|
||||||
gPrefixDir = binaryPath.splitPath().head.parentDir()
|
gPrefixDir = binaryPath.splitPath().head.parentDir()
|
||||||
#msgs.writelnHook = proc (line: string) = logStr(line)
|
#msgs.writelnHook = proc (line: string) = logStr(line)
|
||||||
|
|
||||||
loadConfigs(DefaultConfig, cache) # load all config files
|
loadConfigs(DefaultConfig, cache, config) # load all config files
|
||||||
# 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 overwite the config file's settings
|
# command line can overwite the config file's settings
|
||||||
options.command = "nimsuggest"
|
options.command = "nimsuggest"
|
||||||
let scriptFile = gProjectFull.changeFileExt("nims")
|
let scriptFile = gProjectFull.changeFileExt("nims")
|
||||||
if fileExists(scriptFile):
|
if fileExists(scriptFile):
|
||||||
runNimScript(cache, scriptFile, freshDefines=false)
|
runNimScript(cache, scriptFile, freshDefines=false, config)
|
||||||
# '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 scriptFile == gProjectFull: return
|
if scriptFile == gProjectFull: return
|
||||||
elif fileExists(gProjectPath / "config.nims"):
|
elif fileExists(gProjectPath / "config.nims"):
|
||||||
# directory wide NimScript file
|
# directory wide NimScript file
|
||||||
runNimScript(cache, gProjectPath / "config.nims", freshDefines=false)
|
runNimScript(cache, gProjectPath / "config.nims", freshDefines=false, config)
|
||||||
|
|
||||||
extccomp.initVars()
|
extccomp.initVars()
|
||||||
processCmdLine(passCmd2, "")
|
processCmdLine(passCmd2, "")
|
||||||
|
|
||||||
let graph = newModuleGraph()
|
let graph = newModuleGraph(config)
|
||||||
graph.suggestMode = true
|
graph.suggestMode = true
|
||||||
mainCommand(graph, cache)
|
mainCommand(graph, cache)
|
||||||
|
|
||||||
|
|
@ -472,4 +472,4 @@ when false:
|
||||||
|
|
||||||
condsyms.initDefines()
|
condsyms.initDefines()
|
||||||
defineSymbol "nimsuggest"
|
defineSymbol "nimsuggest"
|
||||||
handleCmdline(newIdentCache())
|
handleCmdline(newIdentCache(), newConfigRef())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue