Skip to content

Instantly share code, notes, and snippets.

@lispm
Created August 4, 2018 21:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lispm/c16e759fab98b59139e1c1063bf96c9a to your computer and use it in GitHub Desktop.
Save lispm/c16e759fab98b59139e1c1063bf96c9a to your computer and use it in GitHub Desktop.
; https://z0ltan.wordpress.com/2018/08/04/simple-expression-evaluator-comparison-between-haskell-rust-and-common-lisp/
; this version: 2018, Rainer Joswig, joswig@lisp.de
; we create a bunch of structures for the expression types
; each structure defines a constructor of the same name
; each expression knows the corresponding Lisp function
(defstruct (val (:constructor val (e))) e)
(defstruct (bop :conc-name) e1 e2 op)
(defmacro defbinops (&rest names)
`(progn ,@(loop for (name op) in names
collect `(defstruct (,name (:include bop (op ',op)) (:constructor ,name (e1 e2)))))))
(defbinops (mul *) (div /) (add +) (sub -))
; a bunch of CLOS methods for evaluation
; we use two functions - the first function catches the errors and returns NIL then
(defmethod evaluate (e)
(ignore-errors (evaluate1 e)))
(defmethod evaluate1 ((e val))
(val-e e))
(defmethod evaluate1 ((e bop))
(funcall (op e) (evaluate (e1 e)) (evaluate (e2 e))))
(defun example ()
(format t "~s~%" (evaluate (Add (Val 2) (Mul (Val 3) (Val 6)))))
(format t "~s~%" (evaluate (Div (Val 10) (Val 0)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment