Lisp本を書くつもりがMACLISP互換処理系の作成にはまってしまいました。
古いWinstonのLISP本をパラパラとめくっているうちに懐かしくなってきました。これは1977年当時のMACLISPで書かれたいたのでした。先日作ったLISP1.5互換実装をちょっと改良するとできそうでした。
なにしろ思い出深い本です。22歳くらいのときに読みました。処理系が手元になくてほとんど理解できませんでした。なんとも懐かしい。
インストール
Githubにおいてあります。クローンをつくってください。sudo make installでokです。起動は maclisp です。
FEXPRとマクロ
当時はまだLISP1.5からCommonLispへと至る過渡期でした。
今のマクロとはかなり違います。そしてFEXPRというものも当時はありました。
(DEFUN IF MACRO (X)
(SUBST (CADR X) '1ST
(SUBST (CADDR X) '2ND
(SUBST (COND ((EQUAL (LENGTH X) 4) (CADDDR X))
(T NIL))
'3RD
'(COND (1ST 2ND) (T 3RD))))))
(DEFUN IF* FEXPR (X)
(COND ((EVAL (CAR X)) (EVAL (CADR X)))
((CDDR X) (EVAL (CADDR X)))
(T NIL)))
ifをcond節に置き換えるものです。変換の様子とみるのにステッパーが使えるようにしてあります。
実行例
$ maclisp
MACLISP 1977
* (load "macro.lsp")
T
* (step t)
T
* (if 1 2 3)
(IF 1 2 3) in [] >> (SUBST (CADR X) (QUOTE 1ST) (SUBST (CADDR X) (QUOTE 2ND) (SUBST (COND ((EQUAL (LENGTH X) 4) (CADDDR X)) (T NIL)) (QUOTE 3RD) (QUOTE (COND (1ST 2ND) (T 3RD)))))) in [(X _ 1 2 3)] >>
(CADR X) in [(X _ 1 2 3)] >>
X in [(X _ 1 2 3)] >>
(QUOTE 1ST) in [(X _ 1 2 3)] >>
(SUBST (CADDR X) (QUOTE 2ND) (SUBST (COND ((EQUAL (LENGTH X) 4) (CADDDR X)) (T NIL)) (QUOTE 3RD) (QUOTE (COND (1ST 2ND) (T 3RD))))) in [(X _ 1 2 3)] >>
(CADDR X) in [(X _ 1 2 3)] >>
X in [(X _ 1 2 3)] >>
(QUOTE 2ND) in [(X _ 1 2 3)] >>
(SUBST (COND ((EQUAL (LENGTH X) 4) (CADDDR X)) (T NIL)) (QUOTE 3RD) (QUOTE (COND (1ST 2ND) (T 3RD)))) in [(X _ 1 2 3)] >>
(COND ((EQUAL (LENGTH X) 4) (CADDDR X)) (T NIL)) in [(X _ 1 2 3)] >>
(EQUAL (LENGTH X) 4) in [(X _ 1 2 3)] >>
(LENGTH X) in [(X _ 1 2 3)] >>
X in [(X _ 1 2 3)] >>
4 in [(X _ 1 2 3)] >>
(CADDDR X) in [(X _ 1 2 3)] >>
X in [(X _ 1 2 3)] >>
(QUOTE 3RD) in [(X _ 1 2 3)] >>
(QUOTE (COND (1ST 2ND) (T 3RD))) in [(X _ 1 2 3)] >>
(COND (1 2) (T 3)) in [] >>
1 in [] >>
2 in [] >>
2
* (if* 1 2 3)
(IF* 1 2 3) in [] >> (COND ((EVAL (CAR X)) (EVAL (CADR X))) ((CDDR X) (EVAL (CADDR X))) (T NIL)) in [(X 1 2 3)] >>
(EVAL (CAR X)) in [(X 1 2 3)] >>
(CAR X) in [(X 1 2 3)] >>
X in [(X 1 2 3)] >>
1 in [(X 1 2 3)] >>
(EVAL (CADR X)) in [(X 1 2 3)] >>
(CADR X) in [(X 1 2 3)] >>
X in [(X 1 2 3)] >>
2 in [(X 1 2 3)] >>
2
*
CL以前はこんな風にしていたんですね。なんとも懐かしい。
お試しください。
ざっくりとWinstonの本を実行してみました。おおよそ動作しているようです。
全部は試していません。バグを見つけたらIssuesにてお知らせください。
古参のLisperにとっては懐かしい想い出でしょう。
