module Rose where import BoundsParser import OldExprParser import Control.Applicative import Control.Monad.Either type ParseTree a = Rose (Bounds, a) data Rose a = Rose a [Rose a] -- data Expr -- = Add Expr Expr -- | Sub Expr Expr -- | Mul Expr Expr -- | Div Expr Expr -- | Num Int -- deriving (Eq, Show) -- 1 + 2 * 3 example :: ParseTree BareExpr example = let one = Num 1 two = Num 2 three = Num 3 mul = Mul two three add = Add one mul in Rose (Bounds (0, 0) (9, 9), add) [ Rose (Bounds (0, 0) (1, 2), one) [] , Rose (Bounds (3, 4) (9, 9), mul) [ Rose (Bounds (3, 4) (5, 6), two) [] , Rose (Bounds (7, 8) (9, 9), three) [] ] ] eval :: ParseTree BareExpr -> Either Bounds Int eval (Rose (bounds, expr) cs) = case (expr, cs) of (Num n, []) -> pure n (Add _ _, [x, y]) -> (+) <$> eval x <*> eval y (Sub _ _, [x, y]) -> (-) <$> eval x <*> eval y (Mul _ _, [x, y]) -> (*) <$> eval x <*> eval y (Div _ _, [x, y]) -> do x' <- eval x y' <- eval y case y' of 0 -> Left bounds _ -> pure (x' `div` y') data ExprAlg aT = ExprAlg { cataNum :: Int -> aT , cataAdd :: aT -> aT -> aT , cataSub :: aT -> aT -> aT , cataMul :: aT -> aT -> aT , cataDiv :: aT -> aT -> aT } -- cataExpr :: ExprAlg aT -> Fix ExprF -> aT -- cataExpr alg (In expr) = case expr of