lispの勉強がてら・・・
common lispの勉強の為にGrassのインタプリタ(未完)を作っている。
Grassの詳細な仕様などは適当にググってください。
とりあえずパーサとかは作ってないけど、中間コードで書いてみた。
中間コードは
wWWwwwWwwvwWWWwvWw
ってのがあったとしたら
(def 1 `(2 3) `(1 2)) (def 1 `(3 1)) (app 1 1)
って感じ
以下ソース。そのまま処理系に渡すと Hello, world ってでてくる。
(defun out (prim) (let ((chr (first prim))) (format t "~c" (first chr)) chr)) (defun succ (prim) (let ((chr (first prim))) (setf (first chr) (code-char (mod (1+ (char-code (first chr))) 256))) chr)) (defun in (prim) (let ((rc (first prim)) (c (read-char))) (unless (null c) (setf rc `(,c 0 `()))) rc)) (defun true (prim) (first prim)) (defun false (prim) (second prim)) (defun stack-trace (stream &optional (prim *prim*)) (dotimes (i (length *prim*)) (format stream "~&~d: ~a~%" (1+ i) (first (nth i prim))))) (defun app (func arg &optional (prim *prim*)) (let ((func (copy-list (nth (1- func) prim))) (arg (copy-list (nth (1- arg) prim)))) (if (= (second func) 0) `(,(if (eql (first func) (first arg)) #'true #'false) 2 (copy-list prim)) (progn (push arg (third func)) (if (= (decf (second func)) 0) (funcall (first func) (third func)) func))))) (defun def (arg &rest apps) (let ((applist (copy-list apps))) (setf func #'(lambda (prim) (dolist (appelem applist) (push (app (first appelem) (second appelem) prim) prim)) (first prim))) (push `(,func ,arg ,(copy-list *prim*)) *prim*))) (defvar *prim* `(,`(,#'out 1 `()) ,`(,#'succ 1 `()) ,`(#\w 0 `()) ,`(,#'in 1 `()))) ; print w ; wWWwwww ;(def 1 `(2 4)) ; print x ; wWWWwwwwWWWw ;(def 1 `(3 4) `(3 1)) ; print w (infinite) ; !!WARNING!! ; Always stack overflow occurs. ; wWWwwwwWWWW ;(def 1 `(2 4) `(2 2)) ; print answer of '1+1' in number of w ; wwWWwvwwwwWWWwwWwwWWWWWWwwwwWwwvwWWwwwWwwwwWwwwwwwWwwwwwwwww ;(def 2 `(2 1)) ;(def 4 `(3 2) `(1 2) `(6 4) `(1 2)) ;(def 1 `(2 3) `(1 4) `(1 6) `(1 9)) ; hello world (def 2) (def 3 `(3 2) `(1 2) `(4 1)) (def 1 `(2 3) `(1 2)) (def 1 `(1 3) `(1 2)) (def 1 `(2 1) `(5 1)) (def 1 `(3 4) `(4 1) `(4 1) `(6 1) `(7 1) `(7 1) `(8 1) `(1 8)) (def 1 `(3 5) `(5 1) `(5 1) `(7 1) `(8 1) `(9 1) `(1 7)) (def 1 `(4 6) `(6 1) `(6 1) `(7 1) `(9 1) `(9 1) `(1 7)) (def 1 `(5 7) `(7 1) `(8 1) `(8 1) `(10 1) `(10 1) `(1 7)) (def 1 `(7 8) `(8 1) `(9 1) `(9 1) `(11 1) `(1 6)) (def 1 `(8 9) `(8 1) `(9 1) `(11 1) `(11 1) `(13 1) `(1 7)) (def 1 `(8 10) `(9 1) `(10 1) `(11 1) `(13 1) `(1 6)) (def 1 `(10 11) `(10 1) `(11 1) `(13 1) `(1 5)) (def 1 `(10 12) `(12 1) `(13 1) `(14 1) `(14 1) `(16 1) `(1 7)) (def 1 `(10 17) `(1 19) `(3 19) `(1 2) `(20 1)) (def 1 `(2 4) `(3 10) `(4 10) `(5 13) `(6 7) `(7 11) `(8 22)) (def 1 `(16 7) `(1 2)) (def 1 `(4 7) `(5 3) `(6 7) `(7 8) `(8 14) `(9 14)) (def 1 `(2 1) `(5 1)) ; build-in application (push (app 1 1) *prim*) ;(stack-trace t)
真のlisperからするとかなり汚いコードだろうが結構勉強になった。
次は中間コードではなくパーサーも組み込みたい。