{-# OPTIONS -w #-} module Lambdabot.Plugin.Haskell.Free.Expr where import Lambdabot.Plugin.Haskell.Free.Type import Lambdabot.Plugin.Haskell.Free.Util import Prelude hiding ((<>)) varInExpr :: Var -> Expr -> Bool varInExpr v (EBuiltin _) = False varInExpr v (EVar v') = v == v' varInExpr v (EVarOp _ _ v') = False varInExpr v (EApp e1 e2) = varInExpr v e1 || varInExpr v e2 varInExpr v (ETyApp e1 t) = varInExpr v e1 leftVarOfExpr :: Expr -> Var leftVarOfExpr (EVar v) = v leftVarOfExpr (EApp e _) = leftVarOfExpr e leftVarOfExpr (ETyApp e _) = leftVarOfExpr e exprSubst :: Var -> Expr -> Expr -> Expr exprSubst v e e'@(EBuiltin _) = e' exprSubst v e e'@(EVar v') | v == v' = e | otherwise = e' exprSubst v e e'@(EVarOp _ _ v') | v == v' = e | otherwise = e' exprSubst v e (EApp e1 e2) = EApp (exprSubst v e e1) (exprSubst v e e2) exprSubst v e (ETyApp e1 t) = ETyApp (exprSubst v e e1) t type Var = String data Fixity = FL | FN | FR deriving (Eq, Show) data Expr = EVar Var | EBuiltin Builtin | EVarOp Fixity Int Var | EApp Expr Expr | ETyApp Expr Type deriving (Eq, Show) data Builtin = BMap TyName | BId | BProj Int Int | BMapTuple Int | BArr deriving (Eq, Show) data ExprCtx = ECDot | ECAppL ExprCtx Expr | ECAppR Expr ExprCtx | ECTyApp ExprCtx Type deriving (Eq, Show) applySimplifierExpr :: (Expr -> Expr) -> (Expr -> Expr) applySimplifierExpr s (EApp e1 e2) = EApp (s e1) (s e2) applySimplifierExpr s (ETyApp e t) = ETyApp (s e) t applySimplifierExpr s e = e unzipExpr :: Expr -> ExprCtx -> Expr unzipExpr e ECDot = e unzipExpr e (ECAppL c e2) = unzipExpr (EApp e e2) c unzipExpr e (ECAppR e1 c) = unzipExpr (EApp e1 e) c unzipExpr e (ECTyApp c t) = unzipExpr (ETyApp e t) c varInCtx :: Var -> ExprCtx -> Bool varInCtx v ECDot = False varInCtx v (ECAppL c e2) = varInCtx v c || varInExpr v e2 varInCtx v (ECAppR e1 c) = varInCtx v c || varInExpr v e1 varInCtx v (ECTyApp c _) = varInCtx v c precAPP :: Int precAPP = 10 instance Pretty Expr where prettyP p (EBuiltin b) = prettyP p b prettyP _ (EVar v) = text v prettyP _ (EVarOp _ _ v) = lparen <> text v <> rparen prettyP p (EApp (EApp (EVarOp fix prec op) e1) e2) = prettyParen (p > prec) ( prettyP pl e1 <+> text op <+> prettyP pr e2 ) where pl = if fix == FL then prec else prec+1 pr = if fix == FR then prec else prec+1 prettyP p (EApp e1 e2) = prettyParen (p > precAPP) ( prettyP precAPP e1 <+> prettyP (precAPP+1) e2 ) prettyP p (ETyApp e t) = prettyP precAPP e instance Pretty Builtin where prettyP p (BMap "[]") = text "$map" prettyP p (BMap c) = text ("$map_" ++ c) prettyP p BId = text "$id" prettyP p (BProj 2 1) = text "$fst" prettyP p (BProj 2 2) = text "$snd" prettyP p (BProj 3 1) = text "$fst3" prettyP p (BProj 3 2) = text "$snd3" prettyP p (BProj 3 3) = text "$thd3" prettyP p (BProj l i) = text ("$proj_" ++ show l ++ "_" ++ show i) prettyP p (BMapTuple 2) = text "$map_Pair" prettyP p (BMapTuple 3) = text "$map_Triple" prettyP p (BMapTuple n) = text $ "$map_Tuple" ++ show n prettyP p BArr = text "$arr" -- vim: ts=4:sts=4:expandtab:ai