git @ Cat's Eye Technologies Lanthorn / master src / Language / Lanthorn / Eval.hs
master

Tree @master (Download .tar.gz)

Eval.hs @masterraw · history · blame

module Language.Lanthorn.Eval where

import Language.Lanthorn.AST
import qualified Language.Lanthorn.Env as Env
import qualified Language.Lanthorn.Value as Value


evalTopLevelExpr :: Expr -> Either String Value.Value
evalTopLevelExpr expr =
    Right (evalExpr Env.stdEnv expr)

--
-- Evaluator
--

evalExpr env (NumLit i) = Value.Number i

evalExpr env (ValueOf name) = case Env.lookup name env of
    Just value -> value
    Nothing -> error ("Not in scope: " ++ name ++ " (env: " ++ (show env) ++ ")")

evalExpr env (LetStar [] body) = evalExpr env body
evalExpr env (LetStar ((name, expr):rest) body) =
    let
        val = evalExpr env expr
        env' = Env.extend [(name,val)] env
    in
        evalExpr env' (LetStar rest body)

evalExpr env (If c t f) =
    case evalExpr env c of
        Value.Boolean True -> evalExpr env t
        Value.Boolean False -> evalExpr env f
        other -> error ("Expected boolean: " ++ show other)

evalExpr env (Fun formals body) =
    let
        f values =
           let
               env' = Env.extend (zip formals values) env
           in
               evalExpr env' body
    in
        Value.Function f

evalExpr env (Apply name actualExprs) =
    case (evalExpr env (ValueOf name)) of
        (Value.Function f) ->
            let
                actuals = map (\expr -> evalExpr env expr) actualExprs
            in
                f actuals
        other -> error ("Expected function: " ++ show other)

evalExpr env other = error ("Unimplemented: " ++ show other)