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
This commit is contained in:
parent
1563cb2f6e
commit
2bd1aa186e
8 changed files with 435 additions and 205 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue