{-# language LambdaCase #-}
{-# language DataKinds, KindSignatures #-}
{-# language DeriveFunctor, DeriveFoldable, DeriveTraversable, DeriveGeneric #-}
{-# language ExistentialQuantification #-}
{-# language InstanceSigs, TypeApplications #-}
{-# language MultiParamTypeClasses, FlexibleInstances #-}
{-# language ScopedTypeVariables #-}
module Language.Python.Syntax.Expr
(
Expr(..), HasExprs(..), shouldGroupLeft, shouldGroupRight
, Param(..), paramAnn, paramType_, paramType, paramName
, Arg(..), argExpr
, Comprehension(..), CompIf(..), CompFor(..)
, DictItem(..), ListItem(..), SetItem(..), TupleItem(..)
, Subscript(..)
)
where
import Control.Lens.Cons (_last)
import Control.Lens.Fold ((^?), (^?!))
import Control.Lens.Getter ((^.), getting, to, view)
import Control.Lens.Lens (Lens, Lens', lens)
import Control.Lens.Plated (Plated(..))
import Control.Lens.Prism (_Just, _Left, _Right)
import Control.Lens.Setter ((.~), mapped, over)
import Control.Lens.Traversal (Traversal, failing, traverseOf)
import Control.Lens.Tuple (_2)
import Data.Bifunctor (bimap)
import Data.Bifoldable (bifoldMap)
import Data.Bitraversable (bitraverse)
import Data.Coerce (coerce)
import Data.Digit.Integral (integralDecDigits)
import Data.Function ((&))
import Data.Generics.Product.Typed (typed)
import Data.List.NonEmpty (NonEmpty)
import Data.Maybe (isNothing)
import Data.Monoid ((<>))
import Data.String (IsString(..))
import GHC.Generics (Generic)
import Unsafe.Coerce (unsafeCoerce)
import Language.Python.Optics.Validated (Validated(..))
import Language.Python.Syntax.Ann
import Language.Python.Syntax.CommaSep
import Language.Python.Syntax.Ident
import Language.Python.Syntax.Numbers
import Language.Python.Syntax.Operator.Binary
import Language.Python.Syntax.Operator.Unary
import Language.Python.Syntax.Punctuation
import Language.Python.Syntax.Strings
import Language.Python.Syntax.Whitespace
instance Validated Expr where; unvalidated = to unsafeCoerce
instance Validated Param where; unvalidated = to unsafeCoerce
instance Validated Arg where; unvalidated = to unsafeCoerce
instance Validated DictItem where; unvalidated = to unsafeCoerce
instance Validated SetItem where; unvalidated = to unsafeCoerce
instance Validated TupleItem where; unvalidated = to unsafeCoerce
instance Validated ListItem where; unvalidated = to unsafeCoerce
class HasExprs s where
_Exprs :: Traversal (s v a) (s '[] a) (Expr v a) (Expr '[] a)
data Param (v :: [*]) a
= PositionalParam
{ _paramAnn :: Ann a
, _paramName :: Ident v a
, _paramType :: Maybe (Colon, Expr v a)
}
| KeywordParam
{ _paramAnn :: Ann a
, _paramName :: Ident v a
, _paramType :: Maybe (Colon, Expr v a)
, _unsafeKeywordParamWhitespaceRight :: [Whitespace]
, _unsafeKeywordParamExpr :: Expr v a
}
| StarParam
{ _paramAnn :: Ann a
, _unsafeStarParamWhitespace :: [Whitespace]
, _unsafeStarParamName :: Ident v a
, _paramType :: Maybe (Colon, Expr v a)
}
| UnnamedStarParam
{ _paramAnn :: Ann a
, _unsafeUnnamedStarParamWhitespace :: [Whitespace]
}
| DoubleStarParam
{ _paramAnn :: Ann a
, _unsafeDoubleStarParamWhitespace :: [Whitespace]
, _paramName :: Ident v a
, _paramType :: Maybe (Colon, Expr v a)
}
deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (Param v) where
annot :: forall a. Lens' (Param v a) (Ann a)
annot = typed @(Ann a)
instance IsString (Param '[] ()) where
fromString a = PositionalParam (Ann ()) (fromString a) Nothing
instance HasTrailingWhitespace (Param v a) where
trailingWhitespace =
lens
(\case
PositionalParam _ a b ->
maybe (a ^. trailingWhitespace) (^. _2.trailingWhitespace) b
KeywordParam _ _ _ _ a -> a ^. trailingWhitespace
UnnamedStarParam _ a -> a
StarParam _ _ b c ->
maybe
(b ^. trailingWhitespace)
(^. _2.trailingWhitespace)
c
DoubleStarParam _ _ a b ->
maybe
(a ^. trailingWhitespace)
(^. _2.trailingWhitespace)
b)
(\p ws -> case p of
PositionalParam a b c ->
PositionalParam a
(if isNothing c then b & trailingWhitespace .~ ws else b)
(c & _Just._2.trailingWhitespace .~ ws)
KeywordParam a b c d e ->
KeywordParam a b c d $ e & trailingWhitespace .~ ws
UnnamedStarParam a _ -> UnnamedStarParam a ws
StarParam a b c d ->
StarParam a
b
(if isNothing d then c & trailingWhitespace .~ ws else c)
(d & _Just._2.trailingWhitespace .~ ws)
DoubleStarParam a b c d ->
DoubleStarParam a b
(if isNothing d then c & trailingWhitespace .~ ws else c)
(d & _Just._2.trailingWhitespace .~ ws))
paramAnn :: Lens' (Param v a) a
paramAnn = lens (getAnn . _paramAnn) (\s a -> s { _paramAnn = Ann a})
paramType_
:: Functor f
=> (Maybe (Colon, Expr v a) -> f (Maybe (Colon, Expr '[] a)))
-> Param v a -> f (Param '[] a)
paramType_ =
lens
(\case
UnnamedStarParam{} -> Nothing
a -> _paramType a)
(\s ty -> case s ^. unvalidated of
PositionalParam a b _ -> PositionalParam a b ty
KeywordParam a b _ c d -> KeywordParam a b ty c d
StarParam a b c _ -> StarParam a b c ty
UnnamedStarParam a b -> UnnamedStarParam a b
DoubleStarParam a b c _ -> DoubleStarParam a b c ty)
paramType :: Traversal (Param v a) (Param '[] a) (Colon, Expr v a) (Colon, Expr '[] a)
paramType = paramType_._Just
paramName :: Traversal (Param v a) (Param '[] a) (Ident v a) (Ident '[] a)
paramName f (PositionalParam a b c) =
PositionalParam a <$> f b <*> pure (over (mapped._2) (view unvalidated) c)
paramName f (KeywordParam a b c d e) =
(\b' -> KeywordParam a b' (over (mapped._2) (view unvalidated) c) d (e ^. unvalidated)) <$>
f b
paramName f (StarParam a b c d) =
(\c' -> StarParam a b c' (over (mapped._2) (view unvalidated) d)) <$>
f c
paramName _ (UnnamedStarParam a b) = pure $ UnnamedStarParam a b
paramName f (DoubleStarParam a b c d) =
(\c' -> DoubleStarParam a b c' (over (mapped._2) (view unvalidated) d)) <$>
f c
instance HasExprs Param where
_Exprs f (KeywordParam a name ty ws2 expr) =
KeywordParam a (coerce name) <$>
traverseOf (traverse._2) f ty <*>
pure ws2 <*>
f expr
_Exprs f (PositionalParam a b c) =
PositionalParam a (coerce b) <$> traverseOf (traverse._2) f c
_Exprs f (StarParam a b c d) =
StarParam a b (coerce c) <$> traverseOf (traverse._2) f d
_Exprs _ (UnnamedStarParam a b) = pure $ UnnamedStarParam a b
_Exprs f (DoubleStarParam a b c d) =
DoubleStarParam a b (coerce c) <$> traverseOf (traverse._2) f d
data Arg (v :: [*]) a
= PositionalArg
{ _argAnn :: Ann a
, _argExpr :: Expr v a
}
| KeywordArg
{ _argAnn :: Ann a
, _unsafeKeywordArgName :: Ident v a
, _unsafeKeywordArgWhitespaceRight :: [Whitespace]
, _argExpr :: Expr v a
}
| StarArg
{ _argAnn :: Ann a
, _unsafeStarArgWhitespace :: [Whitespace]
, _argExpr :: Expr v a
}
| DoubleStarArg
{ _argAnn :: Ann a
, _unsafeDoubleStarArgWhitespace :: [Whitespace]
, _argExpr :: Expr v a
}
deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (Arg v) where
annot :: forall a. Lens' (Arg v a) (Ann a)
annot = typed @(Ann a)
instance IsString (Arg '[] ()) where
fromString = PositionalArg (Ann ()) . fromString
argExpr :: Lens (Arg v a) (Arg '[] a) (Expr v a) (Expr '[] a)
argExpr = lens _argExpr (\s a -> (s ^. unvalidated) { _argExpr = a })
instance HasExprs Arg where
_Exprs f (KeywordArg a name ws2 expr) = KeywordArg a (coerce name) ws2 <$> f expr
_Exprs f (PositionalArg a expr) = PositionalArg a <$> f expr
_Exprs f (StarArg a ws expr) = StarArg a ws <$> f expr
_Exprs f (DoubleStarArg a ws expr) = StarArg a ws <$> f expr
data Comprehension e (v :: [*]) a
= Comprehension
(Ann a)
(e v a)
(CompFor v a)
[Either (CompFor v a) (CompIf v a)]
deriving (Eq, Show, Generic)
instance HasAnn (Comprehension e v) where
annot :: forall a. Lens' (Comprehension e v a) (Ann a)
annot = typed @(Ann a)
instance HasTrailingWhitespace (Comprehension e v a) where
trailingWhitespace =
lens
(\(Comprehension _ _ a b) ->
case b of
[] -> a ^. trailingWhitespace
_ -> b ^?! _last.failing (_Left.trailingWhitespace) (_Right.trailingWhitespace))
(\(Comprehension a b c d) ws ->
case d of
[] -> Comprehension a b (c & trailingWhitespace .~ ws) d
_ ->
Comprehension a b c
(d &
_last.failing (_Left.trailingWhitespace) (_Right.trailingWhitespace) .~ ws))
instance Functor (e v) => Functor (Comprehension e v) where
fmap f (Comprehension a b c d) =
Comprehension (f <$> a) (fmap f b) (fmap f c) (fmap (bimap (fmap f) (fmap f)) d)
instance Foldable (e v) => Foldable (Comprehension e v) where
foldMap f (Comprehension a b c d) =
foldMap f a <> foldMap f b <> foldMap f c <> foldMap (bifoldMap (foldMap f) (foldMap f)) d
instance Traversable (e v) => Traversable (Comprehension e v) where
traverse f (Comprehension a b c d) =
Comprehension <$>
traverse f a <*>
traverse f b <*>
traverse f c <*>
traverse (bitraverse (traverse f) (traverse f)) d
data CompIf (v :: [*]) a
= CompIf (Ann a) [Whitespace] (Expr v a)
deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (CompIf v) where
annot :: forall a. Lens' (CompIf v a) (Ann a)
annot = typed @(Ann a)
instance HasTrailingWhitespace (CompIf v a) where
trailingWhitespace =
lens
(\(CompIf _ _ a) -> a ^. trailingWhitespace)
(\(CompIf a b c) ws -> CompIf a b $ c & trailingWhitespace .~ ws)
data CompFor (v :: [*]) a
= CompFor (Ann a) [Whitespace] (Expr v a) [Whitespace] (Expr v a)
deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (CompFor v) where
annot :: forall a. Lens' (CompFor v a) (Ann a)
annot = typed @(Ann a)
instance HasTrailingWhitespace (CompFor v a) where
trailingWhitespace =
lens
(\(CompFor _ _ _ _ a) -> a ^. trailingWhitespace)
(\(CompFor a b c d e) ws -> CompFor a b c d $ e & trailingWhitespace .~ ws)
data DictItem (v :: [*]) a
= DictItem
{ _dictItemAnn :: Ann a
, _unsafeDictItemKey :: Expr v a
, _unsafeDictItemColon :: Colon
, _unsafeDictItemValue :: Expr v a
}
| DictUnpack
{ _dictItemAnn :: Ann a
, _unsafeDictItemUnpackWhitespace :: [Whitespace]
, _unsafeDictItemUnpackValue :: Expr v a
} deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (DictItem v) where
annot :: forall a. Lens' (DictItem v a) (Ann a)
annot = typed @(Ann a)
instance HasTrailingWhitespace (DictItem v a) where
trailingWhitespace =
lens
(\(DictItem _ _ _ a) -> a ^. trailingWhitespace)
(\(DictItem a b c d) ws -> DictItem a b c (d & trailingWhitespace .~ ws))
data Subscript (v :: [*]) a
= SubscriptExpr (Expr v a)
| SubscriptSlice
(Maybe (Expr v a))
Colon
(Maybe (Expr v a))
(Maybe (Colon, Maybe (Expr v a)))
deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasTrailingWhitespace (Subscript v a) where
trailingWhitespace =
lens
(\case
SubscriptExpr e -> e ^. trailingWhitespace
SubscriptSlice _ b c d ->
case d of
Nothing ->
case c of
Nothing -> b ^. trailingWhitespace
Just e -> e ^. trailingWhitespace
Just (e, f) ->
case f of
Nothing -> e ^. trailingWhitespace
Just g -> g ^. trailingWhitespace)
(\x ws ->
case x of
SubscriptExpr e -> SubscriptExpr $ e & trailingWhitespace .~ ws
SubscriptSlice a b c d ->
(\(b', c', d') -> SubscriptSlice a b' c' d') $
case d of
Nothing ->
case c of
Nothing -> (MkColon ws, c, d)
Just e -> (b, Just $ e & trailingWhitespace .~ ws, d)
Just (e, f) ->
case f of
Nothing -> (b, c, Just (MkColon ws, f))
Just g -> (b, c, Just (e, Just $ g & trailingWhitespace .~ ws)))
data ListItem (v :: [*]) a
= ListItem
{ _listItemAnn :: Ann a
, _unsafeListItemValue :: Expr v a
}
| ListUnpack
{ _listItemAnn :: Ann a
, _unsafeListUnpackParens :: [([Whitespace], [Whitespace])]
, _unsafeListUnpackWhitespace :: [Whitespace]
, _unsafeListUnpackValue :: Expr v a
} deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (ListItem v) where
annot :: forall a. Lens' (ListItem v a) (Ann a)
annot = typed @(Ann a)
instance HasExprs ListItem where
_Exprs f (ListItem a b) = ListItem a <$> f b
_Exprs f (ListUnpack a b c d) = ListUnpack a b c <$> f d
instance HasTrailingWhitespace (ListItem v a) where
trailingWhitespace =
lens
(\case
ListItem _ a -> a ^. trailingWhitespace
ListUnpack _ [] _ a -> a ^. trailingWhitespace
ListUnpack _ ((_, ws) : _) _ _ -> ws)
(\a ws ->
case a of
ListItem b c -> ListItem b $ c & trailingWhitespace .~ ws
ListUnpack b [] d e -> ListUnpack b [] d $ e & trailingWhitespace .~ ws
ListUnpack b ((c, _) : rest) e f -> ListUnpack b ((c, ws) : rest) e f)
data SetItem (v :: [*]) a
= SetItem
{ _setItemAnn :: Ann a
, _unsafeSetItemValue :: Expr v a
}
| SetUnpack
{ _setItemAnn :: Ann a
, _unsafeSetUnpackParens :: [([Whitespace], [Whitespace])]
, _unsafeSetUnpackWhitespace :: [Whitespace]
, _unsafeSetUnpackValue :: Expr v a
} deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (SetItem v) where
annot :: forall a. Lens' (SetItem v a) (Ann a)
annot = typed @(Ann a)
instance HasExprs SetItem where
_Exprs f (SetItem a b) = SetItem a <$> f b
_Exprs f (SetUnpack a b c d) = SetUnpack a b c <$> f d
instance HasTrailingWhitespace (SetItem v a) where
trailingWhitespace =
lens
(\case
SetItem _ a -> a ^. trailingWhitespace
SetUnpack _ [] _ a -> a ^. trailingWhitespace
SetUnpack _ ((_, ws) : _) _ _ -> ws)
(\a ws ->
case a of
SetItem b c -> SetItem b $ c & trailingWhitespace .~ ws
SetUnpack b [] d e -> SetUnpack b [] d $ e & trailingWhitespace .~ ws
SetUnpack b ((c, _) : rest) e f -> SetUnpack b ((c, ws) : rest) e f)
data TupleItem (v :: [*]) a
= TupleItem
{ _tupleItemAnn :: Ann a
, _unsafeTupleItemValue :: Expr v a
}
| TupleUnpack
{ _tupleItemAnn :: Ann a
, _unsafeTupleUnpackParens :: [([Whitespace], [Whitespace])]
, _unsafeTupleUnpackWhitespace :: [Whitespace]
, _unsafeTupleUnpackValue :: Expr v a
} deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (TupleItem v) where
annot :: forall a. Lens' (TupleItem v a) (Ann a)
annot = typed @(Ann a)
instance HasExprs TupleItem where
_Exprs f (TupleItem a b) = TupleItem a <$> f b
_Exprs f (TupleUnpack a b c d) = TupleUnpack a b c <$> f d
instance HasTrailingWhitespace (TupleItem v a) where
trailingWhitespace =
lens
(\case
TupleItem _ a -> a ^. trailingWhitespace
TupleUnpack _ [] _ a -> a ^. trailingWhitespace
TupleUnpack _ ((_, ws) : _) _ _ -> ws)
(\a ws ->
case a of
TupleItem b c -> TupleItem b $ c & trailingWhitespace .~ ws
TupleUnpack b [] d e -> TupleUnpack b [] d $ e & trailingWhitespace .~ ws
TupleUnpack b ((c, _) : rest) e f -> TupleUnpack b ((c, ws) : rest) e f)
data Expr (v :: [*]) a
= Unit
{ _unsafeExprAnn :: Ann a
, _unsafeUnitWhitespaceInner :: [Whitespace]
, _unsafeUnitWhitespaceRight :: [Whitespace]
}
| Lambda
{ _unsafeExprAnn :: Ann a
, _unsafeLambdaWhitespace :: [Whitespace]
, _unsafeLambdaArgs :: CommaSep (Param v a)
, _unsafeLambdaColon :: Colon
, _unsafeLambdaBody :: Expr v a
}
| Yield
{ _unsafeExprAnn :: Ann a
, _unsafeYieldWhitespace :: [Whitespace]
, _unsafeYieldValue :: CommaSep (Expr v a)
}
| YieldFrom
{ _unsafeExprAnn :: Ann a
, _unsafeYieldWhitespace :: [Whitespace]
, _unsafeFromWhitespace :: [Whitespace]
, _unsafeYieldFromValue :: Expr v a
}
| Ternary
{ _unsafeExprAnn :: Ann a
, _unsafeTernaryValue :: Expr v a
, _unsafeTernaryWhitespaceIf :: [Whitespace]
, _unsafeTernaryCond :: Expr v a
, _unsafeTernaryWhitespaceElse :: [Whitespace]
, _unsafeTernaryElse :: Expr v a
}
| ListComp
{ _unsafeExprAnn :: Ann a
, _unsafeListCompWhitespaceLeft :: [Whitespace]
, _unsafeListCompValue :: Comprehension Expr v a
, _unsafeListCompWhitespaceRight :: [Whitespace]
}
| List
{ _unsafeExprAnn :: Ann a
, _unsafeListWhitespaceLeft :: [Whitespace]
, _unsafeListValues :: Maybe (CommaSep1' (ListItem v a))
, _unsafeListWhitespaceRight :: [Whitespace]
}
| DictComp
{ _unsafeExprAnn :: Ann a
, _unsafeDictCompWhitespaceLeft :: [Whitespace]
, _unsafeDictCompValue :: Comprehension DictItem v a
, _unsafeDictCompWhitespaceRight :: [Whitespace]
}
| Dict
{ _unsafeExprAnn :: Ann a
, _unsafeDictWhitespaceLeft :: [Whitespace]
, _unsafeDictValues :: Maybe (CommaSep1' (DictItem v a))
, _unsafeDictWhitespaceRight :: [Whitespace]
}
| SetComp
{ _unsafeExprAnn :: Ann a
, _unsafeSetCompWhitespaceLeft :: [Whitespace]
, _unsafeSetCompValue :: Comprehension SetItem v a
, _unsafeSetCompWhitespaceRight :: [Whitespace]
}
| Set
{ _unsafeExprAnn :: Ann a
, _unsafeSetWhitespaceLeft :: [Whitespace]
, _unsafeSetValues :: CommaSep1' (SetItem v a)
, _unsafeSetWhitespaceRight :: [Whitespace]
}
| Deref
{ _unsafeExprAnn :: Ann a
, _unsafeDerefValueLeft :: Expr v a
, _unsafeDerefWhitespaceLeft :: [Whitespace]
, _unsafeDerefValueRight :: Ident v a
}
| Subscript
{ _unsafeExprAnn :: Ann a
, _unsafeSubscriptValueLeft :: Expr v a
, _unsafeSubscriptWhitespaceLeft :: [Whitespace]
, _unsafeSubscriptValueRight :: CommaSep1' (Subscript v a)
, _unsafeSubscriptWhitespaceRight :: [Whitespace]
}
| Call
{ _unsafeExprAnn :: Ann a
, _unsafeCallFunction :: Expr v a
, _unsafeCallWhitespaceLeft :: [Whitespace]
, _unsafeCallArguments :: Maybe (CommaSep1' (Arg v a))
, _unsafeCallWhitespaceRight :: [Whitespace]
}
| None
{ _unsafeExprAnn :: Ann a
, _unsafeNoneWhitespace :: [Whitespace]
}
| Ellipsis
{ _unsafeExprAnn :: Ann a
, _unsafeEllipsisWhitespace :: [Whitespace]
}
| BinOp
{ _unsafeExprAnn :: Ann a
, _unsafeBinOpExprLeft :: Expr v a
, _unsafeBinOpOp :: BinOp a
, _unsafeBinOpExprRight :: Expr v a
}
| UnOp
{ _exprAnn :: Ann a
, _unsafeUnOpOp :: UnOp a
, _unsafeUnOpValue :: Expr v a
}
| Parens
{ _exprAnn :: Ann a
, _unsafeParensWhitespaceLeft :: [Whitespace]
, _unsafeParensValue :: Expr v a
, _unsafeParensWhitespaceAfter :: [Whitespace]
}
| Ident
{ _exprAnn :: Ann a
, _unsafeIdentValue :: Ident v a
}
| Int
{ _exprAnn :: Ann a
, _unsafeIntValue :: IntLiteral a
, _unsafeIntWhitespace :: [Whitespace]
}
| Float
{ _exprAnn :: Ann a
, _unsafeFloatValue :: FloatLiteral a
, _unsafeFloatWhitespace :: [Whitespace]
}
| Imag
{ _exprAnn :: Ann a
, _unsafeImagValue :: ImagLiteral a
, _unsafeImagWhitespace :: [Whitespace]
}
| Bool
{ _exprAnn :: Ann a
, _unsafeBoolValue :: Bool
, _unsafeBoolWhitespace :: [Whitespace]
}
| String
{ _exprAnn :: Ann a
, _unsafeStringValue :: NonEmpty (StringLiteral a)
}
| Tuple
{ _exprAnn :: Ann a
, _unsafeTupleHead :: TupleItem v a
, _unsafeTupleWhitespace :: Comma
, _unsafeTupleTail :: Maybe (CommaSep1' (TupleItem v a))
}
| Not
{ _exprAnn :: Ann a
, _unsafeNotWhitespace :: [Whitespace]
, _unsafeNotValue :: Expr v a
}
| Generator
{ _exprAnn :: Ann a
, _generatorValue :: Comprehension Expr v a
}
| Await
{ _exprAnn :: Ann a
, _unsafeAwaitWhitespace :: [Whitespace]
, _unsafeAwaitValue :: Expr v a
}
deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
instance HasAnn (Expr v) where
annot :: forall a. Lens' (Expr v a) (Ann a)
annot = typed @(Ann a)
instance HasTrailingWhitespace (Expr v a) where
trailingWhitespace =
lens
(\case
Unit _ _ a -> a
Lambda _ _ _ _ a -> a ^. trailingWhitespace
Yield _ ws CommaSepNone -> ws
Yield _ _ e -> e ^?! csTrailingWhitespace
YieldFrom _ _ _ e -> e ^. trailingWhitespace
Ternary _ _ _ _ _ e -> e ^. trailingWhitespace
None _ ws -> ws
Ellipsis _ ws -> ws
List _ _ _ ws -> ws
ListComp _ _ _ ws -> ws
Deref _ _ _ a -> a ^. trailingWhitespace
Subscript _ _ _ _ ws -> ws
Call _ _ _ _ ws -> ws
BinOp _ _ _ e -> e ^. trailingWhitespace
UnOp _ _ e -> e ^. trailingWhitespace
Parens _ _ _ ws -> ws
Ident _ a -> a ^. getting trailingWhitespace
Int _ _ ws -> ws
Float _ _ ws -> ws
Imag _ _ ws -> ws
Bool _ _ ws -> ws
String _ v -> v ^. trailingWhitespace
Not _ _ e -> e ^. trailingWhitespace
Tuple _ _ (MkComma ws) Nothing -> ws
Tuple _ _ _ (Just cs) -> cs ^. trailingWhitespace
DictComp _ _ _ ws -> ws
Dict _ _ _ ws -> ws
SetComp _ _ _ ws -> ws
Set _ _ _ ws -> ws
Generator _ a -> a ^. trailingWhitespace
Await _ _ e -> e ^. trailingWhitespace)
(\e ws ->
case e of
Unit a b _ -> Unit a b ws
Lambda a b c d f -> Lambda a b c d (f & trailingWhitespace .~ ws)
Yield a _ CommaSepNone -> Yield a ws CommaSepNone
Yield a b c -> Yield a b (c & csTrailingWhitespace .~ ws)
YieldFrom a b c d -> YieldFrom a b c (d & trailingWhitespace .~ ws)
Ternary a b c d e f -> Ternary a b c d e (f & trailingWhitespace .~ ws)
None a _ -> None a ws
Ellipsis a _ -> Ellipsis a ws
List a b c _ -> List a b (coerce c) ws
ListComp a b c _ -> ListComp a b (coerce c) ws
Deref a b c d -> Deref a (coerce b) c (d & trailingWhitespace .~ ws)
Subscript a b c d _ -> Subscript a (coerce b) c d ws
Call a b c d _ -> Call a (coerce b) c (coerce d) ws
BinOp a b c e -> BinOp a (coerce b) c (e & trailingWhitespace .~ ws)
UnOp a b c -> UnOp a b (c & trailingWhitespace .~ ws)
Parens a b c _ -> Parens a b (coerce c) ws
Ident a b -> Ident a $ b & trailingWhitespace .~ ws
Int a b _ -> Int a b ws
Float a b _ -> Float a b ws
Imag a b _ -> Imag a b ws
Bool a b _ -> Bool a b ws
String a v -> String a (v & trailingWhitespace .~ ws)
Not a b c -> Not a b (c & trailingWhitespace .~ ws)
Tuple a b _ Nothing -> Tuple a (coerce b) (MkComma ws) Nothing
Tuple a b c (Just cs) ->
Tuple a (coerce b) c (Just $ cs & trailingWhitespace .~ ws)
DictComp a b c _ -> DictComp a b c ws
Dict a b c _ -> Dict a b c ws
SetComp a b c _ -> SetComp a b c ws
Set a b c _ -> Set a b c ws
Generator a b -> Generator a $ b & trailingWhitespace .~ ws
Await a b c -> Await a b (c & trailingWhitespace .~ ws))
instance IsString (Expr '[] ()) where
fromString s = Ident (Ann ()) $ MkIdent (Ann ()) s []
instance Num (Expr '[] ()) where
fromInteger n
| n >= 0 = Int (Ann ()) (IntLiteralDec (Ann ()) $ integralDecDigits n ^?! _Right) []
| otherwise =
UnOp
(Ann ())
(Negate (Ann ()) [])
(Int (Ann ()) (IntLiteralDec (Ann ()) $ integralDecDigits (-n) ^?! _Right) [])
negate = UnOp (Ann ()) (Negate (Ann ()) [])
(+) a = BinOp (Ann ()) (a & trailingWhitespace .~ [Space]) (Plus (Ann ()) [Space])
(*) a = BinOp (Ann ()) (a & trailingWhitespace .~ [Space]) (Multiply (Ann ()) [Space])
(-) a = BinOp (Ann ()) (a & trailingWhitespace .~ [Space]) (Minus (Ann ()) [Space])
signum = undefined
abs = undefined
instance Plated (Expr '[] a) where
plate fun e =
case e of
Unit{} -> pure e
Lambda a b c d e ->
(\c' -> Lambda a b c' d) <$>
(traverse.paramExpr) fun c <*>
fun e
Yield a b c ->
Yield a b <$> traverse fun c
YieldFrom a b c d ->
YieldFrom a b c <$> fun d
Ternary a b c d e f ->
(\b' d' -> Ternary a b' c d' e) <$>
fun b <*>
fun d <*>
fun f
None{} -> pure e
Ellipsis{} -> pure e
List a b c d ->
(\c' -> List a b c' d) <$>
(traverse.traverse.listItemExpr) fun c
ListComp a b c d ->
(\c' -> ListComp a b c' d) <$>
compExpr fun c
Deref a b c d ->
(\b' -> Deref a b' c d) <$>
fun b
Subscript a b c d e ->
(\b' d' -> Subscript a b' c d' e) <$>
fun b <*>
(traverse.subscriptExpr) fun d
Call a b c d e ->
(\b' d' -> Call a b' c d' e) <$>
fun b <*>
(traverse.traverse.argExpr) fun d
BinOp a b c d ->
(\b' -> BinOp a b' c) <$>
fun b <*>
fun d
UnOp a b c ->
UnOp a b <$> fun c
Parens a b c d ->
(\c' -> Parens a b c' d) <$>
fun c
Ident{} -> pure e
Int{} -> pure e
Float{} -> pure e
Imag{} -> pure e
Bool{} -> pure e
String{} -> pure e
Not a b c -> Not a b <$> fun c
Tuple a b c d ->
(\b' -> Tuple a b' c) <$>
tupleItemExpr fun b <*>
(traverse.traverse.tupleItemExpr) fun d
DictComp a b c d ->
(\c' -> DictComp a b c' d) <$>
dictCompExpr fun c
Dict a b c d ->
(\c' -> Dict a b c' d) <$>
(traverse.traverse.dictItemExpr) fun c
SetComp a b c d ->
(\c' -> SetComp a b c' d) <$>
setCompExpr fun c
Set a b c d ->
(\c' -> Set a b c' d) <$>
(traverse.setItemExpr) fun c
Generator a b -> Generator a <$> compExpr fun b
Await a b c -> Await a b <$> fun c
where
paramExpr fun' p =
case p of
PositionalParam a b c ->
PositionalParam a b <$>
(traverse._2) fun' c
KeywordParam a b c d e ->
(\c' -> KeywordParam a b c' d) <$>
(traverse._2) fun' c <*>
fun' e
UnnamedStarParam{} -> pure p
StarParam a b c d ->
StarParam a b c <$> (traverse._2) fun' d
DoubleStarParam a b c d ->
DoubleStarParam a b c <$> (traverse._2) fun' d
listItemExpr fun' li =
case li of
ListItem a b -> ListItem a <$> fun' b
ListUnpack a b c d -> ListUnpack a b c <$> fun' d
tupleItemExpr fun' ti =
case ti of
TupleItem a b -> TupleItem a <$> fun' b
TupleUnpack a b c d -> TupleUnpack a b c <$> fun' d
setItemExpr fun' si =
case si of
SetItem a b -> SetItem a <$> fun' b
SetUnpack a b c d -> SetUnpack a b c <$> fun' d
dictItemExpr fun' di =
case di of
DictItem a b c d ->
(\b' -> DictItem a b' c) <$>
fun' b <*>
fun' d
DictUnpack a b c -> DictUnpack a b <$> fun' c
compIfExpr fun' (CompIf a b c) = CompIf a b <$> fun' c
compForExpr fun' (CompFor a b c d e) =
(\c' -> CompFor a b c' d) <$>
fun' c <*>
fun' e
compExpr fun' (Comprehension a b c d) =
Comprehension a <$>
fun' b <*>
compForExpr fun' c <*>
traverse (bitraverse (compForExpr fun') (compIfExpr fun')) d
dictCompExpr fun' (Comprehension a b c d) =
Comprehension a <$>
dictItemExpr fun' b <*>
compForExpr fun' c <*>
traverse (bitraverse (compForExpr fun') (compIfExpr fun')) d
setCompExpr fun' (Comprehension a b c d) =
Comprehension a <$>
setItemExpr fun' b <*>
compForExpr fun' c <*>
traverse (bitraverse (compForExpr fun') (compIfExpr fun')) d
subscriptExpr fun' ss =
case ss of
SubscriptExpr a -> SubscriptExpr <$> fun' a
SubscriptSlice a b c d ->
(\a' -> SubscriptSlice a' b) <$>
traverse fun' a <*>
traverse fun' c <*>
(traverse._2.traverse) fun' d
argExpr fun' arg =
case arg of
PositionalArg a b -> PositionalArg a <$> fun' b
KeywordArg a b c d -> KeywordArg a b c <$> fun' d
StarArg a b c -> StarArg a b <$> fun' c
DoubleStarArg a b c -> DoubleStarArg a b <$> fun' c
instance HasExprs Expr where
_Exprs = id
shouldGroupLeft :: BinOp a -> Expr v a -> Bool
shouldGroupLeft op left =
let
entry = lookupOpEntry op operatorTable
lEntry =
case left of
BinOp _ _ lOp _ -> Just $ lookupOpEntry lOp operatorTable
_ -> Nothing
leftf =
case entry ^. opAssoc of
R | Just (OpEntry _ prec R) <- lEntry -> prec <= entry ^. opPrec
_ -> False
leftf' =
case (left, op) of
(UnOp{}, Exp{}) -> True
(Tuple{}, _) -> True
(Not{}, BoolAnd{}) -> False
(Not{}, BoolOr{}) -> False
(Not{}, _) -> True
_ -> maybe False (\p -> p < entry ^. opPrec) (lEntry ^? _Just.opPrec)
in
leftf || leftf'
shouldGroupRight :: BinOp a -> Expr v a -> Bool
shouldGroupRight op right =
let
entry = lookupOpEntry op operatorTable
rEntry =
case right of
BinOp _ _ rOp _ -> Just $ lookupOpEntry rOp operatorTable
_ -> Nothing
rightf =
case entry ^. opAssoc of
L | Just (OpEntry _ prec L) <- rEntry -> prec <= entry ^. opPrec
_ -> False
rightf' =
case (op, right) of
(_, Tuple{}) -> True
(BoolAnd{}, Not{}) -> False
(BoolOr{}, Not{}) -> False
(_, Not{}) -> True
_ -> maybe False (\p -> p < entry ^. opPrec) (rEntry ^? _Just.opPrec)
in
rightf || rightf'