{-# LANGUAGE LambdaCase        #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Strict            #-}
module Apigen.Parser.InferGenerated (simplify) where

import           Apigen.Parser.SymbolTable  (M, Name, SIdToName, Sym, display,
                                             mustLookupM)
import           Apigen.Types               (Decl (..), Generated (..))
import           Control.Arrow              (Arrow (first, second))
import           Control.Monad.Extra        (concatMapM)
import qualified Control.Monad.State.Strict as State
import           Data.List                  (isPrefixOf)
import qualified Data.Text                  as Text
import           Data.Tuple                 (swap)
import           Language.Cimple            (Lexeme (..))

simplify :: SIdToName -> [Sym] -> (SIdToName, [Sym])
simplify :: SIdToName -> [Sym] -> (SIdToName, [Sym])
simplify SIdToName
st = ((SIdToName, Maybe (Name, Sym)) -> SIdToName)
-> ((SIdToName, Maybe (Name, Sym)), [Sym]) -> (SIdToName, [Sym])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (SIdToName, Maybe (Name, Sym)) -> SIdToName
forall a b. (a, b) -> a
fst (((SIdToName, Maybe (Name, Sym)), [Sym]) -> (SIdToName, [Sym]))
-> ([Sym] -> ((SIdToName, Maybe (Name, Sym)), [Sym]))
-> [Sym]
-> (SIdToName, [Sym])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Sym], (SIdToName, Maybe (Name, Sym)))
-> ((SIdToName, Maybe (Name, Sym)), [Sym])
forall a b. (a, b) -> (b, a)
swap (([Sym], (SIdToName, Maybe (Name, Sym)))
 -> ((SIdToName, Maybe (Name, Sym)), [Sym]))
-> ([Sym] -> ([Sym], (SIdToName, Maybe (Name, Sym))))
-> [Sym]
-> ((SIdToName, Maybe (Name, Sym)), [Sym])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State (SIdToName, Maybe (Name, Sym)) [Sym]
 -> (SIdToName, Maybe (Name, Sym))
 -> ([Sym], (SIdToName, Maybe (Name, Sym))))
-> (SIdToName, Maybe (Name, Sym))
-> State (SIdToName, Maybe (Name, Sym)) [Sym]
-> ([Sym], (SIdToName, Maybe (Name, Sym)))
forall a b c. (a -> b -> c) -> b -> a -> c
flip State (SIdToName, Maybe (Name, Sym)) [Sym]
-> (SIdToName, Maybe (Name, Sym))
-> ([Sym], (SIdToName, Maybe (Name, Sym)))
forall s a. State s a -> s -> (a, s)
State.runState (SIdToName
st, Maybe (Name, Sym)
forall a. Maybe a
Nothing) (State (SIdToName, Maybe (Name, Sym)) [Sym]
 -> ([Sym], (SIdToName, Maybe (Name, Sym))))
-> ([Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym])
-> [Sym]
-> ([Sym], (SIdToName, Maybe (Name, Sym)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym])
-> [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym]
go
  where
    go :: Sym -> M (Maybe (Name, Sym)) [Sym]
    go :: Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym]
go (Namespace [Text]
name [Sym]
mems) = do
        ([Sym]
leftovers, [Sym]
mems') <- [Sym]
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ([Sym], [Sym])
descend [Sym]
mems
        [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym])
-> [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall a b. (a -> b) -> a -> b
$ [Sym]
leftovers [Sym] -> [Sym] -> [Sym]
forall a. [a] -> [a] -> [a]
++ [[Text] -> [Sym] -> Sym
forall lexeme. [Text] -> [Decl lexeme] -> Decl lexeme
Namespace [Text]
name [Sym]
mems']
    go (ClassDecl Lexeme SId
name [Sym]
mems) = do
        ([Sym]
leftovers, [Sym]
mems') <- [Sym]
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ([Sym], [Sym])
descend [Sym]
mems
        [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym])
-> [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall a b. (a -> b) -> a -> b
$ [Sym]
leftovers [Sym] -> [Sym] -> [Sym]
forall a. [a] -> [a] -> [a]
++ [Lexeme SId -> [Sym] -> Sym
forall lexeme. lexeme -> [Decl lexeme] -> Decl lexeme
ClassDecl Lexeme SId
name [Sym]
mems']

    go e :: Sym
e@(Enumeration [Generated]
_ (L AlexPosn
_ LexemeClass
_ SId
sid) [Sym]
_) = do
        Maybe (Name, Sym)
ctx <- (SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym)
forall a b. (a, b) -> b
snd ((SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym))
     Identity
     (SIdToName, Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym)) Identity (Maybe (Name, Sym))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT
  (SIdToName, Maybe (Name, Sym))
  Identity
  (SIdToName, Maybe (Name, Sym))
forall s (m :: * -> *). MonadState s m => m s
State.get
        case Maybe (Name, Sym)
ctx of
            Maybe (Name, Sym)
Nothing -> do
                Name
name <- ([Text] -> [Text]) -> Name -> Name
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
Text.toLower) (Name -> Name)
-> StateT (SIdToName, Maybe (Name, Sym)) Identity Name
-> StateT (SIdToName, Maybe (Name, Sym)) Identity Name
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SId -> StateT (SIdToName, Maybe (Name, Sym)) Identity Name
forall s. SId -> M s Name
mustLookupM SId
sid
                ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const (Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym))
-> Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. (a -> b) -> a -> b
$ (Name, Sym) -> Maybe (Name, Sym)
forall a. a -> Maybe a
Just (Name
name, Sym
e)
                [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return []
            Just (Name
_, Sym
esym) -> do
                ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const Maybe (Name, Sym)
forall a. Maybe a
Nothing
                (Sym
esymSym -> [Sym] -> [Sym]
forall a. a -> [a] -> [a]
:) ([Sym] -> [Sym])
-> State (SIdToName, Maybe (Name, Sym)) [Sym]
-> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym]
go Sym
e

    go f :: Sym
f@(Function Sym
_ (L AlexPosn
_ LexemeClass
_ SId
sid) [Sym]
_) = do
        Name
name <- SId -> StateT (SIdToName, Maybe (Name, Sym)) Identity Name
forall s. SId -> M s Name
mustLookupM SId
sid
        Maybe (Name, Sym)
ctx <- (SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym)
forall a b. (a, b) -> b
snd ((SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym))
     Identity
     (SIdToName, Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym)) Identity (Maybe (Name, Sym))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT
  (SIdToName, Maybe (Name, Sym))
  Identity
  (SIdToName, Maybe (Name, Sym))
forall s (m :: * -> *). MonadState s m => m s
State.get
        case Maybe (Name, Sym)
ctx of
            -- No enum currently being processed.
            Maybe (Name, Sym)
Nothing -> [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return [Sym
f]
            Just (Name
ename, Enumeration [Generated]
funs Lexeme SId
esid [Sym]
mems) | Name -> [Text]
forall a b. (a, b) -> b
snd Name
ename [Text] -> [Text] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` Name -> [Text]
forall a b. (a, b) -> b
snd Name
name -> do
                case [Text] -> [Text]
forall a. [a] -> [a]
reverse ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Name -> [Text]
forall a b. (a, b) -> b
snd Name
name of
                    (Text
"string":Text
"to":[Text]
_) -> do
                        ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const (Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym))
-> Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. (a -> b) -> a -> b
$ (Name, Sym) -> Maybe (Name, Sym)
forall a. a -> Maybe a
Just (Name
ename, [Generated] -> Lexeme SId -> [Sym] -> Sym
forall lexeme.
[Generated] -> lexeme -> [Decl lexeme] -> Decl lexeme
Enumeration (Generated
GeneratedToStringGenerated -> [Generated] -> [Generated]
forall a. a -> [a] -> [a]
:[Generated]
funs) Lexeme SId
esid [Sym]
mems)
                        [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return []
                    [Text]
_ ->
                        [Char] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall a. HasCallStack => [Char] -> a
error ([Char] -> State (SIdToName, Maybe (Name, Sym)) [Sym])
-> [Char] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall a b. (a -> b) -> a -> b
$ [Char]
"invalid enum function: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Name -> [Char]
display Name
name
            Just (Name
_, Sym
esym) -> do
                ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const Maybe (Name, Sym)
forall a. Maybe a
Nothing
                (Sym
esymSym -> [Sym] -> [Sym]
forall a. a -> [a] -> [a]
:) ([Sym] -> [Sym])
-> State (SIdToName, Maybe (Name, Sym)) [Sym]
-> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym]
go Sym
f

    go Sym
x = do
        Maybe (Name, Sym)
ctx <- (SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym)
forall a b. (a, b) -> b
snd ((SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym))
     Identity
     (SIdToName, Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym)) Identity (Maybe (Name, Sym))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT
  (SIdToName, Maybe (Name, Sym))
  Identity
  (SIdToName, Maybe (Name, Sym))
forall s (m :: * -> *). MonadState s m => m s
State.get
        case Maybe (Name, Sym)
ctx of
            Maybe (Name, Sym)
Nothing -> [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return [Sym
x]
            Just (Name
_, Sym
esym) -> do
                ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const Maybe (Name, Sym)
forall a. Maybe a
Nothing
                (Sym
esymSym -> [Sym] -> [Sym]
forall a. a -> [a] -> [a]
:) ([Sym] -> [Sym])
-> State (SIdToName, Maybe (Name, Sym)) [Sym]
-> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym]
go Sym
x


    descend :: [Sym]
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ([Sym], [Sym])
descend [Sym]
mems = do
        Maybe (Name, Sym)
ctx <- (SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym)
forall a b. (a, b) -> b
snd ((SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym))
     Identity
     (SIdToName, Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym)) Identity (Maybe (Name, Sym))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT
  (SIdToName, Maybe (Name, Sym))
  Identity
  (SIdToName, Maybe (Name, Sym))
forall s (m :: * -> *). MonadState s m => m s
State.get
        [Sym]
leftovers <- case Maybe (Name, Sym)
ctx of
            Maybe (Name, Sym)
Nothing -> [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return []
            Just (Name
_, Sym
esym) -> do
                ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const Maybe (Name, Sym)
forall a. Maybe a
Nothing
                [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a. Monad m => a -> m a
return [Sym
esym]
        ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const Maybe (Name, Sym)
forall a. Maybe a
Nothing
        [Sym]
res <- (Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym])
-> [Sym] -> State (SIdToName, Maybe (Name, Sym)) [Sym]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM Sym -> State (SIdToName, Maybe (Name, Sym)) [Sym]
go [Sym]
mems
        Maybe (Name, Sym)
ctx' <- (SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym)
forall a b. (a, b) -> b
snd ((SIdToName, Maybe (Name, Sym)) -> Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym))
     Identity
     (SIdToName, Maybe (Name, Sym))
-> StateT
     (SIdToName, Maybe (Name, Sym)) Identity (Maybe (Name, Sym))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT
  (SIdToName, Maybe (Name, Sym))
  Identity
  (SIdToName, Maybe (Name, Sym))
forall s (m :: * -> *). MonadState s m => m s
State.get
        case Maybe (Name, Sym)
ctx' of
            Maybe (Name, Sym)
Nothing -> ([Sym], [Sym])
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ([Sym], [Sym])
forall (m :: * -> *) a. Monad m => a -> m a
return ([Sym]
leftovers, [Sym]
res)
            Just (Name
_, Sym
esym) -> do
                ((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
State.modify (((SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym)))
 -> StateT (SIdToName, Maybe (Name, Sym)) Identity ())
-> ((SIdToName, Maybe (Name, Sym))
    -> (SIdToName, Maybe (Name, Sym)))
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ()
forall a b. (a -> b) -> a -> b
$ (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym)) -> (SIdToName, Maybe (Name, Sym))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ((Maybe (Name, Sym) -> Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym))
 -> (SIdToName, Maybe (Name, Sym)))
-> (Maybe (Name, Sym) -> Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
-> (SIdToName, Maybe (Name, Sym))
forall a b. (a -> b) -> a -> b
$ Maybe (Name, Sym) -> Maybe (Name, Sym) -> Maybe (Name, Sym)
forall a b. a -> b -> a
const Maybe (Name, Sym)
forall a. Maybe a
Nothing
                ([Sym], [Sym])
-> StateT (SIdToName, Maybe (Name, Sym)) Identity ([Sym], [Sym])
forall (m :: * -> *) a. Monad m => a -> m a
return ([Sym]
leftovers, [Sym]
res [Sym] -> [Sym] -> [Sym]
forall a. [a] -> [a] -> [a]
++ [Sym
esym])