module Language.PureScript.Sugar.Operators.Expr where import Prelude import Control.Monad.Except (MonadError) import Data.Functor.Identity (Identity) import Text.Parsec qualified as P import Text.Parsec.Expr qualified as P import Language.PureScript.AST (Associativity, Expr(..), SourceSpan) import Language.PureScript.Names (OpName(..), OpNameType(..), Qualified(..)) import Language.PureScript.Sugar.Operators.Common (Chain, matchOperators, token) import Language.PureScript.Errors (MultipleErrors) matchExprOperators :: MonadError MultipleErrors m => [[(Qualified (OpName 'ValueOpName), Associativity)]] -> Expr -> m Expr matchExprOperators :: forall (m :: * -> *). MonadError MultipleErrors m => [[(Qualified (OpName 'ValueOpName), Associativity)]] -> Expr -> m Expr matchExprOperators = forall (m :: * -> *) a (nameType :: OpNameType). (Show a, MonadError MultipleErrors m) => (a -> Bool) -> (a -> Maybe (a, a, a)) -> FromOp nameType a -> Reapply nameType a -> ([[Operator (Chain a) () Identity a]] -> [[Operator (Chain a) () Identity a]]) -> [[(Qualified (OpName nameType), Associativity)]] -> a -> m a matchOperators Expr -> Bool isBinOp Expr -> Maybe (Expr, Expr, Expr) extractOp Expr -> Maybe (SourceSpan, Qualified (OpName 'ValueOpName)) fromOp SourceSpan -> Qualified (OpName 'ValueOpName) -> Expr -> Expr -> Expr reapply [[Operator (Chain Expr) () Identity Expr]] -> [[Operator (Chain Expr) () Identity Expr]] modOpTable where isBinOp :: Expr -> Bool isBinOp :: Expr -> Bool isBinOp BinaryNoParens{} = Bool True isBinOp Expr _ = Bool False extractOp :: Expr -> Maybe (Expr, Expr, Expr) extractOp :: Expr -> Maybe (Expr, Expr, Expr) extractOp (BinaryNoParens Expr op Expr l Expr r) | PositionedValue SourceSpan _ [Comment] _ Expr op' <- Expr op = forall a. a -> Maybe a Just (Expr op', Expr l, Expr r) | Bool otherwise = forall a. a -> Maybe a Just (Expr op, Expr l, Expr r) extractOp Expr _ = forall a. Maybe a Nothing fromOp :: Expr -> Maybe (SourceSpan, Qualified (OpName 'ValueOpName)) fromOp :: Expr -> Maybe (SourceSpan, Qualified (OpName 'ValueOpName)) fromOp (Op SourceSpan ss q :: Qualified (OpName 'ValueOpName) q@(Qualified QualifiedBy _ (OpName Text _))) = forall a. a -> Maybe a Just (SourceSpan ss, Qualified (OpName 'ValueOpName) q) fromOp Expr _ = forall a. Maybe a Nothing reapply :: SourceSpan -> Qualified (OpName 'ValueOpName) -> Expr -> Expr -> Expr reapply :: SourceSpan -> Qualified (OpName 'ValueOpName) -> Expr -> Expr -> Expr reapply SourceSpan ss = Expr -> Expr -> Expr -> Expr BinaryNoParens forall b c a. (b -> c) -> (a -> b) -> a -> c . SourceSpan -> Qualified (OpName 'ValueOpName) -> Expr Op SourceSpan ss modOpTable :: [[P.Operator (Chain Expr) () Identity Expr]] -> [[P.Operator (Chain Expr) () Identity Expr]] modOpTable :: [[Operator (Chain Expr) () Identity Expr]] -> [[Operator (Chain Expr) () Identity Expr]] modOpTable [[Operator (Chain Expr) () Identity Expr]] table = [ forall s u (m :: * -> *) a. ParsecT s u m (a -> a -> a) -> Assoc -> Operator s u m a P.Infix (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a P.try (Expr -> Expr -> Expr -> Expr BinaryNoParens forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Parsec (Chain Expr) () Expr parseTicks)) Assoc P.AssocLeft ] forall a. a -> [a] -> [a] : [[Operator (Chain Expr) () Identity Expr]] table parseTicks :: P.Parsec (Chain Expr) () Expr parseTicks :: Parsec (Chain Expr) () Expr parseTicks = forall s t a u. Stream s Identity t => (t -> Maybe a) -> Parsec s u a token (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c either (forall a b. a -> b -> a const forall a. Maybe a Nothing) Expr -> Maybe Expr fromOther) forall s u (m :: * -> *) a. ParsecT s u m a -> String -> ParsecT s u m a P.<?> String "infix function" where fromOther :: Expr -> Maybe Expr fromOther (Op SourceSpan _ Qualified (OpName 'ValueOpName) _) = forall a. Maybe a Nothing fromOther Expr v = forall a. a -> Maybe a Just Expr v