¿Cómo envolver y ejecutar una expresión s lisp por otra expresión s?

Traté de ajustar una expresión lisp por otra expresión lisp. Supongo que una macro debería hacerlo, pero no entiendo el truco. ¿Puede alguien ayudarme, quién sabe cómo hacerlo?

Mi objetivo real es escribir una macro que envuelva un lote dewith-open-file expresiones alrededor de algún código de macro-cuerpo.

(Quiero escribir un script / programa, que abre uno o dos archivos de entrada, procesarlos línea por línea, pero también genera el resultado del procesamiento en varios archivos de salida independientes diferentes. Por eso me encantaría tener elwith-open-file llamadas macro apiladas alrededor del código que procesa y escribe en los archivos de salida independientes, todo abierto para el código del cuerpo macro).

Desde elwith-open-file requiere un símbolo (controlador) para la secuencia de entrada o salida y la variable de ruta al archivo de salida (o entrada), y alguna información adicional (dirección del archivo, etc.), quiero ponerlos en listas.

;; Output file-paths:
(defparameter *paths* '("~/out1.lisp" "~/out2.lisp" "~/out3.lisp"))

;; stream handlers (symbols for the output streams)
(defparameter *handlers* '(out1 out2 out3))

;; code which I would love to execute in the body
(print "something1" out1)
(print "something2" out2)
(print "something3" out3)

Cómo me gustaría que se llamara la macro:

(with-open-files (*handlers* *paths* '(:direction :output :if-exists :append))
  ;; the third macro argument should be what should be passed to the
  ;; individual `with-open-file` calls
  ;; and it might be without `quote`-ing or with `quote`-ing
  ;; - is there by the way a good-practice for such cases? -
  ;; - is it recommended to have `quote`-ing? Or how would you do that? -
  ;; and then follows the code which should be in the macro body:
  (print "something1" out1)
  (print "something2" out2)
  (print "something3" out3))

A lo que debería expandirse la llamada macro:

(with-open-file (out1 "~/out1.lisp" :direction :output :if-exists :append)
  (with-open-file (out2 "~/out2.lisp" :direction :output :if-exists :append)
    (with-open-file (out3 "~/out3.lisp" :direction :output :if-exists :append)
      (print "something1" out1)
      (print "something2" out2)
      (print "something3" out3))))

omo un paso, pensé que tenía que hacer que una expresión-s envolviera otra expresión-s.

Mi primera pregunta fue: ¿Cómo envolver una expresión-s con otra expresión-s? Pero simplemente no podía manejarlo en este momento. Todo lo que pude hacer fue escribir una función que simplemente derrame una expresión no ejecutada. ¿Cómo escribir una macro que haga lo mismo pero también ejecute el código después de expandirlo de esta manera?

(defun wrap (s-expr-1 s-expr-2)
  (append s-expr-1 (list s-expr-2)))

(wrap '(func1 arg1) '(func2 arg2))
;; => (FUNC1 ARG1 (FUNC2 ARG2))

(wrap '(with-open-files (out1 "~/out1.lisp" :direction :output :if-exists :append))
  '(with-open-files (out2 "~/out2.lisp" :direction :output :if-exists :append) 
      (print "something1" out1)
      (print "something2" out2)
      (print "something3" out3)))

Lo que da

(WITH-OPEN-FILES (OUT1 "~/out1.lisp" :DIRECTION :OUTPUT :IF-EXISTS :APPEND)
 (WITH-OPEN-FILES (OUT2 "~/out2.lisp" :DIRECTION :OUTPUT :IF-EXISTS :APPEND)
  (PRINT "something1" OUT1) 
  (PRINT "something2" OUT2)
  (PRINT "something3" OUT3)))

De esta manera, aplicandowrap funciona sucesivamente, recorriendo las listas de entrada, podría construir el código tal vez ...

Sin embargo, estas funciones generarían solo código pero no lo ejecutarían. Y al final me vería obligado a usar laeval función para evaluar el código construido ... (Pero de alguna manera sé que esto no debería hacerse así. Y realmente no entendí cómo escribir macros que hacen tales cosas ... En realidad, las macros están ahí para resolver exactamente tales problemas ...)

Con la ejecución, acabo de tener grandes problemas. Y como no se puede llamar afuncall oapply en macros (en lugar de nombres de funciones) No veo una solución obvia. ¿Alguien tenía experiencia con ese tipo de situaciones?

Y cuando se logra envolver una expresión-s en una macro por otra expresión-s y dejar que se evalúe, la siguiente pregunta sería, ¿cómo procesar la lista para permitir que el código se expanda al código deseado y luego ser evaluado? Solo intenté horas y no llegué lejos.

Necesito ayuda de alguien que tenga experiencia para escribir este tipo de macros ...

Respuestas a la pregunta(1)

Su respuesta a la pregunta