{-# LANGUAGE Strict #-}
module Apigen.Parser.InferSizedParam (simplify) where

import           Apigen.Parser.SymbolTable (SIdToName, Sym)
import           Apigen.Types              (BuiltinType (SizeT), Decl (..))

simplify :: SIdToName -> [Sym] -> (SIdToName, [Sym])
simplify :: SIdToName -> [Sym] -> (SIdToName, [Sym])
simplify SIdToName
st [Sym]
decls = (SIdToName
st, (Sym -> Sym) -> [Sym] -> [Sym]
forall a b. (a -> b) -> [a] -> [b]
map Sym -> Sym
go [Sym]
decls)
  where
    go :: Sym -> Sym
    go :: Sym -> Sym
go (Namespace [Text]
ns [Sym]
mems) = [Text] -> [Sym] -> Sym
forall lexeme. [Text] -> [Decl lexeme] -> Decl lexeme
Namespace [Text]
ns ([Sym] -> Sym) -> [Sym] -> Sym
forall a b. (a -> b) -> a -> b
$ (Sym -> Sym) -> [Sym] -> [Sym]
forall a b. (a -> b) -> [a] -> [b]
map Sym -> Sym
go [Sym]
mems

    go (Function Sym
ret     Lexeme SId
name [Sym]
params) = Sym -> Lexeme SId -> [Sym] -> Sym
forall lexeme.
Decl lexeme -> lexeme -> [Decl lexeme] -> Decl lexeme
Function Sym
ret     Lexeme SId
name ([Sym] -> [Sym]
forall a. [a] -> [a]
reverse ([Sym] -> [Sym]) -> ([Sym] -> [Sym]) -> [Sym] -> [Sym]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Sym] -> Sym -> [Sym]) -> [Sym] -> [Sym] -> [Sym]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl [Sym] -> Sym -> [Sym]
collapse [] ([Sym] -> [Sym]) -> [Sym] -> [Sym]
forall a b. (a -> b) -> a -> b
$ [Sym]
params)
    go (CallbackTypeDecl Lexeme SId
name [Sym]
params) = Lexeme SId -> [Sym] -> Sym
forall lexeme. lexeme -> [Decl lexeme] -> Decl lexeme
CallbackTypeDecl Lexeme SId
name ([Sym] -> [Sym]
forall a. [a] -> [a]
reverse ([Sym] -> [Sym]) -> ([Sym] -> [Sym]) -> [Sym] -> [Sym]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Sym] -> Sym -> [Sym]) -> [Sym] -> [Sym] -> [Sym]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl [Sym] -> Sym -> [Sym]
collapse [] ([Sym] -> [Sym]) -> [Sym] -> [Sym]
forall a b. (a -> b) -> a -> b
$ [Sym]
params)
    go Sym
x = Sym
x

collapse :: [Sym] -> Sym -> [Sym]
collapse :: [Sym] -> Sym -> [Sym]
collapse [] Sym
p = [Sym
p]
collapse (Var (ConstArrayType BuiltinType
ty) Lexeme SId
name:[Sym]
ps) (Var (BuiltinType BuiltinType
SizeT) Lexeme SId
len) =
    Sym -> Lexeme SId -> Sym
forall lexeme. Decl lexeme -> lexeme -> Decl lexeme
Var (Sym -> Sym -> Sym
forall lexeme. Decl lexeme -> Decl lexeme -> Decl lexeme
SizedArrayType (Sym -> Sym
forall lexeme. Decl lexeme -> Decl lexeme
ConstType (BuiltinType -> Sym
forall lexeme. BuiltinType -> Decl lexeme
BuiltinType BuiltinType
ty)) (Lexeme SId -> Sym
forall lexeme. lexeme -> Decl lexeme
Ref Lexeme SId
len)) Lexeme SId
nameSym -> [Sym] -> [Sym]
forall a. a -> [a] -> [a]
:[Sym]
ps
collapse (Var (ArrayType BuiltinType
ty) Lexeme SId
name:[Sym]
ps) (Var (BuiltinType BuiltinType
SizeT) Lexeme SId
len) =
    Sym -> Lexeme SId -> Sym
forall lexeme. Decl lexeme -> lexeme -> Decl lexeme
Var (Sym -> Sym -> Sym
forall lexeme. Decl lexeme -> Decl lexeme -> Decl lexeme
SizedArrayType (BuiltinType -> Sym
forall lexeme. BuiltinType -> Decl lexeme
BuiltinType BuiltinType
ty) (Lexeme SId -> Sym
forall lexeme. lexeme -> Decl lexeme
Ref Lexeme SId
len)) Lexeme SId
nameSym -> [Sym] -> [Sym]
forall a. a -> [a] -> [a]
:[Sym]
ps
collapse [Sym]
ps Sym
p = Sym
pSym -> [Sym] -> [Sym]
forall a. a -> [a] -> [a]
:[Sym]
ps