module Feldspar.Core.Constructs where
import Data.Typeable
import Language.Syntactic
import Language.Syntactic.Constructs.Binding.HigherOrder
import Feldspar.Core.Types
import Feldspar.Core.Interpretation
import Feldspar.Core.Constructs.Array
import Feldspar.Core.Constructs.Binding
import Feldspar.Core.Constructs.Bits
import Feldspar.Core.Constructs.Complex
import Feldspar.Core.Constructs.Condition
import Feldspar.Core.Constructs.ConditionM
import Feldspar.Core.Constructs.Conversion
import Feldspar.Core.Constructs.Eq
import Feldspar.Core.Constructs.Error
import Feldspar.Core.Constructs.FFI
import Feldspar.Core.Constructs.Floating
import Feldspar.Core.Constructs.Fractional
import Feldspar.Core.Constructs.Future
import Feldspar.Core.Constructs.Integral
import Feldspar.Core.Constructs.Literal
import Feldspar.Core.Constructs.Logic
import Feldspar.Core.Constructs.Loop
import Feldspar.Core.Constructs.Mutable
import Feldspar.Core.Constructs.MutableArray
import Feldspar.Core.Constructs.MutableReference
import Feldspar.Core.Constructs.MutableToPure
import Feldspar.Core.Constructs.NoInline
import Feldspar.Core.Constructs.Par
import Feldspar.Core.Constructs.Num
import Feldspar.Core.Constructs.Ord
import Feldspar.Core.Constructs.Save
import Feldspar.Core.Constructs.Switch
import Feldspar.Core.Constructs.SizeProp
import Feldspar.Core.Constructs.SourceInfo
import Feldspar.Core.Constructs.RealFloat
import Feldspar.Core.Constructs.Trace
import Feldspar.Core.Constructs.Tuple
type FeldSymbols
= (Decor SourceInfo1 Identity :|| Type)
:+: (Condition :|| Type)
:+: (FFI :|| Type)
:+: (Literal :|| Type)
:+: (Select :|| Type)
:+: (Tuple :|| Type)
:+: (Array :|| Type)
:+: (BITS :|| Type)
:+: (COMPLEX :|| Type)
:+: (Conversion :|| Type)
:+: (EQ :|| Type)
:+: (Error :|| Type)
:+: (FLOATING :|| Type)
:+: (REALFLOAT :|| Type)
:+: (FRACTIONAL :|| Type)
:+: (FUTURE :|| Type)
:+: (INTEGRAL :|| Type)
:+: (Logic :|| Type)
:+: (Loop :|| Type)
:+: (NUM :|| Type)
:+: (NoInline :|| Type)
:+: (ORD :|| Type)
:+: (PropSize :|| Type)
:+: (Save :|| Type)
:+: (Switch :|| Type)
:+: (Trace :|| Type)
:+: Let
:+: ConditionM Mut
:+: LoopM Mut
:+: MONAD Mut
:+: Mutable
:+: MutableArray
:+: MutableReference
:+: MutableToPure
:+: MONAD Par
:+: ParFeature
:+: Empty
type FeldDom = FODomain FeldSymbols Typeable Type
newtype FeldDomain a = FeldDomain { getFeldDomain :: HODomain FeldSymbols Typeable Type a }
instance Constrained FeldDomain
where
type Sat FeldDomain = Typeable
exprDict (FeldDomain s) = exprDict s
deriving instance (Project sym FeldSymbols) => Project sym FeldDomain
instance (InjectC sym FeldSymbols a, Typeable a) => InjectC sym FeldDomain a
where
injC = FeldDomain . injC
toFeld :: ASTF (HODomain FeldSymbols Typeable Type) a -> ASTF FeldDomain a
toFeld = fold $ appArgs . Sym . FeldDomain
fromFeld :: ASTF FeldDomain a -> ASTF (HODomain FeldSymbols Typeable Type) a
fromFeld = fold $ appArgs . Sym . getFeldDomain
instance IsHODomain FeldDomain Typeable Type
where
lambda f = case lambda (fromFeld . f . toFeld) of
Sym s -> Sym (FeldDomain s)
newtype Data a = Data { unData :: ASTF FeldDomain a }
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
deriving instance Typeable Data
#else
deriving instance Typeable1 Data
#endif
instance Type a => Syntactic (Data a)
where
type Domain (Data a) = FeldDomain
type Internal (Data a) = a
desugar = unData
sugar = Data
type SyntacticFeld a = (Syntactic a, Domain a ~ FeldDomain, Typeable (Internal a))
class (SyntacticFeld a, Type (Internal a)) => Syntax a
instance (SyntacticFeld a, Type (Internal a)) => Syntax a
reifyF :: SyntacticFeld a => a -> ASTF FeldDom (Internal a)
reifyF = reifyTop . fromFeld . desugar
instance Type a => Eq (Data a)
where
Data a == Data b = alphaEq (reifyF a) (reifyF b)
instance Type a => Show (Data a)
where
show = render . reifyF . unData
sugarSymF :: ( ApplySym sig b FeldDomain
, SyntacticN c b
, InjectC (feature :|| Type) (HODomain FeldSymbols Typeable Type) (DenResult sig)
, Type (DenResult sig)
)
=> feature sig -> c
sugarSymF sym = sugarN $ appSym' $ Sym $ FeldDomain $ injC $ c' sym