Hi, Juan Carlos.
Your example was of great help, indeed. I wrote a small macro based on it.
Please, take a look and let me know where it can be improved:
import macros
macro iter(i:untyped, c1:untyped,
c2:untyped, stm:untyped): untyped =
result = newNimNode(nnkStmtList) # Genera un result vacio.
var mi_bucle_for=
newNimNode(nnkForStmt) # Genera un bucle for vacio.
mi_bucle_for.add(i) # Usa indice en el bucle para la iteration.
var rango_para_iterar =
newNimNode(nnkInfix).add(ident("..")).add(c1,c2) # range.
let spc= newLit("- ")
var mi_echo = newCall(ident("write"),ident("stdout"), i, spc)
var stmList= newNimNode(nnkStmtList)
stmList.add(mi_echo)
for s in stm: stmList.add(s)
mi_bucle_for.add(rango_para_iterar) # Mete range para ite.
mi_bucle_for.add(stmList)
result.add(mi_bucle_for) # Mete el bucle for en el result.
iter(i, 0, 3):
echo "Hello, world."
echo "End"
Run
I guess Nim has a method of creating an nnkStmtList already initialized with
mi_echo, but I could not find it in the documentation. I suppose that I can
also add the stm list to mi_bucle_for without using the for s in stm:
stmList.add(s) statement.
I am waiting for your feedback. My opinion is that macro writing in Nim is much
harder than in Lisp. The same macro in Lisp:
(defmacro itr(ixx c1xx c2xx &rest body)
`(loop for ,ixx from ,c1xx to ,c2xx do
(format t "~a- " ,ixx) ,@body))
(itr i 0 3 (format t "Hello, world~%")
(format t "End~%"))
Run
Since writing macros in Nim is less intuitive than in Lisp, I believe that a
Nim macro tutorial must cover all the NimNode constructors with small examples
for everything. I hope to keep counting on your help for this task.