Como quebrar e executar uma expressão s de lisp por outra expressão

Eu tentei quebrar uma expressão lisp por outra expressão lisp. Eu acho que uma macro deve fazer isso, mas eu não entendo o truque. Alguém pode me ajudar, quem sabe como fazer isso?

Meu objetivo real é escrever uma macro que envolva um lote dewith-open-filexpressões em torno de algum código de macro-corp

(Eu quero escrever um script / programa, que abra um ou dois arquivos de entrada, processe-os linha por linha, mas também produz o resultado do processamento em vários arquivos de saída independentes diferentes. Por isso, eu adoraria ter owith-open-filehamadas de macro empilhadas em torno do código que processa e grava nos arquivos de saída independentes - todos abertos para o código do corpo da macro

Desde owith-open-file requer um símbolo (manipulador) para o fluxo de entrada ou saída e a variável de caminho para o arquivo de saída (ou entrada) e algumas informações adicionais (direção do arquivo etc.), desejo colocá-las em 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)

Como eu adoraria que a macro fosse chamada:

(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))

Para o que a chamada de macro deve expandir:

(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))))

Como um passo, pensei em fazer uma expressão s envolver outra expressão s.

inha primeira pergunta foi:Como quebrar uma expressão s por outra expressão s? Mas eu simplesmente não conseguia gerenciá-lo neste momento. Tudo o que eu pude fazer foi escrever uma função que apenas expele uma expressão não executada. Como escrever uma macro que faz o mesmo, mas também executa o código após expandi-lo dessa maneir

(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)))

Que dá

(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)))

Desta forma, aplicandowrap funcionar sucessivamente, passando pelas listas de entrada, eu poderia criar o código talvez ...

No entanto, essas funções gerariam apenas código, mas não o executariam. E eu seria forçado no final a usar oeval função para avaliar o código criado ... (Mas de alguma forma eu sei que isso não deve ser feito assim. E eu realmente não entendi como escrever macros que fazem essas coisas ... Na verdade, as macros estão lá para resolver exatamente esses problemas ...)

Com a execução, acabei de ter um grande problema. E como não se pode chamarfuncall ouapply em macros (em vez de nomes de funções) não vejo uma solução óbvia. Alguém teve experiência com esse tipo de situação?

E quando concluir a quebra de uma expressão s em uma macro por outra expressão s e seja avaliado, a próxima pergunta seria: como processar a lista para permitir que o código se expanda para o código desejado e depois seja avaliado? Apenas tentei horas e não fui long

Preciso da ajuda de alguém com experiência para escrever esse tipo de macros ...

questionAnswers(1)

yourAnswerToTheQuestion