Макеты ракеток - создание пар - PullRequest
2 голосов
/ 25 марта 2012

Я только начал погружаться в макросы Racket и пытаюсь создать краткий макрос, определяющий простые макросы.Я хотел бы расширить выражение следующим образом:

(macro id
    (param) replacement1
    (params ...) replacement2)

примерно так:

(define-syntax id
    (syntax-rules ()
        ((id param) replacement1)
        ((id params ...) replacement2)))

Таким образом, cddr исходного выражения превращается в пары выражений (для использования втело правил синтаксиса), и идентификатор вставляется в машину каждой из этих пар.

У меня возникают проблемы с рекурсивным мышлением, когда я использую только сопоставление с образцом, предусмотренное правилами синтаксиса (я продолжаю хотетьманипулировать выражением, как будто это обычный список).Какой тип шаблона я должен использовать?Или я могу как-то манипулировать им как обычным списком, а затем заключить в кавычки результат для использования в расширении?

Большое спасибо

Правка - предварительное решение, основанное на ответе Таймона

Частично мое любопытство было связано с тем, чтобы избавиться от этих парных скобок.Я изучил синтаксис-кейс, но немного запутался, поэтому попытался сделать это исключительно с помощью языка соответствия шаблону.Я закончил тем, что использовал макрос Теймона в сочетании с другим макросом для «паиризации» заданных шаблонов (он действует как функция аккумулятора):

(define-syntax-rule (macro-aux id ((param ...) expr) ...)
  (define-syntax id
    (syntax-rules ()
      ((id param ...) expr)
      ...)))

(define-syntax pairize
  (syntax-rules ()
   ((pairize id (pairs ...) p b) (macro-aux id pairs ... (p b)))
   ((pairize id (pairs ...) p b rest ...) (pairize id (pairs ... (p b)) rest ...))))

(define-syntax macro
  (syntax-rules ()
    ((macro id tpl-expr ...) (pairize id () tpl-expr ...))))

Ответы [ 2 ]

6 голосов
/ 25 марта 2012

Можно построить макроэкспандер, который манипулирует синтаксическим выражением как обычные данные Racket. Однако в этом случае это не обязательно.

Я бы порекомендовал немного изменить синтаксис, чтобы каждая пара замены шаблона заключалась в скобки. Как это:

(macro id
  [(param) replacement1]
  [(params ...) replacement2])

Как только это будет сделано, вы можете просто использовать обычный макрос сопоставления с образцом. Вот мой взгляд на это:

(define-syntax-rule (macro id [(param ...) replacement] ...)
  (define-syntax id
    (syntax-rules ()
      [(id param ...) replacement] ...)))
1 голос
/ 05 ноября 2015

Таймон прав, но это также возможно сделать с эллипсами без , заключив пары замены шаблона в скобки, используя ~seq из syntax/parse:

(require syntax/parse/define)
(define-simple-macro (macro id (~seq (param ...) replacement) ...)
  (define-syntax id
    (syntax-rules ()
      [(id param ...) replacement] ...)))

Который можно использовать так, как вы изначально хотели:

(macro id
  (param) replacement1
  (params ...) replacement2)
...