summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md2
-rw-r--r--lib/core/macros.nim16
-rw-r--r--tests/macros/tmacro1.nim14
3 files changed, 31 insertions, 1 deletions
diff --git a/changelog.md b/changelog.md
index 1f2655d7a..9a5671757 100644
--- a/changelog.md
+++ b/changelog.md
@@ -25,6 +25,8 @@
 - Added `split`, `splitWhitespace`, `size`, `alignLeft`, `align`,
   `strip`, `repeat` procs and iterators to `unicode.nim`.
 
+- Added `or` for `NimNode` in `macros`.
+
 ### Library changes
 
 
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 2b0d74e6a..79195966e 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -176,6 +176,21 @@ proc `[]=`*(n: NimNode, i: BackwardsIndex, child: NimNode) =
   ## set `n`'s `i`'th child to `child`.
   n[n.len - i.int] = child
 
+template `or`*(x, y: NimNode): NimNode =
+  ## Evaluate ``x`` and when it is not an empty node, return
+  ## it. Otherwise evaluate to ``y``. Can be used to chain several
+  ## expressions to get the first expression that is not empty.
+  ##
+  ## .. code-block:: nim
+  ##
+  ##   let node = mightBeEmpty() or mightAlsoBeEmpty() or fallbackNode
+
+  let arg = x
+  if arg != nil and arg.kind != nnkEmpty:
+    arg
+  else:
+    y
+
 proc add*(father, child: NimNode): NimNode {.magic: "NAdd", discardable,
   noSideEffect, locks: 0.}
   ## Adds the `child` to the `father` node. Returns the
@@ -1433,4 +1448,3 @@ proc getProjectPath*(): string = discard
   ## Returns the path to the currently compiling project, not to
   ## be confused with ``system.currentSourcePath`` which returns
   ## the path of the current module.
-
diff --git a/tests/macros/tmacro1.nim b/tests/macros/tmacro1.nim
index ac2bf9094..5388e861c 100644
--- a/tests/macros/tmacro1.nim
+++ b/tests/macros/tmacro1.nim
@@ -79,3 +79,17 @@ static:
   assert fooSym.kind in {nnkOpenSymChoice, nnkClosedSymChoice}
   assert    fooSym.eqIdent("fOO")
   assertNot fooSym.eqIdent("bar")
+
+  var empty: NimNode
+  var myLit = newLit("str")
+
+  assert( (empty or myLit) == myLit )
+
+  empty = newEmptyNode()
+
+  assert( (empty or myLit) == myLit )
+
+  proc bottom(): NimNode =
+    quit("may not be evaluated")
+
+  assert( (myLit or bottom()) == myLit )