マクロでtarai回し 4回目

さらに修正したら状態数がまた少し減った。あと地味にバグがあったのを直した。

(define-syntax tarai-r/o
  (syntax-rules ()
    ((_ 0 %x %y %z %k ...)
     (tarai-r/o "force" %x (tarai-r/o 1 %y %z) %k ...))

    ((_ 1 %y %z %x-value %k ...)
     (tarai-r/o "force" %y (tarai-r/o 2 %z %x-value) %k ...))

    ((_ 2 %z %x-value %y-value %k ...)
     (tarai-r/o "loop" %x-value %y-value %x-value %y-value %z %k ...))

    ((_ "loop" (%x1 %x2 ...) (%y1 %y2 ...) %x-value %y-value %z %k ...)
     (tarai-r/o "loop" (%x2 ...) (%y2 ...) %x-value %y-value %z %k ...))

    ((_ "loop" () (%y1 ...) %x-value %y-value %z %k ...)
     (tarai-r/o "return" %y-value %k ...))

    ((_ "loop" (%x1 %x2 ...) () %x-value %y-value %z %k ...)
     (tarai-r/o 0
                ("delay" (tarai-r/o 3 %x-value %y-value %z))
                ("delay" (tarai-r/o 3 %y-value %z %x-value))
                ("delay" (tarai-r/o 3 %z %x-value %y-value))
                %k ...))

    ((_ 3 %x %y %z %k ...)
     (tarai-r/o "force" %x (tarai-r/o 4 %y %z) %k ...))

    ((_ 4 %y %z (%x1 %x2 ...) %k ...)
     (tarai-r/o 0 (%x2 ...) %y %z %k ...))

    ((_ "force" ("delay" (%f ...)) %k ...)
     (%f ... %k ...))

    ((_ "force" %val %k ...)
     (tarai-r/o "return" %val %k ...))

    ((_ "return" %val)
     %val)

    ((_ "return" %val (%k1 ...) %k2 ...)
     (%k1 ... %val %k2 ...))

    ((_ %x %y %z)
     (tarai-r/o "loop" %x %y %x %y %z))

    ))

そろそろ完全形に近づいてきた。もう改善するところはないかな。

動作テスト

次のようなファイルを用意して(...には上に挙げた定義が入る)

#! /usr/bin/env gosh

(define-syntax tarai-r/o
 ...)

(define (main args)
  (display (macroexpand '(tarai-r/o (12 11 10 9 8 7 6 5 4 3 2 1) (6 5 4 3 2 1) (1))))
  (newline))
% time ./tarai-mac.scm
(12 11 10 9 8 7 6 5 4 3 2 1)

real    0m0.027s
user    0m0.020s
sys     0m0.006s

ということで、確かに遅延評価の効果はあったようだ。