summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/manual.rst28
-rw-r--r--doc/manual_experimental.rst72
2 files changed, 83 insertions, 17 deletions
diff --git a/doc/manual.rst b/doc/manual.rst
index 4eabd0225..2469a0525 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -7781,9 +7781,10 @@ More examples with custom pragmas:
 Macro pragmas
 -------------
 
-All macros and templates can also be used as pragmas. They can be attached
-to routines (procs, iterators, etc), type names, or type expressions. The
-compiler will perform the following simple syntactic transformations:
+Macros and templates can sometimes be called with the pragma syntax. Cases
+where this is possible include when attached to routine (procs, iterators, etc)
+declarations or routine type expressions. The compiler will perform the
+following simple syntactic transformations:
 
 .. code-block:: nim
   template command(name: string, def: untyped) = discard
@@ -7810,20 +7811,15 @@ This is translated to:
 
 ------
 
-.. code-block:: nim
-  type
-    MyObject {.schema: "schema.protobuf".} = object
-
-This is translated to a call to the `schema` macro with a `nnkTypeDef`
-AST node capturing both the left-hand side and right-hand side of the
-definition. The macro can return a potentially modified `nnkTypeDef` tree
-or multiple `nnkTypeDef` trees contained in a `nnkTypeSection` node
-which will replace the original row in the type section.
-
-When multiple macro pragmas are applied to the same definition, the
-compiler will apply them consequently from left to right. Each macro
-will receive as input the output of the previous one.
+When multiple macro pragmas are applied to the same definition, the first one
+from left to right will be evaluated. This macro can then choose to keep
+the remaining macro pragmas in its output, and those will be evaluated in
+the same way.
 
+There are a few more applications of macro pragmas, such as in type,
+variable and constant declarations, but this behavior is considered to be
+experimental and is documented in the `experimental manual
+<manual_experimental.html#extended-macro-pragmas>` instead.
 
 
 Foreign function interface
diff --git a/doc/manual_experimental.rst b/doc/manual_experimental.rst
index 407924a13..3089755cb 100644
--- a/doc/manual_experimental.rst
+++ b/doc/manual_experimental.rst
@@ -404,6 +404,76 @@ to use this operator.
     doAssert (a.b)(c) == `()`(a.b, c)
 
 
+Extended macro pragmas
+======================
+
+Macro pragmas as described in `the manual <manual.html#userminusdefined-pragmas-macro-pragmas>`_
+can also be applied to type, variable and constant declarations.
+
+For types:
+
+.. code-block:: nim
+  type
+    MyObject {.schema: "schema.protobuf".} = object
+
+This is translated to a call to the `schema` macro with a `nnkTypeDef`
+AST node capturing the left-hand side, remaining pragmas and the right-hand
+side of the definition. The macro can return either a type section or
+another `nnkTypeDef` node, both of which will replace the original row
+in the type section.
+
+In the future, this `nnkTypeDef` argument may be replaced with a unary
+type section node containing the type definition, or some other node that may
+be more convenient to work with. The ability to return nodes other than type
+definitions may also be supported, however currently this is not convenient
+when dealing with mutual type recursion. For now, macros can return an unused
+type definition where the right-hand node is of kind `nnkStmtListType`.
+Declarations in this node will be attached to the same scope as
+the parent scope of the type section.
+
+------
+
+For variables and constants, it is largely the same, except a unary node with
+the same kind as the section containing a single definition is passed to macros,
+and macros can return any expression.
+
+.. code-block:: nim
+  var
+    a = ...
+    b {.importc, foo, nodecl.} = ...
+    c = ...
+
+Assuming `foo` is a macro or a template, this is roughly equivalent to:
+
+.. code-block:: nim
+  var a = ...
+  foo:
+    var b {.importc, nodecl.} = ...
+  var c = ...
+
+
+Symbols as template/macro calls
+===============================
+
+Templates and macros that take no arguments can be called as lone symbols,
+i.e. without parentheses. This is useful for repeated uses of complex
+expressions that cannot conveniently be represented as runtime values.
+
+.. code-block:: nim
+  type Foo = object
+    bar: int
+  
+  var foo = Foo(bar: 10)
+  template bar: untyped = foo.bar
+  assert bar == 10
+  bar = 15
+  assert bar == 15
+
+In the future, this may require more specific information on template or macro
+signatures to be used. Specializations for some applications of this may also
+be introduced to guarantee consistency and circumvent bugs.
+
+
 Not nil annotation
 ==================
 
@@ -613,7 +683,7 @@ has `source` as the owner. A path expression `e` is defined recursively:
 
 If a view type is used as a return type, the location must borrow from a location
 that is derived from the first parameter that is passed to the proc.
-See `the manual <https://nim-lang.org/docs/manual.html#procedures-var-return-type>`_
+See `the manual <manual.html#procedures-var-return-type>`_
 for details about how this is done for `var T`.
 
 A mutable view can borrow from a mutable location, an immutable view can borrow