Skip to content

Instantly share code, notes, and snippets.

@woodrush
Last active March 10, 2023 11:47
Show Gist options
  • Save woodrush/5bc9d8e670067e06a6a3f55c14025543 to your computer and use it in GitHub Desktop.
Save woodrush/5bc9d8e670067e06a6a3f55c14025543 to your computer and use it in GitHub Desktop.
Krivine machine interpreter based on Binary Lambda Calculus written in LambdaLisp
(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