Skip to content

Instantly share code, notes, and snippets.

@eiel
Last active August 29, 2015 14:10
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 eiel/af120e6f44febc875702 to your computer and use it in GitHub Desktop.
Save eiel/af120e6f44febc875702 to your computer and use it in GitHub Desktop.
Lisp インタープリタ勉強で学んだことを試した。
module Mylisp where
import Data.HashMap.Strict as HM hiding (map)
import Data.Maybe
import Data.List as L hiding (insert)
data Value = Func ([Value] -> Value) |
List [Value] |
Symbol String |
Number Int
instance Show Value where
show (Func x) = "#fn"
show (List xs) = "(" ++ intercalate " " (map show xs) ++ ")"
show (Symbol x) = x
show (Number x) = show x
type Env = HashMap String Value
-- |
-- >>> putStrLn . show $ List [Symbol "+", Number 1, Number 2, Number 3]
-- (+ 1 2 3)
-- >>> evaluate global $ List [Symbol "+", Number 1, Number 2, Number 3]
-- 6
-- >>> eval $ List [Symbol "+", Number 1, Number 2, Number 3]
-- 6
evaluate :: Env -> Value -> Value
evaluate _ (Number x) = Number x
evaluate env (Symbol x) = fromMaybe nil $ HM.lookup x env
evaluate _ (List []) = nil
evaluate env (List (x:xs)) = case x of
Symbol x' -> case fromMaybe nil $ HM.lookup x' env of
x''@(Func _) -> apply env x'' xs
_ -> nil
_ -> nil
eval = evaluate global
apply :: Env -> Value -> [Value] -> Value
apply env (Func x) = x . map (evaluate env)
global = insert "+" plus $
HM.empty
where
number (Number x) = x
car (x:_) = x
cdr (_:x) = x
list xs = List xs
plus = Func plus'
where
number (Number x) = x
plus' = Number . sum . map number
nil = List []
n1 = Number 1
n2 = Number 2
n3 = Number 3
sPlus = Symbol "+"
-- >>> eval $ List [sPlus, n1, n2, n3]
-- 6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment