Implement {.booldefine.} (#10533)

This commit is contained in:
Oscar Nihlgård
2019-02-03 09:06:00 +01:00
committed by Andreas Rumpf
parent 07553034de
commit 0091f2ad3b
9 changed files with 71 additions and 17 deletions

View File

@@ -655,7 +655,7 @@ type
mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl, mNGenSym,
mNHint, mNWarning, mNError,
mInstantiationInfo, mGetTypeInfo,
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
mNimvm, mIntDefine, mStrDefine, mBoolDefine, mRunnableExamples,
mException, mBuiltinType, mSymOwner, mUncheckedArray, mGetImplTransf,
mSymIsInstantiationOf

View File

@@ -15,26 +15,21 @@ import
from options import Feature
from lineinfos import HintsToStr, WarningsToStr
const
catNone = "false"
proc defineSymbol*(symbols: StringTableRef; symbol: string, value: string = "true") =
symbols[symbol] = value
proc undefSymbol*(symbols: StringTableRef; symbol: string) =
symbols[symbol] = catNone
symbols.del(symbol)
#proc lookupSymbol*(symbols: StringTableRef; symbol: string): string =
# result = if isDefined(symbol): gSymbols[symbol] else: nil
iterator definedSymbolNames*(symbols: StringTableRef): string =
for key, val in pairs(symbols):
if val != catNone: yield key
yield key
proc countDefinedSymbols*(symbols: StringTableRef): int =
result = 0
for key, val in pairs(symbols):
if val != catNone: inc(result)
symbols.len
proc initDefines*(symbols: StringTableRef) =
# for bootstrapping purposes and old code:

View File

@@ -360,7 +360,7 @@ proc cppDefine*(c: ConfigRef; define: string) =
proc isDefined*(conf: ConfigRef; symbol: string): bool =
if conf.symbols.hasKey(symbol):
result = conf.symbols[symbol] != "false"
result = true
elif cmpIgnoreStyle(symbol, CPU[conf.target.targetCPU].name) == 0:
result = true
elif cmpIgnoreStyle(symbol, platform.OS[conf.target.targetOS].name) == 0:

View File

@@ -67,7 +67,7 @@ const
wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims, wUsed}
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject, wExportNims,
wIntDefine, wStrDefine, wUsed, wCompilerProc, wCore}
wIntDefine, wStrDefine, wBoolDefine, wUsed, wCompilerProc, wCore}
letPragmas* = varPragmas
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect,
wThread, wRaises, wLocks, wTags, wGcSafe}
@@ -1106,6 +1106,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
sym.magic = mIntDefine
of wStrDefine:
sym.magic = mStrDefine
of wBoolDefine:
sym.magic = mBoolDefine
of wUsed:
noVal(c, it)
if sym == nil: invalidPragma(c, it)

View File

@@ -569,10 +569,20 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
try:
result = newIntNodeT(g.config.symbols[s.name.s].parseInt, n, g)
except ValueError:
localError(g.config, n.info, "expression is not an integer literal")
localError(g.config, s.info,
"{.intdefine.} const was set to an invalid integer: '" &
g.config.symbols[s.name.s] & "'")
of mStrDefine:
if isDefined(g.config, s.name.s):
result = newStrNodeT(g.config.symbols[s.name.s], n, g)
of mBoolDefine:
if isDefined(g.config, s.name.s):
try:
result = newIntNodeT(g.config.symbols[s.name.s].parseBool.int, n, g)
except ValueError:
localError(g.config, s.info,
"{.booldefine.} const was set to an invalid bool: '" &
g.config.symbols[s.name.s] & "'")
else:
result = copyTree(s.ast)
of skProc, skFunc, skMethod:

View File

@@ -35,7 +35,7 @@ type
wColon, wColonColon, wEquals, wDot, wDotDot,
wStar, wMinus,
wMagic, wThread, wFinal, wProfiler, wMemTracker, wObjChecks,
wIntDefine, wStrDefine,
wIntDefine, wStrDefine, wBoolDefine
wDestroy,
@@ -122,7 +122,8 @@ const
":", "::", "=", ".", "..",
"*", "-",
"magic", "thread", "final", "profiler", "memtracker", "objchecks", "intdefine", "strdefine",
"magic", "thread", "final", "profiler", "memtracker", "objchecks",
"intdefine", "strdefine", "booldefine",
"destroy",

View File

@@ -7851,6 +7851,7 @@ pragma description
================= ============================================
`intdefine`:idx: Reads in a build-time define as an integer
`strdefine`:idx: Reads in a build-time define as a string
`booldefine`:idx: Reads in a build-time define as a bool
================= ============================================
.. code-block:: nim
@@ -7858,13 +7859,14 @@ pragma description
echo FooBar
::
nim c -d:FooBar=42 foobar.c
nim c -d:FooBar=42 foobar.nim
In the above example, providing the -d flag causes the symbol
``FooBar`` to be overwritten at compile time, printing out 42. If the
``-d:FooBar=42`` were to be omitted, the default value of 5 would be
used.
used. To see if a value was provided, `defined(FooBar)` can be used.
The syntax `-d:flag` is actually just a shortcut for `-d:flag=true`.
Custom annotations
------------------

View File

@@ -28,7 +28,7 @@ runnableExamples:
## When using the style insensitive mode ``modeStyleInsensitive``,
## all letters are compared case insensitively within the ASCII range
## all letters are compared case insensitively within the ASCII range
## and underscores are ignored.
runnableExamples:
@@ -272,6 +272,32 @@ proc `%`*(f: string, t: StringTableRef, flags: set[FormatFlag] = {}): string {.
add(result, f[i])
inc(i)
proc del*(t: StringTableRef, key: string) =
## Removes `key` from `t`.
# Impl adapted from `tableimpl.delImplIdx`
var i = rawGet(t, key)
let msk = high(t.data)
if i >= 0:
dec(t.counter)
block outer:
while true: # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1
var j = i # The correctness of this depends on (h+1) in nextTry,
var r = j # though may be adaptable to other simple sequences.
t.data[i].hasValue = false # mark current EMPTY
t.data[i].key = ""
t.data[i].val = ""
while true:
i = (i + 1) and msk # increment mod table size
if not t.data[i].hasValue: # end of collision cluster; So all done
break outer
r = t.myhash(t.data[i].key) and msk # "home" location of key@i
if not ((i >= r and r > j) or (r > j and j > i) or (j > i and i >= r)):
break
when defined(js):
t.data[j] = t.data[i]
else:
shallowCopy(t.data[j], t.data[i]) # data[j] will be marked EMPTY next loop
proc `$`*(t: StringTableRef): string {.rtlFunc, extern: "nstDollar".} =
## The `$` operator for string tables.
if t.len == 0:

18
tests/misc/tdefine.nim Normal file
View File

@@ -0,0 +1,18 @@
discard """
joinable: false
cmd: "nim c -d:booldef -d:booldef2=false -d:intdef=2 -d:strdef=foobar -r $file"
"""
const booldef {.booldefine.} = false
const booldef2 {.booldefine.} = true
const intdef {.intdefine.} = 0
const strdef {.strdefine.} = ""
doAssert defined(booldef)
doAssert defined(booldef2)
doAssert defined(intdef)
doAssert defined(strdef)
doAssert booldef
doAssert not booldef2
doAssert intdef == 2
doAssert strdef == "foobar"