@@ -18,14 +18,18 @@ module Language.PureScript.Declarations where
1818
1919import Data.Monoid (Monoid(..), mconcat)
2020
21+import qualified Data.Data as D
22+
23+import Control.Applicative
24+import Control.Monad
25+
2126import Language.PureScript.Types
2227import Language.PureScript.Names
2328import Language.PureScript.Kinds
2429import Language.PureScript.TypeClassDictionaries
2530import Language.PureScript.CodeGen.JS.AST
2631import Language.PureScript.Environment
27−
28−import qualified Data.Data as D
32+import Language.PureScript.Traversals
2933
3034-- |
3135-- A precedence level for an infix operator
@@ -513,6 +517,55 @@ everywhereOnValues f g h = (f', g', h')
513517 handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)
514518 handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos (handleDoNotationElement e)
515519
520+everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) =>
521+ (Declaration -> m Declaration) ->
522+ (Value -> m Value) ->
523+ (Binder -> m Binder) ->
524+ (Declaration -> m Declaration, Value -> m Value, Binder -> m Binder)
525+everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
526+ where
527+ f' (DataBindingGroupDeclaration ds) = DataBindingGroupDeclaration <$> mapM (f' <=< f) ds
528+ f' (ValueDeclaration name nameKind bs grd val) = ValueDeclaration name nameKind <$> mapM (h' <=< h) bs <*> maybeM (g' <=< g) grd <*> (g val >>= g')
529+ f' (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> (g val >>= g')) ds
530+ f' (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f' <=< f) ds
531+ f' (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f' <=< f) ds
532+ f' (PositionedDeclaration pos d) = PositionedDeclaration pos <$> (f d >>= f')
533+ f' other = f other
534+
535+ g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')
536+ g' (BinaryNoParens op v1 v2) = BinaryNoParens op <$> (g v1 >>= g') <*> (g v2 >>= g')
537+ g' (Parens v) = Parens <$> (g v >>= g')
538+ g' (ArrayLiteral vs) = ArrayLiteral <$> mapM (g' <=< g) vs
539+ g' (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g' <=< g)) vs
540+ g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
541+ g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> mapM (sndM (g' <=< g)) vs
542+ g' (Abs name v) = Abs name <$> (g v >>= g')
543+ g' (App v1 v2) = App <$> (g v1 >>= g') <*> (g v2 >>= g')
544+ g' (IfThenElse v1 v2 v3) = IfThenElse <$> (g v1 >>= g') <*> (g v2 >>= g') <*> (g v3 >>= g')
545+ g' (Case vs alts) = Case <$> mapM (g' <=< g) vs <*> mapM handleCaseAlternative alts
546+ g' (TypedValue check v ty) = TypedValue check <$> (g v >>= g') <*> pure ty
547+ g' (Let ds v) = Let <$> mapM (f' <=< f) ds <*> (g v >>= g')
548+ g' (Do es) = Do <$> mapM handleDoNotationElement es
549+ g' (PositionedValue pos v) = PositionedValue pos <$> (g v >>= g')
550+ g' other = g other
551+
552+ h' (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h' <=< h) bs
553+ h' (ObjectBinder bs) = ObjectBinder <$> mapM (sndM (h' <=< h)) bs
554+ h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs
555+ h' (ConsBinder b1 b2) = ConsBinder <$> (h b1 >>= h') <*> (h b2 >>= h')
556+ h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')
557+ h' (PositionedBinder pos b) = PositionedBinder pos <$> (h b >>= h')
558+ h' other = h other
559+
560+ handleCaseAlternative (CaseAlternative bs grd val) = CaseAlternative <$> mapM (h' <=< h) bs
561+ <*> maybeM (g' <=< g) grd
562+ <*> (g' <=< g) val
563+
564+ handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> (g' <=< g) v
565+ handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> (h' <=< h) b <*> (g' <=< g) v
566+ handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM (f' <=< f) ds
567+ handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e
568+
516569everythingOnValues :: (r -> r -> r) ->
517570 (Declaration -> r) ->
518571 (Value -> r) ->