mirror of
https://github.com/peklaiho/madlisp.git
synced 2024-11-22 13:24:46 +00:00
add eval.mad
This commit is contained in:
parent
c4e0a991c6
commit
9e0550736a
39
mad/eval.mad
Normal file
39
mad/eval.mad
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
;;
|
||||||
|
;; MadLisp interpreter written in... MadLisp?
|
||||||
|
;;
|
||||||
|
;; Inspired by "The Most Beautiful Program Ever Written" by William Byrd:
|
||||||
|
;; https://youtu.be/OyfBQmvr2Hc
|
||||||
|
;;
|
||||||
|
;; Currently supports very minimal functionality. Note that the expression
|
||||||
|
;; to evaluate must be quoted, because otherwise it is evaluated before
|
||||||
|
;; eval-expr!
|
||||||
|
;;
|
||||||
|
;; Some examples:
|
||||||
|
;; > (eval-expr '(+ 1 2 (* 3 4)) (make-envr))
|
||||||
|
;; 15
|
||||||
|
;; > (eval-expr '((fn (a) (* a 2)) 7) (make-envr))
|
||||||
|
;; 14
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defn eval-list (lst envr)
|
||||||
|
(case (let (item (first lst)) (if (symbol? item) (str item) "other"))
|
||||||
|
["if" (if (eval-expr (second lst) envr)
|
||||||
|
(eval-expr (get lst 2) envr)
|
||||||
|
(eval-expr (get lst 3) envr))]
|
||||||
|
["fn" (let (x (first (second lst)) body (get lst 2))
|
||||||
|
(fn (arg) (eval-expr body
|
||||||
|
(fn (y) (if (= x y) arg (envr y))))))]
|
||||||
|
[else (apply (eval-expr (first lst) envr)
|
||||||
|
(map (fn (a) (eval-expr a envr)) (tail lst)))]))
|
||||||
|
|
||||||
|
(defn eval-expr (expr envr)
|
||||||
|
(cond
|
||||||
|
[(symbol? expr) (envr expr)]
|
||||||
|
[(list? expr) (if (empty? expr) expr (eval-list expr envr))]
|
||||||
|
[else expr]))
|
||||||
|
|
||||||
|
(defn make-envr ()
|
||||||
|
(fn (key) (case key
|
||||||
|
(+ +) (- -) (* *) (/ /)
|
||||||
|
(else (throw (str key " not found in envr"))))))
|
Loading…
Reference in New Issue
Block a user