summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/vm.nim8
-rw-r--r--compiler/vmdef.nim1
-rw-r--r--compiler/vmgen.nim1
-rw-r--r--lib/core/macros.nim4
-rw-r--r--tests/macros/tgetimpl.nim20
-rw-r--r--todo.txt1
-rw-r--r--web/news.txt4
8 files changed, 39 insertions, 2 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 3a4158204..a0a5d204a 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -602,7 +602,7 @@ type
     mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo,
     mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr,
     mNBindSym, mLocals, mNCallSite,
-    mEqIdent, mEqNimrodNode, mSameNodeType,
+    mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl,
     mNHint, mNWarning, mNError,
     mInstantiationInfo, mGetTypeInfo, mNGenSym
 
diff --git a/compiler/vm.nim b/compiler/vm.nim
index b15c55565..b7b09f4a3 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -781,6 +781,14 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
         regs[ra].node.add(copyTree(regs[rb].regToNode))
       else:
         stackTrace(c, tos, pc, errNilAccess)
+    of opcGetImpl:
+      decodeB(rkNode)
+      let a = regs[rb].node
+      if a.kind == nkSym:
+        regs[ra].node = if a.sym.ast.isNil: newNode(nkNilLit)
+                        else: copyTree(a.sym.ast)
+      else:
+        stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
     of opcEcho:
       let rb = instr.regB
       if rb == 1:
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 6900b17c2..337e4ec8f 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -102,6 +102,7 @@ type
     opcEqIdent,
     opcStrToIdent,
     opcIdentToStr,
+    opcGetImpl,
 
     opcEcho,
     opcIndCall, # dest = call regStart, n; where regStart = fn, arg1, ...
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 919c38e08..237a44e18 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -948,6 +948,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
   of mSlurp: genUnaryABC(c, n, dest, opcSlurp)
   of mStaticExec: genBinaryABCD(c, n, dest, opcGorge)
   of mNLen: genUnaryABI(c, n, dest, opcLenSeq)
+  of mGetImpl: genUnaryABC(c, n, dest, opcGetImpl)
   of mNChild: genBinaryABC(c, n, dest, opcNChild)
   of mNSetChild, mNDel:
     unused(n, dest)
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index d371a92cf..2058229a1 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -213,6 +213,10 @@ proc newNimNode*(kind: NimNodeKind,
 proc copyNimNode*(n: NimNode): NimNode {.magic: "NCopyNimNode", noSideEffect.}
 proc copyNimTree*(n: NimNode): NimNode {.magic: "NCopyNimTree", noSideEffect.}
 
+proc getImpl*(s: NimSym): NimNode {.magic: "GetImpl", noSideEffect.}
+  ## retrieve the implementation of a symbol `s`. `s` can be a routine or a
+  ## const.
+
 proc error*(msg: string) {.magic: "NError", benign.}
   ## writes an error message at compile time
 
diff --git a/tests/macros/tgetimpl.nim b/tests/macros/tgetimpl.nim
new file mode 100644
index 000000000..d38492934
--- /dev/null
+++ b/tests/macros/tgetimpl.nim
@@ -0,0 +1,20 @@
+discard """
+  msg: '''"muhaha"
+proc poo(x, y: int) =
+  echo ["poo"]'''
+"""
+
+import macros
+
+const
+  foo = "muhaha"
+
+proc poo(x, y: int) =
+  echo "poo"
+
+macro m(x: typed): untyped =
+  echo repr x.symbol.getImpl
+  result = x
+
+discard m foo
+discard m poo
diff --git a/todo.txt b/todo.txt
index 3089dfbbe..37e82e230 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,7 +2,6 @@ version 0.11.4
 ==============
 
 - make tuple unpacking work in a non-var/let context
-- built-in 'getImpl'
 
 - document special cased varargs[untyped] and varargs[typed]
 
diff --git a/web/news.txt b/web/news.txt
index c93bb821f..fce77a0bf 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -61,6 +61,7 @@ News
   - The ``expandSymlink`` proc has been added to the ``os`` module.
   - The ``tailDir`` proc has been added to the ``os`` module.
 
+
   Language Additions
   ------------------
 
@@ -68,6 +69,9 @@ News
     variable or parameter for C interoperability. Since technically this
     makes parameters and ``let`` variables mutable, it is considered even more
     unsafe than the ordinary ``addr`` builtin.
+  - Added ``macros.getImpl`` that can be used to access the implementation of
+    a routine or a constant. This allows for example for user-defined inlining
+    of function calls.
 
 
   Bugfixes