module Console.Garepinoh.Utils
( step
, value
, appendFunction
, function
, append
, apply
, list
) where
import Data.List
import Console.Garepinoh.Types
step :: Read t => Prelude t -> Result t -> String -> Result t
step _ (Left ermsg) _ = Left ermsg
step fl (Right stack) word
| Just x <- value word
= append x stack
| Just x <- appendFunction word fl
= append (el Va Li (\f -> Fu (f { symb = NEL (tail word) [] })) x) stack
| Just x <- applyFunction word fl
= apply fl x stack
| otherwise
= Left $ "Invalid input " ++ show word ++ "."
value :: Read t => String -> Maybe (El t)
value word = case reads word of
[(v, "")] -> Just $ Va v
_ -> Nothing
appendFunction :: String -> Prelude t -> Maybe (El t)
appendFunction (',':word) = applyFunction word
appendFunction _ = const Nothing
applyFunction :: String -> Prelude t -> Maybe (El t)
applyFunction word = fmap Fu . find (elem word . list . symb)
append :: El t -> Stack t -> Result t
append e l = Right (e:l)
apply :: Read t => Prelude t -> El t -> Stack t -> Result t
apply fl (Fu (Func _ fs)) stack = applyAll fs stack
where
applyAll [] s = Right s
applyAll (g:gs) s = either Left (applyAll gs) $ function
(Right . (:s))
(step fl (Right s))
(\h -> h fl s)
g
apply _ _ _ = Left "Expecting a function to be applied."
list :: NonEmptyList t -> [t]
list (NEL x xs) = x:xs
el :: (t -> x) -> ([El t] -> x) -> (Func t -> x) -> El t -> x
el f _ _ (Va x) = f x
el _ f _ (Li x) = f x
el _ _ f (Fu x) = f x
function :: (El t -> x) -> (String -> x) -> ((Prelude t -> Stack t -> Either String (Stack t)) -> x) -> Function t -> x
function f _ _ (Ele x) = f x
function _ f _ (Ref x) = f x
function _ _ f (Fun x) = f x