Skip to content

Commit

Permalink
Merge pull request #2 from nim-lang/devel
Browse files Browse the repository at this point in the history
Pull 25-04-18
  • Loading branch information
survivorm authored Apr 25, 2018
2 parents 17d3c6f + e931f3b commit 3949c9f
Show file tree
Hide file tree
Showing 90 changed files with 405 additions and 379 deletions.
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,10 @@
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual
machine.

- The ``deadCodeElim`` option is now always turned on and the switch has no
effect anymore, but is recognized for backwards compatibility.

- ``experimental`` is now a pragma / command line switch that can enable specific
language extensions, it is not an all-or-nothing switch anymore.

### Bugfixes
8 changes: 4 additions & 4 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ type
# variable is a thread variable
sfCompileTime, # proc can be evaluated at compile time
sfConstructor, # proc is a C++ constructor
sfDeadCodeElim, # dead code elimination for the module is turned on
sfDispatcher, # copied method symbol is the dispatcher
# deprecated and unused, except for the con
sfBorrow, # proc is borrowed
sfInfixCall, # symbol needs infix call syntax in target language;
# for interfacing with C++, JS
Expand All @@ -275,10 +276,9 @@ type
TSymFlags* = set[TSymFlag]

const
sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher
sfNoInit* = sfMainModule # don't generate code to init the variable

sfImmediate* = sfDeadCodeElim
sfImmediate* = sfDispatcher
# macro or template is immediately expanded
# without considering any possible overloads
sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
Expand Down Expand Up @@ -1622,7 +1622,7 @@ iterator items*(n: PNode): PNode =
for i in 0..<n.safeLen: yield n.sons[i]

iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
for i in 0..<n.len: yield (i, n.sons[i])
for i in 0..<n.safeLen: yield (i, n.sons[i])

proc isAtom*(n: PNode): bool {.inline.} =
result = n.kind >= nkNone and n.kind <= nkNilLit
Expand Down
5 changes: 2 additions & 3 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2264,7 +2264,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
of nkEmpty: discard
of nkWhileStmt: genWhileStmt(p, n)
of nkVarSection, nkLetSection: genVarStmt(p, n)
of nkConstSection: genConstStmt(p, n)
of nkConstSection: discard # consts generated lazily on use
of nkForStmt: internalError(n.info, "for statement not eliminated")
of nkCaseStmt: genCase(p, n, d)
of nkReturnStmt: genReturnStmt(p, n)
Expand Down Expand Up @@ -2315,8 +2315,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
# are not transformed correctly. We work around this issue (#411) here
# by ensuring it's no inner proc (owner is a module):
if prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags:
if (not emitLazily(prc)) or
({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
if ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
(sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
(prc.kind == skMethod):
# we have not only the header:
Expand Down
18 changes: 2 additions & 16 deletions compiler/ccgstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -280,20 +280,6 @@ proc genVarStmt(p: BProc, n: PNode) =
else:
genVarTuple(p, it)

proc genConstStmt(p: BProc, n: PNode) =
for it in n.sons:
if it.kind == nkCommentStmt: continue
if it.kind != nkConstDef: internalError(n.info, "genConstStmt")

let sym = it.sons[0].sym
if sym.typ.containsCompileTimeOnly or
sym.typ.kind notin ConstantDataTypes or
sym.ast.len == 0 or
emitLazily(sym):
continue

requestConstImpl(p, sym)

proc genIf(p: BProc, n: PNode, d: var TLoc) =
#
# { if (!expr1) goto L1;
Expand Down Expand Up @@ -587,7 +573,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
genLineDir(p, t)
if isImportedException(typ):
lineF(p, cpsStmts, "throw $1;$n", [e])
else:
else:
lineCg(p, cpsStmts, "#raiseException((#Exception*)$1, $2);$n",
[e, makeCString(typ.sym.name.s)])
else:
Expand Down Expand Up @@ -836,7 +822,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
else:
for j in 0..t[i].len-2:
if t[i][j].isInfixAs():
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
fillLoc(exvar.sym.loc, locTemp, exvar, mangleLocalName(p, exvar.sym), OnUnknown)
startBlock(p, "catch ($1& $2) {$n", getTypeDesc(p.module, t[i][j][1].typ), rdLoc(exvar.sym.loc))
else:
Expand Down
4 changes: 0 additions & 4 deletions compiler/ccgutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,4 @@ proc mangle*(name: string): string =
if requiresUnderscore:
result.add "_"

proc emitLazily*(s: PSym): bool {.inline.} =
result = optDeadCodeElim in gGlobalOptions or
sfDeadCodeElim in getModule(s).flags

initTypeTables()
4 changes: 0 additions & 4 deletions compiler/cgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1309,10 +1309,6 @@ proc newModule(g: BModuleList; module: PSym): BModule =
growCache g.modules, module.position
g.modules[module.position] = result

if (optDeadCodeElim in gGlobalOptions):
if (sfDeadCodeElim in module.flags):
internalError("added pending module twice: " & toFilename(FileIndex module.position))

template injectG(config) {.dirty.} =
if graph.backend == nil:
graph.backend = newModuleList(config)
Expand Down
52 changes: 29 additions & 23 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ type
passCmd2, # second pass over the command line
passPP # preprocessor called processCommand()

proc processCommand*(switch: string, pass: TCmdLinePass)
proc processCommand*(switch: string, pass: TCmdLinePass; config: ConfigRef)
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
config: ConfigRef = nil)
config: ConfigRef)

# implementation

Expand All @@ -58,7 +58,13 @@ const

const
Usage = slurp"../doc/basicopt.txt".replace("//", "")
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "")
FeatureDesc = block:
var x = ""
for f in low(Feature)..high(Feature):
if x.len > 0: x.add "|"
x.add $f
x
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "") % FeatureDesc

proc getCommandLineDesc(): string =
result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name,
Expand Down Expand Up @@ -268,7 +274,6 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
of "movechecks": result = contains(gOptions, optMoveCheck)
of "linedir": result = contains(gOptions, optLineDir)
of "assertions", "a": result = contains(gOptions, optAssert)
of "deadcodeelim": result = contains(gGlobalOptions, optDeadCodeElim)
of "run", "r": result = contains(gGlobalOptions, optRun)
of "symbolfiles": result = gSymbolFiles != disabledSf
of "genscript": result = contains(gGlobalOptions, optGenScript)
Expand All @@ -277,7 +282,6 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
of "implicitstatic": result = contains(gOptions, optImplicitStatic)
of "patterns": result = contains(gOptions, optPatterns)
of "experimental": result = gExperimentalMode
of "excessivestacktrace": result = contains(gGlobalOptions, optExcessiveStackTrace)
else: invalidCmdLineOption(passCmd1, switch, info)

Expand Down Expand Up @@ -340,7 +344,7 @@ proc dynlibOverride(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
options.inclDynlibOverride(arg)

proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
config: ConfigRef = nil) =
config: ConfigRef) =
var
theOS: TSystemOS
cpu: TSystemCPU
Expand Down Expand Up @@ -509,7 +513,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "movechecks": processOnOffSwitch({optMoveCheck}, arg, pass, info)
of "linedir": processOnOffSwitch({optLineDir}, arg, pass, info)
of "assertions", "a": processOnOffSwitch({optAssert}, arg, pass, info)
of "deadcodeelim": processOnOffSwitchG({optDeadCodeElim}, arg, pass, info)
of "deadcodeelim": discard # deprecated, dead code elim always on
of "threads":
processOnOffSwitchG({optThreads}, arg, pass, info)
#if optThreads in gGlobalOptions: incl(gNotes, warnGcUnsafe)
Expand Down Expand Up @@ -648,6 +652,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "genscript", "gendeps":
expectNoArg(switch, arg, pass, info)
incl(gGlobalOptions, optGenScript)
incl(gGlobalOptions, optCompileOnly)
of "colors": processOnOffSwitchG({optUseColors}, arg, pass, info)
of "lib":
expectArg(switch, arg, pass, info)
Expand Down Expand Up @@ -695,8 +700,13 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
# only supported for compatibility. Does nothing.
expectArg(switch, arg, pass, info)
of "experimental":
expectNoArg(switch, arg, pass, info)
gExperimentalMode = true
if arg.len == 0:
config.features.incl oldExperimentalFeatures
else:
try:
config.features.incl parseEnum[Feature](arg)
except ValueError:
localError(info, "unknown experimental feature")
of "nocppexceptions":
expectNoArg(switch, arg, pass, info)
incl(gGlobalOptions, optNoCppExceptions)
Expand All @@ -707,7 +717,8 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
config.cppDefine(arg)
of "newruntime":
expectNoArg(switch, arg, pass, info)
newDestructors = true
doAssert(config != nil)
incl(config.features, destructor)
defineSymbol("nimNewRuntime")
of "cppcompiletonamespace":
expectNoArg(switch, arg, pass, info)
Expand All @@ -717,36 +728,31 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
else: invalidCmdLineOption(pass, switch, info)

proc processCommand(switch: string, pass: TCmdLinePass) =
proc processCommand(switch: string, pass: TCmdLinePass; config: ConfigRef) =
var cmd, arg: string
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
processSwitch(cmd, arg, pass, gCmdLineInfo)
processSwitch(cmd, arg, pass, gCmdLineInfo, config)


var
arguments* = ""
# the arguments to be passed to the program that
# should be run

proc processSwitch*(pass: TCmdLinePass; p: OptParser) =
proc processSwitch*(pass: TCmdLinePass; p: OptParser; config: ConfigRef) =
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
# we fix this here
var bracketLe = strutils.find(p.key, '[')
if bracketLe >= 0:
var key = substr(p.key, 0, bracketLe - 1)
var val = substr(p.key, bracketLe + 1) & ':' & p.val
processSwitch(key, val, pass, gCmdLineInfo)
processSwitch(key, val, pass, gCmdLineInfo, config)
else:
processSwitch(p.key, p.val, pass, gCmdLineInfo)
processSwitch(p.key, p.val, pass, gCmdLineInfo, config)

proc processArgument*(pass: TCmdLinePass; p: OptParser;
argsCount: var int): bool =
argsCount: var int; config: ConfigRef): bool =
if argsCount == 0:
# nim filename.nims is the same as "nim e filename.nims":
if p.key.endswith(".nims"):
options.command = "e"
options.gProjectName = unixToNativePath(p.key)
arguments = cmdLineRest(p)
config.arguments = cmdLineRest(p)
result = true
elif pass != passCmd2:
options.command = p.key
Expand All @@ -755,6 +761,6 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
if argsCount == 1:
# support UNIX style filenames everywhere for portable build scripts:
options.gProjectName = unixToNativePath(p.key)
arguments = cmdLineRest(p)
config.arguments = cmdLineRest(p)
result = true
inc argsCount
3 changes: 2 additions & 1 deletion compiler/extccomp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,9 @@ proc execExternalProgram*(cmd: string, msg = hintExecuting) =

proc generateScript(projectFile: string, script: Rope) =
let (dir, name, ext) = splitFile(projectFile)
writeRope(script, dir / addFileExt("compile_" & name,
writeRope(script, getNimcacheDir() / addFileExt("compile_" & name,
platform.OS[targetOS].scriptExt))
copyFile(libpath / "nimbase.h", getNimcacheDir() / "nimbase.h")

proc getOptSpeed(c: TSystemCC): string =
result = getConfigVar(c, ".options.speed")
Expand Down
10 changes: 5 additions & 5 deletions compiler/nim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
writeCommandLineUsage()
else:
# Process command line arguments:
processCmdLine(passCmd1, "")
processCmdLine(passCmd1, "", config)
if gProjectName == "-":
gProjectName = "stdinfile"
gProjectFull = "stdinfile"
Expand Down Expand Up @@ -71,7 +71,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
# now process command line arguments again, because some options in the
# command line can overwite the config file's settings
extccomp.initVars()
processCmdLine(passCmd2, "")
processCmdLine(passCmd2, "", config)
if options.command == "":
rawMessage(errNoCommand, command)
mainCommand(newModuleGraph(config), cache)
Expand All @@ -80,7 +80,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
if msgs.gErrorCounter == 0:
when hasTinyCBackend:
if gCmd == cmdRun:
tccgen.run(commands.arguments)
tccgen.run(config.arguments)
if optRun in gGlobalOptions:
if gCmd == cmdCompileToJS:
var ex: string
Expand All @@ -89,7 +89,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
else:
ex = quoteShell(
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
execExternalProgram(findNodeJs() & " " & ex & ' ' & commands.arguments)
execExternalProgram(findNodeJs() & " " & ex & ' ' & config.arguments)
else:
var binPath: string
if options.outFile.len > 0:
Expand All @@ -99,7 +99,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
# Figure out ourselves a valid binary name.
binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir
var ex = quoteShell(binPath)
execExternalProgram(ex & ' ' & commands.arguments)
execExternalProgram(ex & ' ' & config.arguments)

when declared(GC_setMaxPause):
GC_setMaxPause 2_000
Expand Down
4 changes: 0 additions & 4 deletions compiler/nimconf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,6 @@ proc loadConfigs*(cfg: string; cache: IdentCache; config: ConfigRef = nil) =
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
if not fileExists(projectConfig):
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
if not fileExists(projectConfig):
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
if fileExists(projectConfig):
rawMessage(warnDeprecated, projectConfig)
readConfigFile(projectConfig, cache, config)

proc loadConfigs*(cfg: string; config: ConfigRef = nil) =
Expand Down
19 changes: 15 additions & 4 deletions compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ type # please make sure we have under 32 options

TOptions* = set[TOption]
TGlobalOption* = enum # **keep binary compatible**
gloptNone, optForceFullMake, optDeadCodeElim,
gloptNone, optForceFullMake,
optDeadCodeElimUnused, # deprecated, always on
optListCmd, optCompileOnly, optNoLinking,
optCDebug, # turn on debugging information
optGenDynLib, # generate a dynamic library
Expand Down Expand Up @@ -102,13 +103,25 @@ type
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
ideHighlight, ideOutline, ideKnown, ideMsg

Feature* = enum ## experimental features
implicitDeref,
dotOperators,
callOperator,
parallel,
destructor

ConfigRef* = ref object ## eventually all global configuration should be moved here
cppDefines*: HashSet[string]
headerFile*: string
features*: set[Feature]
arguments*: string ## the arguments to be passed to the program that
## should be run

const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel}

proc newConfigRef*(): ConfigRef =
result = ConfigRef(cppDefines: initSet[string](),
headerFile: "")
headerFile: "", features: {})

proc cppDefine*(c: ConfigRef; define: string) =
c.cppDefines.incl define
Expand Down Expand Up @@ -145,8 +158,6 @@ var
gListFullPaths*: bool
gPreciseStack*: bool = false
gNoNimblePath* = false
gExperimentalMode*: bool
newDestructors*: bool
gDynlibOverrideAll*: bool
useNimNamespace*: bool

Expand Down
2 changes: 1 addition & 1 deletion compiler/passes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
p: TParsers
a: TPassContextArray
s: PLLStream
fileIdx = FileIndex module.fileIdx
fileIdx = module.fileIdx
if module.id < 0:
# new module caching mechanism:
for i in 0..<gPassesLen:
Expand Down
Loading

0 comments on commit 3949c9f

Please sign in to comment.