Правила синтаксиса схемы, соответствующие любому количеству переменных шаблона перед литералом?

Я пытаюсь написать макрос, который заменяет некоторый литерал в выражении значением, например (substitute 3 (+ 4 1 _ 1 5))

Это то, что у меня есть до сих пор,

(define-syntax substitute
  (syntax-rules (_)
    ((substitute val (_ e1 ...))
     (val e1 ...))
    ((substitute val (e1 _ e2 ...))
     (e1 val e2 ...))
    ((substitute val (e1 e2 _ e3 ...))
     (e1 e2 val e3 ...))))

Как я могу это обобщить? Или действительно, как мне подойти к этому?

1 ответ

Хорошо, у меня есть решение.

(define-syntax sub-apply
  (syntax-rules ()
    ((sub-apply val (op e ...))
     (apply op
            (sub-list val (e ...))))))

(define-syntax sub-list
  (syntax-rules (_)
    ((sub-list val (_)) '(val))
    ((sub-list val (e)) '(e))
    ((sub-list val (_ e ...))
     (cons val (sub-list val (e ...))))
    ((sub-list val (e1 e2 ...))
     (cons e1 (sub-list val (e2 ...))))))

редактировать.
Это даже лучше! Работает со специальными конструкциями.

;; usage:
;; (undswap 3 _) => 3
;; (undswap 3 (if _ (+ 3 _ ))) => 6
(define-syntax undswap
  (syntax-rules (_)
    ((undswap val (e ...))
     ((undswap val e) ...))
    ((undswap val _) val)
    ((undswap val e) e)))
Другие вопросы по тегам