{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving, MultiParamTypeClasses #-} module Language.Epsilon.Types where import Text.Parsec import Data.Text (Text, pack, unpack) import Data.String (IsString, fromString) import Control.Monad.IO.Class (MonadIO) import Control.Monad.Except (MonadError) import Control.Monad.Trans.Except (ExceptT) type Ident = Text type Env = [(Ident, Value)] newtype EvalM a = EvalM { runEvalM :: ExceptT Error IO a } deriving (Functor, Applicative, Monad, MonadIO) deriving instance MonadError Error EvalM data PrimType = PrimFn | PrimMacro -- should args/result be evaluated? data Value = Snoc Value Value | Nil | Fn Ident Value | Macro Ident Value | Prim PrimType (Value -> EvalM Value) | Quote Value | Symbol Text | Int Int | Float Double | Str Text | Char Char instance Show Value where show (Snoc a d) = "(" ++ show a ++ " . " ++ show d ++ ")" show Nil = "()" show (Fn i v) = "(fn " ++ unpack i ++ " " ++ show v ++ ")" show (Macro i v) = "(macro " ++ unpack i ++ " " ++ show v ++ ")" show (Prim _ _) = "" show (Quote v) = "'" ++ show v show (Symbol s) = unpack s show (Int i) = show i show (Float f) = show f show (Str s) = show s show (Char c) = show c instance IsString Value where fromString = Symbol . pack infixl 5 `Snoc` data Error = Unbound Ident | BadApply Value Value | TypeError Value | ReadError ParseError deriving Show