Last active
March 10, 2023 11:47
-
-
Save woodrush/5bc9d8e670067e06a6a3f55c14025543 to your computer and use it in GitHub Desktop.
Krivine machine interpreter based on Binary Lambda Calculus written in LambdaLisp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defparameter **lambdalisp-suppress-repl** t) ;; Enters script mode and suppresses REPL messages | |
;; Usage: | |
;; $ git clone https://github.com/woodrush/lambdalisp | |
;; $ cd lambdalisp | |
;; $ make | |
;; $ ( cat bin/lambdalisp.blc | bin/asc2bin; cat examples/lisplambda.lisp; printf '01010000011101000100010' ) | |
;; | bin/Blc > test/krivine.lisp.out | |
;; | |
;; LambdaLisp is available at: https://github.com/woodrush/lambdalisp | |
(defun read-print-01char () | |
(let ((c (read-char))) | |
(cond | |
((or (= "0" c) (= "1" c)) | |
(format t c) | |
c) | |
(t | |
(read-print-01char))))) | |
(defun parsevarname-stdin () | |
(let ((c (read-print-01char))) | |
(cond | |
((= "0" c) | |
0) | |
(t | |
(+ 1 (parsevarname-stdin)))))) | |
(defun parseblc-stdin () | |
(let ((c (read-print-01char))) | |
(cond | |
((= c "0") | |
(setq c (read-print-01char)) | |
(cond | |
((= c "0") | |
(cons 'L (parseblc-stdin))) | |
;; 1 case | |
(t | |
(list (parseblc-stdin) (parseblc-stdin))))) | |
;; 1 case | |
(t | |
(parsevarname-stdin))))) | |
(defun nth (n l) | |
(cond | |
((= 0 n) | |
(car l)) | |
(t | |
(nth (- n 1) (cdr l))))) | |
(defun drop (n l) | |
(cond | |
((= 0 n) l) | |
(t (drop (- n 1) (cdr l))))) | |
(defun krivine (term) | |
(let ((tmp nil) (et term) (ep nil) (ee nil)) | |
(format t "----~%") | |
(loop | |
(format t "t: ~a~%" et) | |
(format t "p: ~a~%" ep) | |
(format t "e: ~a~%" ee) | |
(format t "----~%") | |
(cond | |
;; Variable | |
((integerp et) | |
(setq tmp (nth et ee)) | |
(setq et (car tmp)) | |
(setq ee (cdr tmp))) | |
;; Abstraction | |
((eq 'L (car et)) | |
;; If the stack is empty, finish the evaluation | |
(cond ((eq nil ep) | |
(return-from krivine et))) | |
(setq et (cdr et)) | |
(setq ee (cons (car ep) ee)) | |
(setq ep (cdr ep))) | |
;; Empty term | |
((eq nil et) | |
(return-from krivine et)) | |
;; Application | |
(t | |
(setq ep | |
(cons | |
(cons (car (cdr et)) ee) | |
ep)) | |
(setq et (car et))))))) | |
(defun main () | |
(let ((parsed nil) (result nil)) | |
(format t "~%") | |
(format t "Code: ") | |
(setq parsed (parseblc-stdin)) | |
(format t "~%") | |
(format t "Parsed: ~a~%" parsed) | |
(format t "Krivine machine transitions:~%") | |
(setq result (krivine parsed)) | |
(format t "Result: ~a~%" result))) | |
(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment