マクロ
データを定義して動くプログラムを書こうとしている。SECD マシンの状態遷移の定義が、そのままプログラムになるように。
実際は、SECD マシンのインタプリタなら、そのまま手で書いた方が簡単な位だけど。
INTERP> (def-transitions secd-1 ;; 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 (:LDF c' . c) d -> ((c' . e) . s) e c 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) ] ) SECD-1 INTERP> (secd-1 's 'e (secd.compile::compile-pass1 '((lambda () (* (+ 3 4) 7))) ()) 'd) ;; s: S e: E c: (:NIL :LDF (:LDC 7 :LDC 4 :LDC 3 :+ :* :RTN) :AP) d: D ;; s: (NIL . S) e: E c: (:LDF (:LDC 7 :LDC 4 :LDC 3 :+ :* :RTN) :AP) d: D ;; s: (((:LDC 7 :LDC 4 :LDC 3 :+ :* :RTN) . E) NIL . S) e: E c: (:AP) d: D ;; s: NIL e: (NIL . E) c: (:LDC 7 :LDC 4 :LDC 3 :+ :* :RTN) d: (S E NIL . D) ;; s: (7) e: (NIL . E) c: (:LDC 4 :LDC 3 :+ :* :RTN) d: (S E NIL . D) ;; s: (4 7) e: (NIL . E) c: (:LDC 3 :+ :* :RTN) d: (S E NIL . D) ;; s: (3 4 7) e: (NIL . E) c: (:+ :* :RTN) d: (S E NIL . D) ;; s: (7 7) e: (NIL . E) c: (:* :RTN) d: (S E NIL . D) ;; s: (49) e: (NIL . E) c: (:RTN) d: (S E NIL . D) ;; s: (49 . S) e: E c: NIL d: D STOP (49 . S)
まだ locate とか replcar とかの補助関数が定義できていない。