    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE BlockArguments #-}
    {-# LANGUAGE TupleSections #-}

    module GHC.JS.Transform
      ( identsS
      , identsV
      , identsE
      , jStgExprToJS
      , jStgStatToJS
      )
    where

    import GHC.Prelude

    import GHC.JS.Ident
    import GHC.JS.JStg.Syntax
    import qualified GHC.JS.Syntax as JS

    import Data.List (sortBy)

    import GHC.Data.FastString
    import GHC.Types.Unique.Map
    import GHC.Types.Unique.FM

    {-# INLINE identsS #-}
    identsS :: JStgStat -> [Ident]
    identsS :: JStgStat -> [Ident]
    identsS = \case
      DeclStat Ident
    i Maybe JStgExpr
    e       -> [Ident
    i] [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ [Ident] -> (JStgExpr -> [Ident]) -> Maybe JStgExpr -> [Ident]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] JStgExpr -> [Ident]
    identsE Maybe JStgExpr
    e
      ReturnStat JStgExpr
    e       -> JStgExpr -> [Ident]
    identsE JStgExpr
    e
      IfStat JStgExpr
    e JStgStat
    s1 JStgStat
    s2     -> JStgExpr -> [Ident]
    identsE JStgExpr
    e [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s1 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s2
      WhileStat Bool
    _ JStgExpr
    e JStgStat
    s    -> JStgExpr -> [Ident]
    identsE JStgExpr
    e [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s
      ForStat JStgStat
    init JStgExpr
    p JStgStat
    step JStgStat
    body -> JStgStat -> [Ident]
    identsS JStgStat
    init [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgExpr -> [Ident]
    identsE JStgExpr
    p [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    step [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    body
      ForInStat Bool
    _ Ident
    i JStgExpr
    e JStgStat
    s  -> [Ident
    i] [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgExpr -> [Ident]
    identsE JStgExpr
    e [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s
      SwitchStat JStgExpr
    e [(JStgExpr, JStgStat)]
    xs JStgStat
    s  -> JStgExpr -> [Ident]
    identsE JStgExpr
    e [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ ((JStgExpr, JStgStat) -> [Ident])
    -> [(JStgExpr, JStgStat)] -> [Ident]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (JStgExpr, JStgStat) -> [Ident]
    traverseCase [(JStgExpr, JStgStat)]
    xs [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s
                               where traverseCase :: (JStgExpr, JStgStat) -> [Ident]
    traverseCase (JStgExpr
    e,JStgStat
    s) = JStgExpr -> [Ident]
    identsE JStgExpr
    e [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s
      TryStat JStgStat
    s1 Ident
    i JStgStat
    s2 JStgStat
    s3 -> JStgStat -> [Ident]
    identsS JStgStat
    s1 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ [Ident
    i] [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s2 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s3
      BlockStat [JStgStat]
    xs       -> (JStgStat -> [Ident]) -> [JStgStat] -> [Ident]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap JStgStat -> [Ident]
    identsS [JStgStat]
    xs
      ApplStat JStgExpr
    e [JStgExpr]
    es      -> JStgExpr -> [Ident]
    identsE JStgExpr
    e [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ (JStgExpr -> [Ident]) -> [JStgExpr] -> [Ident]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap JStgExpr -> [Ident]
    identsE [JStgExpr]
    es
      UOpStat UOp
    _op JStgExpr
    e      -> JStgExpr -> [Ident]
    identsE JStgExpr
    e
      AssignStat JStgExpr
    e1 AOp
    _op JStgExpr
    e2 -> JStgExpr -> [Ident]
    identsE JStgExpr
    e1 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgExpr -> [Ident]
    identsE JStgExpr
    e2
      LabelStat JsLabel
    _l JStgStat
    s     -> JStgStat -> [Ident]
    identsS JStgStat
    s
      BreakStat{}        -> []
      ContinueStat{}     -> []
      FuncStat Ident
    i [Ident]
    args JStgStat
    body -> [Ident
    i] [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ [Ident]
    args [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    body

    {-# INLINE identsE #-}
    identsE :: JStgExpr -> [Ident]
    identsE :: JStgExpr -> [Ident]
    identsE = \case
      ValExpr JVal
    v         -> JVal -> [Ident]
    identsV JVal
    v
      SelExpr JStgExpr
    e Ident
    _i      -> JStgExpr -> [Ident]
    identsE JStgExpr
    e -- do not rename properties
      IdxExpr JStgExpr
    e1 JStgExpr
    e2     -> JStgExpr -> [Ident]
    identsE JStgExpr
    e1 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgExpr -> [Ident]
    identsE JStgExpr
    e2
      InfixExpr Op
    _ JStgExpr
    e1 JStgExpr
    e2 -> JStgExpr -> [Ident]
    identsE JStgExpr
    e1 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgExpr -> [Ident]
    identsE JStgExpr
    e2
      UOpExpr UOp
    _ JStgExpr
    e       -> JStgExpr -> [Ident]
    identsE JStgExpr
    e
      IfExpr JStgExpr
    e1 JStgExpr
    e2 JStgExpr
    e3   -> JStgExpr -> [Ident]
    identsE JStgExpr
    e1 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgExpr -> [Ident]
    identsE JStgExpr
    e2 [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgExpr -> [Ident]
    identsE JStgExpr
    e3
      ApplExpr JStgExpr
    e [JStgExpr]
    es     -> JStgExpr -> [Ident]
    identsE JStgExpr
    e  [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ (JStgExpr -> [Ident]) -> [JStgExpr] -> [Ident]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap JStgExpr -> [Ident]
    identsE [JStgExpr]
    es

    {-# INLINE identsV #-}
    identsV :: JVal -> [Ident]
    identsV :: JVal -> [Ident]
    identsV = \case
      JVar Ident
    i       -> [Ident
    i]
      JList [JStgExpr]
    xs     -> (JStgExpr -> [Ident]) -> [JStgExpr] -> [Ident]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap JStgExpr -> [Ident]
    identsE [JStgExpr]
    xs
      JDouble{}    -> []
      JInt{}       -> []
      JStr{}       -> []
      JRegEx{}     -> []
      JBool{}      -> []
      JHash UniqMap FastString JStgExpr
    m      -> (JStgExpr -> [Ident]) -> [JStgExpr] -> [Ident]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap JStgExpr -> [Ident]
    identsE (UniqMap FastString JStgExpr -> [JStgExpr]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap UniqMap FastString JStgExpr
    m)
      JFunc [Ident]
    args JStgStat
    s -> [Ident]
    args [Ident] -> [Ident] -> [Ident]
    forall a. [a] -> [a] -> [a]
    ++ JStgStat -> [Ident]
    identsS JStgStat
    s

    --------------------------------------------------------------------------------
    --                            Translation
    --
    --------------------------------------------------------------------------------
    jStgStatToJS :: JStgStat -> JS.JStat
    jStgStatToJS :: JStgStat -> JStat
    jStgStatToJS  = \case
      DeclStat Ident
    i Maybe JStgExpr
    rhs        -> Ident -> Maybe JExpr -> JStat
    JS.DeclStat Ident
    i (Maybe JExpr -> JStat) -> Maybe JExpr -> JStat
    forall a b. (a -> b) -> a -> b
    $ (JStgExpr -> JExpr) -> Maybe JStgExpr -> Maybe JExpr
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap JStgExpr -> JExpr
    jStgExprToJS Maybe JStgExpr
    rhs
      ReturnStat JStgExpr
    e          -> JExpr -> JStat
    JS.ReturnStat (JExpr -> JStat) -> JExpr -> JStat
    forall a b. (a -> b) -> a -> b
    $ JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    e
      IfStat JStgExpr
    c JStgStat
    t JStgStat
    e          -> JExpr -> JStat -> JStat -> JStat
    JS.IfStat (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    c) (JStgStat -> JStat
    jStgStatToJS JStgStat
    t) (JStgStat -> JStat
    jStgStatToJS JStgStat
    e)
      WhileStat Bool
    is_do JStgExpr
    c JStgStat
    e   -> Bool -> JExpr -> JStat -> JStat
    JS.WhileStat Bool
    is_do (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    c) (JStgStat -> JStat
    jStgStatToJS JStgStat
    e)
      ForStat JStgStat
    init JStgExpr
    p JStgStat
    step JStgStat
    body -> JStat -> JExpr -> JStat -> JStat -> JStat
    JS.ForStat  (JStgStat -> JStat
    jStgStatToJS JStgStat
    init) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    p)
                                               (JStgStat -> JStat
    jStgStatToJS JStgStat
    step) (JStgStat -> JStat
    jStgStatToJS JStgStat
    body)
      ForInStat Bool
    is_each Ident
    i JStgExpr
    iter JStgStat
    body -> Bool -> Ident -> JExpr -> JStat -> JStat
    JS.ForInStat (Bool
    is_each) Ident
    i (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    iter) (JStgStat -> JStat
    jStgStatToJS JStgStat
    body)
      SwitchStat JStgExpr
    struct [(JStgExpr, JStgStat)]
    ps JStgStat
    def -> JExpr -> [(JExpr, JStat)] -> JStat -> JStat
    JS.SwitchStat
                                  (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    struct)
                                  (((JStgExpr, JStgStat) -> (JExpr, JStat))
    -> [(JStgExpr, JStgStat)] -> [(JExpr, JStat)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(JStgExpr
    p1, JStgStat
    p2) -> (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    p1, JStgStat -> JStat
    jStgStatToJS JStgStat
    p2)) [(JStgExpr, JStgStat)]
    ps)
                                  (JStgStat -> JStat
    jStgStatToJS JStgStat
    def)
      TryStat JStgStat
    t Ident
    i JStgStat
    c JStgStat
    f       -> JStat -> Ident -> JStat -> JStat -> JStat
    JS.TryStat (JStgStat -> JStat
    jStgStatToJS JStgStat
    t) Ident
    i (JStgStat -> JStat
    jStgStatToJS JStgStat
    c) (JStgStat -> JStat
    jStgStatToJS JStgStat
    f)
      BlockStat [JStgStat]
    bs          -> [JStat] -> JStat
    JS.BlockStat ([JStat] -> JStat) -> [JStat] -> JStat
    forall a b. (a -> b) -> a -> b
    $ (JStgStat -> JStat) -> [JStgStat] -> [JStat]
    forall a b. (a -> b) -> [a] -> [b]
    map JStgStat -> JStat
    jStgStatToJS [JStgStat]
    bs
      ApplStat JStgExpr
    rator [JStgExpr]
    rand   -> JExpr -> [JExpr] -> JStat
    JS.ApplStat (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    rator) ([JExpr] -> JStat) -> [JExpr] -> JStat
    forall a b. (a -> b) -> a -> b
    $ (JStgExpr -> JExpr) -> [JStgExpr] -> [JExpr]
    forall a b. (a -> b) -> [a] -> [b]
    map JStgExpr -> JExpr
    jStgExprToJS [JStgExpr]
    rand
      UOpStat  UOp
    rator JStgExpr
    rand   -> UOp -> JExpr -> JStat
    JS.UOpStat (UOp -> UOp
    jStgUOpToJS UOp
    rator) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    rand)
      AssignStat JStgExpr
    lhs AOp
    op JStgExpr
    rhs -> JExpr -> AOp -> JExpr -> JStat
    JS.AssignStat (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    lhs) (AOp -> AOp
    jStgAOpToJS AOp
    op) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    rhs)
      LabelStat JsLabel
    lbl JStgStat
    stmt    -> JsLabel -> JStat -> JStat
    JS.LabelStat JsLabel
    lbl (JStgStat -> JStat
    jStgStatToJS JStgStat
    stmt)
      BreakStat Maybe JsLabel
    m_l         -> Maybe JsLabel -> JStat
    JS.BreakStat (Maybe JsLabel -> JStat) -> Maybe JsLabel -> JStat
    forall a b. (a -> b) -> a -> b
    $! Maybe JsLabel
    m_l
      ContinueStat Maybe JsLabel
    m_l      -> Maybe JsLabel -> JStat
    JS.ContinueStat (Maybe JsLabel -> JStat) -> Maybe JsLabel -> JStat
    forall a b. (a -> b) -> a -> b
    $! Maybe JsLabel
    m_l
      FuncStat Ident
    i [Ident]
    args JStgStat
    body  -> Ident -> [Ident] -> JStat -> JStat
    JS.FuncStat Ident
    i [Ident]
    args (JStat -> JStat) -> JStat -> JStat
    forall a b. (a -> b) -> a -> b
    $ JStgStat -> JStat
    jStgStatToJS JStgStat
    body

    jStgExprToJS :: JStgExpr -> JS.JExpr
    jStgExprToJS :: JStgExpr -> JExpr
    jStgExprToJS = \case
      ValExpr JVal
    v            -> JVal -> JExpr
    JS.ValExpr (JVal -> JExpr) -> JVal -> JExpr
    forall a b. (a -> b) -> a -> b
    $ JVal -> JVal
    jStgValToJS JVal
    v
      SelExpr JStgExpr
    obj Ident
    i        -> JExpr -> Ident -> JExpr
    JS.SelExpr (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    obj) Ident
    i
      IdxExpr JStgExpr
    o JStgExpr
    i          -> JExpr -> JExpr -> JExpr
    JS.IdxExpr (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    o) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    i)
      InfixExpr Op
    op JStgExpr
    l JStgExpr
    r     -> Op -> JExpr -> JExpr -> JExpr
    JS.InfixExpr (Op -> Op
    jStgOpToJS Op
    op) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    l) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    r)
      UOpExpr UOp
    op JStgExpr
    r         -> UOp -> JExpr -> JExpr
    JS.UOpExpr (UOp -> UOp
    jStgUOpToJS UOp
    op) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    r)
      IfExpr JStgExpr
    c JStgExpr
    t JStgExpr
    e         -> JExpr -> JExpr -> JExpr -> JExpr
    JS.IfExpr (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    c) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    t) (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    e)
      ApplExpr JStgExpr
    rator [JStgExpr]
    rands -> JExpr -> [JExpr] -> JExpr
    JS.ApplExpr (JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    rator) ([JExpr] -> JExpr) -> [JExpr] -> JExpr
    forall a b. (a -> b) -> a -> b
    $ (JStgExpr -> JExpr) -> [JStgExpr] -> [JExpr]
    forall a b. (a -> b) -> [a] -> [b]
    map JStgExpr -> JExpr
    jStgExprToJS [JStgExpr]
    rands

    jStgValToJS :: JVal -> JS.JVal
    jStgValToJS :: JVal -> JVal
    jStgValToJS = \case
      JVar Ident
    i   -> Ident -> JVal
    JS.JVar Ident
    i
      JList [JStgExpr]
    xs -> [JExpr] -> JVal
    JS.JList ([JExpr] -> JVal) -> [JExpr] -> JVal
    forall a b. (a -> b) -> a -> b
    $ (JStgExpr -> JExpr) -> [JStgExpr] -> [JExpr]
    forall a b. (a -> b) -> [a] -> [b]
    map JStgExpr -> JExpr
    jStgExprToJS [JStgExpr]
    xs
      JDouble SaneDouble
    d -> SaneDouble -> JVal
    JS.JDouble SaneDouble
    d
      JInt Integer
    i    -> Integer -> JVal
    JS.JInt   Integer
    i
      JStr FastString
    s    -> FastString -> JVal
    JS.JStr   FastString
    s
      JRegEx FastString
    f  -> FastString -> JVal
    JS.JRegEx FastString
    f
      JBool Bool
    b   -> Bool -> JVal
    JS.JBool  Bool
    b
      JHash UniqMap FastString JStgExpr
    m   -> UniqMap FastString JExpr -> JVal
    JS.JHash (UniqMap FastString JExpr -> JVal)
    -> UniqMap FastString JExpr -> JVal
    forall a b. (a -> b) -> a -> b
    $ ((FastString, JStgExpr) -> (FastString, (FastString, JExpr)))
    -> UniqMap FastString JStgExpr -> UniqMap FastString JExpr
    forall {k} {b} {a}.
    Uniquable k =>
    ((FastString, b) -> (k, (k, a)))
    -> UniqMap FastString b -> UniqMap k a
    mapUniqMapM (FastString, JStgExpr) -> (FastString, (FastString, JExpr))
    forall {t}. (t, JStgExpr) -> (t, (t, JExpr))
    satHash UniqMap FastString JStgExpr
    m
        where
          satHash :: (t, JStgExpr) -> (t, (t, JExpr))
    satHash (t
    i, JStgExpr
    x) = (t
    i,) ((t, JExpr) -> (t, (t, JExpr)))
    -> (JExpr -> (t, JExpr)) -> JExpr -> (t, (t, JExpr))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (t
    i,) (JExpr -> (t, (t, JExpr))) -> JExpr -> (t, (t, JExpr))
    forall a b. (a -> b) -> a -> b
    $ JStgExpr -> JExpr
    jStgExprToJS JStgExpr
    x
          compareHash :: (FastString, b) -> (FastString, b) -> Ordering
    compareHash (FastString
    i,b
    _) (FastString
    j,b
    _) = FastString -> FastString -> Ordering
    lexicalCompareFS FastString
    i FastString
    j
          -- By lexically sorting the elements, the non-determinism introduced by nonDetEltsUFM is avoided
          mapUniqMapM :: ((FastString, b) -> (k, (k, a)))
    -> UniqMap FastString b -> UniqMap k a
    mapUniqMapM (FastString, b) -> (k, (k, a))
    f (UniqMap UniqFM FastString (FastString, b)
    m) = UniqFM k (k, a) -> UniqMap k a
    forall k a. UniqFM k (k, a) -> UniqMap k a
    UniqMap (UniqFM k (k, a) -> UniqMap k a)
    -> ([(k, (k, a))] -> UniqFM k (k, a))
    -> [(k, (k, a))]
    -> UniqMap k a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(k, (k, a))] -> UniqFM k (k, a)
    forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
    listToUFM ([(k, (k, a))] -> UniqMap k a) -> [(k, (k, a))] -> UniqMap k a
    forall a b. (a -> b) -> a -> b
    $ (((FastString, b) -> (k, (k, a)))
    -> [(FastString, b)] -> [(k, (k, a))]
    forall a b. (a -> b) -> [a] -> [b]
    map (FastString, b) -> (k, (k, a))
    f ([(FastString, b)] -> [(k, (k, a))])
    -> ([(FastString, b)] -> [(FastString, b)])
    -> [(FastString, b)]
    -> [(k, (k, a))]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((FastString, b) -> (FastString, b) -> Ordering)
    -> [(FastString, b)] -> [(FastString, b)]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    sortBy (FastString, b) -> (FastString, b) -> Ordering
    forall {b} {b}. (FastString, b) -> (FastString, b) -> Ordering
    compareHash ([(FastString, b)] -> [(k, (k, a))])
    -> [(FastString, b)] -> [(k, (k, a))]
    forall a b. (a -> b) -> a -> b
    $ UniqFM FastString (FastString, b) -> [(FastString, b)]
    forall {k} (key :: k) elt. UniqFM key elt -> [elt]
    nonDetEltsUFM UniqFM FastString (FastString, b)
    m)
      JFunc [Ident]
    args JStgStat
    body   -> [Ident] -> JStat -> JVal
    JS.JFunc [Ident]
    args (JStat -> JVal) -> JStat -> JVal
    forall a b. (a -> b) -> a -> b
    $ JStgStat -> JStat
    jStgStatToJS JStgStat
    body

    jStgOpToJS :: Op -> JS.Op
    jStgOpToJS :: Op -> Op
    jStgOpToJS = Op -> Op
    go
      where
        go :: Op -> Op
    go Op
    EqOp         = Op
    JS.EqOp
        go Op
    StrictEqOp   = Op
    JS.StrictEqOp
        go Op
    NeqOp        = Op
    JS.NeqOp
        go Op
    StrictNeqOp  = Op
    JS.StrictNeqOp
        go Op
    GtOp         = Op
    JS.GtOp
        go Op
    GeOp         = Op
    JS.GeOp
        go Op
    LtOp         = Op
    JS.LtOp
        go Op
    LeOp         = Op
    JS.LeOp
        go Op
    AddOp        = Op
    JS.AddOp
        go Op
    SubOp        = Op
    JS.SubOp
        go Op
    MulOp        = Op
    JS.MulOp
        go Op
    DivOp        = Op
    JS.DivOp
        go Op
    ModOp        = Op
    JS.ModOp
        go Op
    LeftShiftOp  = Op
    JS.LeftShiftOp
        go Op
    RightShiftOp = Op
    JS.RightShiftOp
        go Op
    ZRightShiftOp = Op
    JS.ZRightShiftOp
        go Op
    BAndOp       = Op
    JS.BAndOp
        go Op
    BOrOp        = Op
    JS.BOrOp
        go Op
    BXorOp       = Op
    JS.BXorOp
        go Op
    LAndOp       = Op
    JS.LAndOp
        go Op
    LOrOp        = Op
    JS.LOrOp
        go Op
    InstanceofOp = Op
    JS.InstanceofOp
        go Op
    InOp         = Op
    JS.InOp

    jStgUOpToJS :: UOp -> JS.UOp
    jStgUOpToJS :: UOp -> UOp
    jStgUOpToJS = UOp -> UOp
    go
      where
        go :: UOp -> UOp
    go UOp
    NotOp     = UOp
    JS.NotOp
        go UOp
    BNotOp    = UOp
    JS.BNotOp
        go UOp
    NegOp     = UOp
    JS.NegOp
        go UOp
    PlusOp    = UOp
    JS.PlusOp
        go UOp
    NewOp     = UOp
    JS.NewOp
        go UOp
    TypeofOp  = UOp
    JS.TypeofOp
        go UOp
    DeleteOp  = UOp
    JS.DeleteOp
        go UOp
    YieldOp   = UOp
    JS.YieldOp
        go UOp
    VoidOp    = UOp
    JS.VoidOp
        go UOp
    PreIncOp  = UOp
    JS.PreIncOp
        go UOp
    PostIncOp = UOp
    JS.PostIncOp
        go UOp
    PreDecOp  = UOp
    JS.PreDecOp
        go UOp
    PostDecOp = UOp
    JS.PostDecOp

    jStgAOpToJS :: AOp -> JS.AOp
    jStgAOpToJS :: AOp -> AOp
    jStgAOpToJS AOp
    AssignOp    = AOp
    JS.AssignOp
    jStgAOpToJS AOp
    AddAssignOp = AOp
    JS.AddAssignOp
    jStgAOpToJS AOp
    SubAssignOp = AOp
    JS.SubAssignOp