{-# LANGUAGE NoImplicitPrelude #-}

module Language.Dash.Evaluate (eval) where

import Language.Dash.Environment

import Prelude (($), Maybe (..), maybe)

eval :: Environment -> Term -> Maybe Literal
eval e (Variable s) = getEnv e s
eval _ (Literal y) = Just y
eval (Environment e) (Lambda n l) = Just (LiteralFunction (Environment e) (maybe Nothing (\x -> eval (Environment $ (n, x) : e) l)))
eval e (Apply t1 t2) =
  case eval e t1 of
    Just (LiteralFunction _ f) -> f $ eval e t2
    _ -> Nothing --error $ "Not a lambda: " ++ show v
eval e (If x y z) = do
  case eval e x of
    Just (LiteralBool res) -> eval e $ if res then y else z
    _ -> Nothing
eval (Environment e) (LetRec s t1 t2) = eval e' t2
  where
    e' = Environment $ (s, v) : e
    (Just v) = eval e' t1

{-# LANGUAGE NoImplicitPrelude #-}

module Language.Dash.Evaluate (eval) where

import Language.Dash.Environment

import Prelude (($), Maybe (..), maybe, (>>=))

eval :: Environment -> Term -> Maybe Literal
eval e (Variable s) = getEnv e s
eval _ (Literal y) = Just y
eval (Environment e) (Lambda n l) = Just (LiteralFunction (Environment e) (maybe Nothing (\x -> eval (Environment $ (n, x) : e) l)))
eval e (Apply t1 t2) =
  case eval e t1 of
    Just (LiteralFunction _ f) -> f $ eval e t2
    _ -> Nothing --error $ "Not a lambda: " ++ show v
eval e (If x y z) =
  case eval e x of
    Just (LiteralBool res) -> eval e $ if res then y else z
    _ -> Nothing
eval (Environment e) (LetRec s t1 t2) = e' >>= (`eval` t2)
  where
    e' :: Maybe Environment
    e' = v >>= (\v' -> Just (Environment $ (s, v') : e))

    v :: Maybe Literal
    v = e' >>= (`eval` t1)

Fix letrec crash when substituting a variable bound to an unbound variable
Fix letrec crash when substituting a variable bound to an unbound variable

Signed-off-by: Ricky Elrod <3de8762d49a778edd8b1aa9f381ea5a9ccb62944@elrod.me>
