Skip to content

Instantly share code, notes, and snippets.

@devyn
Created October 9, 2011 05:25
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 devyn/1273348 to your computer and use it in GitHub Desktop.
Save devyn/1273348 to your computer and use it in GitHub Desktop.
import Prelude hiding (toInteger)
import Data.List
data Value = StringValue String
| IntegerValue Integer
| NameValue String
| FuncValue [String] AST
| NilValue
deriving Show
type AST = [Value]
toString :: Value -> String
toString (StringValue s) = s
toString (IntegerValue i) = show i
toString (NameValue s) = '\'' : s
toString (FuncValue a b) = "(" ++ intercalate ", " a ++ ") -> ..."
toString NilValue = "nil"
toInteger :: Value -> Integer
toInteger (StringValue s) = read s
toInteger (IntegerValue i) = i
toInteger _ = 0
consume :: AST -> IO (Value,AST)
consume (x@(StringValue _):xs) = return (x,xs)
consume (x@(IntegerValue _):xs) = return (x,xs)
consume (NameValue "print":xs) = do (s,xs') <- consume xs
putStrLn $ toString s
return (NilValue, xs')
consume (NameValue "plus":xs) = do (a,xs') <- consume xs
(b,xs'') <- consume xs'
return (IntegerValue $ toInteger a + toInteger b, xs'')
consume [] = error "not enough arguments"
consume _ = undefined
eval :: AST -> IO Value
eval ast = do (x,xs') <- consume ast
if null xs'
then return x
else eval xs'
main = eval [NameValue "print"
,NameValue "plus"
,NameValue "plus"
,IntegerValue 1
,IntegerValue 2
,IntegerValue 3] >>= print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment