summary refs log tree commit diff stats
path: root/lib/std
diff options
context:
space:
mode:
authormetagn <10591326+metagn@users.noreply.github.com>2022-01-20 22:57:50 +0300
committerGitHub <noreply@github.com>2022-01-20 20:57:50 +0100
commit2bd1aa186e09565b2103394bd281478fa1b10ef1 (patch)
tree3c1d9b68565f1c2f98fb3691fc4da1a81045460f /lib/std
parent1563cb2f6e37f07c303d095dabde74955be1e523 (diff)
downloadNim-2bd1aa186e09565b2103394bd281478fa1b10ef1.tar.gz
New/better macro pragmas, mark some as experimental (#19406)
* New/better macro pragmas, make some experimental

fix #15920, close #18212, close #14781, close #6696,
close https://github.com/nim-lang/RFCs/issues/220

Variable macro pragmas have been changed to
only take a unary section node.
They can now also be applied in sections with multiple variables,
as well as `const` sections. They also accept arguments.

Templates now support macro pragmas, mirroring other routine types.

Type and variable macro pragmas have been made experimental.
Symbols without parentheses instatiating nullary macros or templates
has also been documented in the experimental manual.

A check for a redefinition error based on the left hand side of variable
definitions when using variable macro pragmas was disabled.
This nerfs `byaddr` specifically, however this has been documented as
a consequence of the experimental features `byaddr` uses.

Given how simple these changes are I'm worried if I'm missing something.

* accomodate compiler boot

* allow weird pragmas

* add test for #10994

* remove some control flow, try remove some logic
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/decls.nim39
1 files changed, 26 insertions, 13 deletions
diff --git a/lib/std/decls.nim b/lib/std/decls.nim
index dd7d19da7..7b907f5e1 100644
--- a/lib/std/decls.nim
+++ b/lib/std/decls.nim
@@ -1,19 +1,32 @@
 # see `semLowerLetVarCustomPragma` for compiler support that enables these
 # lowerings
 
-template byaddr*(lhs, typ, ex) =
-  ## Allows a syntax for lvalue reference, exact analog to
-  ## `auto& a = ex;` in C++
+import macros
+
+macro byaddr*(sect) =
+  ## Allows a syntax for l-value references, being an exact analog to
+  ## `auto& a = ex;` in C++.
+  ## 
+  ## Warning: This makes use of 2 experimental features, namely nullary
+  ## templates instantiated as symbols and variable macro pragmas.
+  ## For this reason, its behavior is not stable. The current implementation
+  ## allows redefinition, but this is not an intended consequence.
   runnableExamples:
-    var s = @[10,11,12]
+    var s = @[10, 11, 12]
     var a {.byaddr.} = s[0]
-    a+=100
-    doAssert s == @[110,11,12]
-    doAssert a is int
+    a += 100
+    assert s == @[110, 11, 12]
+    assert a is int
     var b {.byaddr.}: int = s[0]
-    doAssert a.addr == b.addr
-  when typ is typeof(nil):
-    let tmp = addr(ex)
-  else:
-    let tmp: ptr typ = addr(ex)
-  template lhs: untyped = tmp[]
+    assert a.addr == b.addr
+  expectLen sect, 1
+  let def = sect[0]
+  let
+    lhs = def[0]
+    typ = def[1]
+    ex = def[2]
+    addrTyp = if typ.kind == nnkEmpty: typ else: newTree(nnkPtrTy, typ)
+  result = quote do:
+    let tmp: `addrTyp` = addr(`ex`)
+    template `lhs`: untyped = tmp[]
+  result.copyLineInfo(def)