状態遷移2

「C'」とかのクォートが後ろについたシンボルを実現するためだけにリードマクロ(#[])を書くのはやっぱりやりすぎだった。素直に|C'|と書こう。

INTERP> (def-transitions secd-1 "secd machine sample 2."
          ;; initial state -> transformed state
          ( s e (:NIL . c) d                         -> (nil . s) e c d )
          ( s e (:LDC x . c) d                       -> (x . s) e c d )
          ( s e (:LD (m . n) . c) d                  -> (x . s) e c d where x = (locate m n e) )
          ( s e (:LDF |c'| . c) d                    -> ((|c'| . e) . s) e c d )
          ( (x . s) e (:SEL cT cF . c) d             -> s e cX (c . d) where cX = (if x cT cF) )
          ( s e (:JOIN . c) (cr . d)                 -> s e cr d )
          ( ((|c'| . |e'|) v . s) e (:AP . c) d      -> nil (v . |e'|) |c'| (s e c . d) )
          ( (a b . s) e (:CONS . c) d                -> ((a . b) . s) e c d )
          ( ((a . b) . s) e (:CAR . c) d             -> (a . s) e c d )
          ( ((a . b) . s) e (:CDR . c) d             -> (b . s) e c d )
          ( (x . z) |e'| (:RTN . |c'|) (s e c . d)   -> (x . s) e c d )
          ( (a b . s) e (:+ . c) d                   -> (x . s) e c d where x = (+ a b) )
          ( (a b . s) e (:- . c) d                   -> (x . s) e c d where x = (- a b) )
          ( (a b . s) e (:* . c) d                   -> (x . s) e c d where x = (* a b) )
          ( (a b . s) e (:= . c) d                   -> (x . s) e c d where x = (= a b) )
          ( (a b . s) e (:> . c) d                   -> (x . s) e c d where x = (> a b) )
          ( (a b . s) e (:< . c) d                   -> (x . s) e c d where x = (< a b) )
          )
SECD-1
INTERP>  (time (secd-1 's 'e (secd::compile-pass1
                             '(let ((Y (lambda (f)
                                         ((lambda (g)
                                            (f (lambda (arg) ((g g) arg))))
                                          (lambda (g)
                                            (f (lambda (arg) ((g g) arg))))))))
                               ((Y (lambda (f)
                                     (lambda (n)
                                       (if (< n 2)
                                           n
                                           (+ (f (- n 1)) (f (- n 2))))))) 27)) ()) 'd))
Evaluation took:
  3.874 seconds of real time
  3.833235 seconds of total run time (3.662237 user, 0.170998 system)
  [ Run times consist of 0.457 seconds GC time, and 3.377 seconds non-GC time. ]
  98.94% CPU
  11,818,810,291 processor cycles
  1,800,092,944 bytes consed
  
STOP
(196418 . S)

はっきりいって遅いインタプリタだけど、状態遷移と補助関数で定義されている。

メモ。scheme の #t, #f と CL の真偽値を混同しているので要修正。nil も怪しい。
locate は今は単なるCLの関数。これも注意。次に書くマクロは vm に対するマクロになる。


マクロの展開系。destructuring-bind に頼り過ぎでエラーチェックが甘い。マクロをいじってもうちょっとカッコよくしたいところだ。

(DEFUN SECD-1 (#:S1241 #:E1242 #:C1243 #:D1244)
  "secd machine sample 2."
  (IF (AND (CONSP #:C1243) (INSTRUCTION-P (CAR #:C1243)))
      (CASE (CAR #:C1243)
        (:NIL
         (DESTRUCTURING-BIND
               (S E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ()
             (SECD-1 (CONS NIL S) E C D))))
        (:LDC
         (DESTRUCTURING-BIND
               (S E (#:|insn1245| X . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ()
             (SECD-1 (CONS X S) E C D))))
        (:LD
         (DESTRUCTURING-BIND
               (S E (#:|insn1245| (M . N) . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((X (LOCATE M N E)))
             (SECD-1 (CONS X S) E C D))))
        (:LDF
         (DESTRUCTURING-BIND
               (S E (#:|insn1245| |c'| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ()
             (SECD-1 (CONS (CONS |c'| E) S) E C D))))
        (:SEL
         (DESTRUCTURING-BIND
               ((X . S) E (#:|insn1245| CT CF . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((CX
                  (IF X
                      CT
                      CF)))
             (SECD-1 S E CX (CONS C D)))))
        (:JOIN
         (DESTRUCTURING-BIND
               (S E (#:|insn1245| . C) (CR . D))
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (DECLARE (IGNORE C))
           (LET ()
             (SECD-1 S E CR D))))
        (:AP
         (DESTRUCTURING-BIND
               (((|c'| . |e'|) V . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ()
             (SECD-1 NIL (CONS V |e'|) |c'| (CONS S (CONS E (CONS C D)))))))
        (:CONS
         (DESTRUCTURING-BIND
               ((A B . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ()
             (SECD-1 (CONS (CONS A B) S) E C D))))
        (:CAR
         (DESTRUCTURING-BIND
               (((A . B) . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (DECLARE (IGNORE B))
           (LET ()
             (SECD-1 (CONS A S) E C D))))
        (:CDR
         (DESTRUCTURING-BIND
               (((A . B) . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (DECLARE (IGNORE A))
           (LET ()
             (SECD-1 (CONS B S) E C D))))
        (:RTN
         (DESTRUCTURING-BIND
               ((X . Z) |e'| (#:|insn1245| . |c'|) (S E C . D))
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (DECLARE (IGNORE Z))
           (DECLARE (IGNORE |e'|))
           (DECLARE (IGNORE |c'|))
           (LET ()
             (SECD-1 (CONS X S) E C D))))
        (:+
         (DESTRUCTURING-BIND
               ((A B . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((X (+ A B)))
             (SECD-1 (CONS X S) E C D))))
        (:-
         (DESTRUCTURING-BIND
               ((A B . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((X (- A B)))
             (SECD-1 (CONS X S) E C D))))
        (:*
         (DESTRUCTURING-BIND
               ((A B . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((X (* A B)))
             (SECD-1 (CONS X S) E C D))))
        (:=
         (DESTRUCTURING-BIND
               ((A B . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((X (= A B)))
             (SECD-1 (CONS X S) E C D))))
        (:>
         (DESTRUCTURING-BIND
               ((A B . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((X (> A B)))
             (SECD-1 (CONS X S) E C D))))
        (:<
         (DESTRUCTURING-BIND
               ((A B . S) E (#:|insn1245| . C) D)
             (LIST #:S1241 #:E1242 #:C1243 #:D1244)
           (DECLARE (IGNORE #:|insn1245|))
           (LET ((X (< A B)))
             (SECD-1 (CONS X S) E C D)))))
      (VALUES 'STOP #:S1241)))