Eq-1.0: EqManips/Algorithm/Eval/GlobalStatement.hs
module EqManips.Algorithm.Eval.GlobalStatement( evalGlobalStatement ) where
import qualified EqManips.ErrorMessages as Err
import EqManips.Types
import EqManips.EvaluationContext
import EqManips.Algorithm.Eval.Types
-- | Add a function into the symbol table.
addLambda :: String -> [Formula ListForm] -> Formula ListForm -> EqContext ()
addLambda varName args body = do
symb <- symbolLookup varName
case symb of
Nothing -> addSymbol varName . Formula
$ lambda [(map unTagFormula args, unTagFormula body)]
Just (Formula (Lambda _ clauses@((prevArg,_):_))) ->
if length prevArg /= length args
then do
_ <- eqFail (Formula $ Variable varName) Err.def_diff_argcount
return ()
else updateSymbol varName . Formula . lambda
$ clauses ++ [(map unTagFormula args
, unTagFormula body)]
Just _ -> do
_ <- eqFail (Formula $ Variable varName) $ Err.def_not_lambda varName
return ()
-- | Add a "value" into the symbol table
addVar :: String -> Formula ListForm -> EqContext ()
addVar varName body = do
symb <- symbolLookup varName
case symb of
Nothing -> addSymbol varName body
Just _ -> do
_ <- eqFail (Formula $ Variable varName) $ Err.def_already varName
return ()
-- | Evaluate top level declarations
evalGlobalStatement :: EvalFun -> Formula ListForm -> EqContext (Formula ListForm)
evalGlobalStatement evaluator (Formula (BinOp _ OpAttrib [ (App _ (Variable funName) argList)
, body ])) = do
pushContext
body' <- evaluator body
popContext
addLambda funName (map Formula argList) (Formula body')
return $ Formula (binOp OpAttrib [(app (Variable funName) argList), body])
evalGlobalStatement _ (Formula (BinOp _ OpLazyAttrib [ (App _ (Variable funName) argList)
, body ])) = do
addLambda funName (map Formula argList) (Formula body)
return $ Formula (binOp OpLazyAttrib [(app (Variable funName) argList), body])
evalGlobalStatement evaluator (Formula (BinOp _ OpAttrib [(Variable varName), body])) = do
pushContext
body' <- evaluator body
popContext
addVar varName (Formula body')
return $ Formula (binOp OpAttrib [(Variable varName), body'])
evalGlobalStatement _ (Formula (BinOp _ OpLazyAttrib [(Variable varName), body])) = do
addVar varName (Formula body)
return $ Formula (binOp OpLazyAttrib [(Variable varName), body])
evalGlobalStatement evaluator (Formula e) = do
pushContext
a <- evaluator e
popContext
return $ Formula a