Skip to content

Instantly share code, notes, and snippets.

@funrep
Created June 3, 2014 17:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save funrep/652e13a14697882fb931 to your computer and use it in GitHub Desktop.
Save funrep/652e13a14697882fb931 to your computer and use it in GitHub Desktop.
Unfinished (but working) lisp interpreter in SML.
(* simple lisp interpreter *)
type sym = string
datatype exp = Sym of sym
| List of exp list
| Num of int
| Str of string
| Bool of bool
| Lam of (sym list) * ((sym * exp) list) * exp
| Prim of (exp list) -> exp
fun exp2bool (Bool x) = x
| exp2bool _ = raise Fail "Y U NO GIEF ME BOOL?!"
fun exp2sym (Sym x) = x
| exp2sym _ = raise Fail "Y U NO GIEF ME SYMBOL?!"
fun lookup key ((x,y)::xs) = if key = x then y else lookup key xs
| lookup _ [] = raise Fail "USE OPTION YOU LAZY CUNT"
fun insert key x xs = (key,x)::xs
fun zip (x::xs) (y::ys) = (x,y)::(zip xs ys)
| zip _ _ = []
fun oneof x (y::ys) = if x = y then true else oneof x ys
| oneof _ [] = false
fun append (x::xs) ys = x::(append xs ys)
| append [] ys = ys
fun add [Num x, Num y] = Num (x+y)
fun sub [Num x, Num y] = Num (x-y)
fun eq [Num x, Num y] = Bool (x=y)
| eq [Str x, Str y] = Bool (x=y)
| eq [Bool x, Bool y] = Bool (x=y)
| eq [_, _] = Bool false
val prims = [("+", Prim add), ("-", Prim sub), ("eq?", Prim eq)]
fun eval (Sym x) e = lookup x e
| eval (List [Sym "quote", x]) e = x
| eval (List [Sym "if", b, x, y]) e = if exp2bool (eval b e)
then eval x e
else eval y e
| eval (List [Sym "lambda", List xs, x]) e = Lam ((map exp2sym xs),e,x)
| eval (List (f::xs)) e = apply (eval f e) (map (fn x=> eval x e) xs)
| eval x e = x
and apply (Prim f) xs = f xs
| apply (Lam (xs, e, x)) ys = eval x (append (zip xs ys) e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment