summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/condsyms.nim11
-rw-r--r--compiler/options.nim2
-rw-r--r--compiler/pragmas.nim4
-rw-r--r--compiler/semfold.nim12
-rw-r--r--compiler/wordrecg.nim5
-rw-r--r--doc/manual.rst6
-rw-r--r--lib/pure/strtabs.nim28
-rw-r--r--tests/misc/tdefine.nim18
9 files changed, 71 insertions, 17 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index fc470b7a8..3146722cb 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -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
 
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 9a4c1701c..5e7ce3a08 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -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:
diff --git a/compiler/options.nim b/compiler/options.nim
index 54276f99d..0a25b1b96 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -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:
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 3967fa22d..03c9127af 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -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)
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 0bdd0b64c..2a2942191 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -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:
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 41bdc9fcb..6f78c9d6f 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -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",
 
diff --git a/doc/manual.rst b/doc/manual.rst
index 170f0d550..bcb1581dd 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -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
 ------------------
diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim
index 7bafe1675..cff5293c9 100644
--- a/lib/pure/strtabs.nim
+++ b/lib/pure/strtabs.nim
@@ -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:
diff --git a/tests/misc/tdefine.nim b/tests/misc/tdefine.nim
new file mode 100644
index 000000000..1378b8901
--- /dev/null
+++ b/tests/misc/tdefine.nim
@@ -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"