-------------------------------------------------------------------------------- {-# LANGUAGE PatternGuards #-} -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- -- |Destructor of 'El'. 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 -------------------------------------------------------------------------------- -- |Destructor of 'Function'. 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