macro manual improvements (#7666)

* macro manual improvements

* fixes a typo

* Small fixes
This commit is contained in:
Arne Döring 2018-04-21 08:15:41 +02:00 • committed by Andreas Rumpf
commit 516ce73066

View file

@ -5241,15 +5241,21 @@ chance to convert it into a sequence.
Macros Macros
====== ======
A macro is a special kind of low level template. Macros can be used A macro is a special function that is executed at compile-time.
to implement `domain specific languages`:idx:. Normally the input for a macro is an abstract syntax
tree (AST) of the code that is passed to it. The macro can then do
transformations on it and return the transformed AST. The
transformed AST is then passed to the compiler as if the macro
invocation would have been replaced by its result in the source
code. This can be used to implement `domain specific
languages`:idx:.
While macros enable advanced compile-time code transformations, they While macros enable advanced compile-time code transformations, they
cannot change Nim's syntax. However, this is no real restriction because cannot change Nim's syntax. However, this is no real restriction because
Nim's syntax is flexible enough anyway. Nim's syntax is flexible enough anyway.
To write macros, one needs to know how the Nim concrete syntax is converted To write macros, one needs to know how the Nim concrete syntax is converted
to an abstract syntax tree. to an AST.
There are two ways to invoke a macro: There are two ways to invoke a macro:
(1) invoking a macro like a procedure call (`expression macros`) (1) invoking a macro like a procedure call (`expression macros`)
@ -5269,19 +5275,21 @@ variable number of arguments:
# ``macros`` module: # ``macros`` module:
import macros import macros
macro debug(n: varargs[untyped]): untyped = macro debug(args: varargs[untyped]): untyped =
# `n` is a Nim AST that contains the whole macro invocation # `args` is a collection of `NimNode` values that each contain the
# this macro returns a list of statements: # AST for an argument of the macro. A macro always has to
result = newNimNode(nnkStmtList, n) # return a `NimNode`. A node of kind `nnkStmtList` is suitable for
# this use case.
result = nnkStmtList.newTree()
# iterate over any argument that is passed to this macro: # iterate over any argument that is passed to this macro:
for i in 0..n.len-1: for n in args:
# add a call to the statement list that writes the expression; # add a call to the statement list that writes the expression;
# `toStrLit` converts an AST to its string representation: # `toStrLit` converts an AST to its string representation:
add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i]))) result.add newCall("write", newIdentNode("stdout"), newLit(n.repr))
# add a call to the statement list that writes ": " # add a call to the statement list that writes ": "
add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) result.add newCall("write", newIdentNode("stdout"), newLit(": "))
# add a call to the statement list that writes the expressions value: # add a call to the statement list that writes the expressions value:
add(result, newCall("writeLine", newIdentNode("stdout"), n[i])) result.add newCall("writeLine", newIdentNode("stdout"), n)
var var
a: array[0..10, int] a: array[0..10, int]
@ -8187,5 +8195,3 @@ validation errors:
If the taint mode is turned off, ``TaintedString`` is simply an alias for If the taint mode is turned off, ``TaintedString`` is simply an alias for
``string``. ``string``.