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.

Reply via email to