Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
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)
(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)
;; (format t "debug: expr[~a]~%env[~a]~%" expr (alexandria:hash-table-alist env))
(cond ((atom expr)
(if (bindp expr env)
(get-env expr env)
((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))
((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