Схема перезаписи let * как вложенная унарная let - PullRequest
0 голосов
/ 25 февраля 2011

Я написал функцию match-rewriter, которая по существу match-lambda, за исключением того, что она возвращает свой аргумент, если совпадение не найдено:

(define-syntax match-rewriter
  (syntax-rules ()
    ((_ (patt body) ...)
      (λ (x) (match x (patt body) ... (_ x))))))

Теперь я хотел бы использоватьmatch-rewriter, чтобы взять строки, представляющие исходный код для let*, и переписать его как вложенный унарный lets:

(define let*→nested-unary-lets
  (match-rewriter (`(let*((,<var> ,<val>) ...) ,<expr1> ,<expr2> ...)

Я действительно озадачен тем, как сопоставить шаблон с этим.Мне нужно вернуть:

`(let((,<var1> ,<val1>)) let((,<var2> ,<val2>)) let((...)) ... )...) ,<expr1> . ,@<expr2>)

Но вложенность поставила меня в тупик.Любой совет приветствуется.


Хорошо, вот моя лучшая попытка:

(define let*→nested-unary-lets
  (match-rewriter
   (`(let* (()) ,<expr1> ,<expr2> ...)
   (`(let () ,<expr1> . ,<expr2>)))
   (`(let* ((,<var1> ,<val1>) (,<var2> ,<val2>) ...) ,<expr1> ,<expr2> ...)
    `(let ((,<var1> ,<val1>) (let*→nested-unary-lets 
                               '(let* ((,<var2> ,<val2>) ...) ,<expr1> . ,<expr2>)))))
   ))

Но вот как он себя ведет:

(пусть *→ nested-unary-let '(let * ((a 1) (b (+ a 1)) (c (+ ab))) (displayln c)))' (let ((a 1) (let * → nested-unary-let '(let * (((bc) ((+ a 1) (+ ab))) ...) (displayln c)))))

Я в замешательствепорядок аргументов в:

(let* (((b c) ((+ a 1) (+ a b)))

Мне кажется, это должно быть:

(let* ((b (+ a 1)) (c (+ a b)))

Также было бы неплохо, если бы вызов let*→nested-unary-lets выполнялся вместопросто печатать как текст.

Ответы [ 2 ]

2 голосов
/ 25 февраля 2011

Да, вы можете сделать это;это не должно быть слишком сложно.В частности, ключевая идея, которая вам здесь нужна, - не пытаться обрабатывать весь список сразу.Вместо этого ваши шаблоны должны отделить первую привязку от остальных, а затем обернуть одну строку вокруг рекурсивного вызова , чтобы позволить * -> nested-unary-let.есть проблемы с формулировкой этого.

2 голосов
/ 25 февраля 2011

Вот определение let* в syntax-rules -подобном псевдокоде, которое вы можете использовать для написания своей собственной версии:

(let* ((a b) (c d) ...) body ...) === (let ((a b)) (let* ((c d) ...) body ...))
(let* () body ...) === body

Вы должны быть в состоянии превратить это в функцию, используя match или макрос, используя syntax-rules.

...