Mini Lisp Interpreter 0.0.1
(ql:quickload :alexandria) | |
(defparameter *globol-env* (make-hash-table)) | |
(defun bindp (expr env) | |
(second (multiple-value-list (gethash expr env)))) | |
(defun get-env (expr env) | |
(gethash expr env)) | |
(defun set-env (var val env) | |
(setf (gethash var env) val)) | |
(defun add-env (env vars vals) | |
(mapcar (lambda (var val) (set-env var val env)) | |
vars vals) | |
env) | |
(defparameter *true* (gensym)) | |
(defparameter *false* (gensym)) | |
(defun eval-cond (c env) | |
(cond ((interp (caar c) env) | |
(interp (cadar c) env)) | |
(t (eval-cond (rest c) env)))) | |
(defun param (func) | |
(second func)) | |
(defun body (func) | |
(third func)) | |
(defun eval-func (func args env) | |
(interp (body func) | |
(add-env env (param func) | |
(mapcar (lambda (x) (interp x env)) args)))) | |
(defun funcp (expr) | |
(eq (car expr) 'lambda)) | |
(defun interp (expr env) | |
(setq env (if (not (hash-table-p env)) | |
(alexandria:alist-hash-table env) | |
env)) | |
;; (format t "debug: expr[~a]~%env[~a]~%" expr (alexandria:hash-table-alist env)) | |
(finish-output) | |
(cond ((atom expr) | |
(if (bindp expr env) | |
(get-env expr env) | |
expr)) | |
((atom (first expr)) | |
(case (first expr) | |
((QUOTE) (second expr)) | |
((ATOM) (atom (interp (second expr) env))) | |
((EQ) (eq (interp (second expr) env) | |
(interp (third expr) env))) | |
((CAR) (car (interp (second expr) env))) | |
((CDR) (cdr (interp (second expr) env))) | |
((CONS) (cons | |
(interp (second expr) env) | |
(interp (third expr) env))) | |
((COND) (eval-cond (rest expr) env)) | |
(t (if (bindp (first expr) env) | |
(interp (cons (interp (first expr) env) | |
(rest expr)) | |
env) | |
expr)))) | |
((funcp (first expr)) | |
(eval-func (first expr) (rest expr) env)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment