4343module Main (main , specMain ) where
4444
4545#if __GLASGOW_HASKELL__ >= 906
46+ import GHC.StaticPtr
47+ import Language.Haskell.TH (TExp , examineCode )
4648import Control.Monad
4749#endif
4850
@@ -516,7 +518,36 @@ desugarRecordType = appRecord . foldr appCons nilL
516518 l = HSE. noSrcSpan
517519
518520--------------------------------------------------------------------------------
519- -- Typed AST support
521+ -- Typed TH support
522+
523+ -- ghci> $((>>= TH.stringE . show . TH.ppr) $ TH.unTypeCode $ compile () $ AppG (LamG (GarG (ZGar [|| id ||]))) $ LitG [|| () ||])
524+ -- "(\\x_0 -> GHC.Internal.Base.id x_0) GHC.Tuple.()"
525+
526+ data Germ g t where
527+ GarG :: Gar g t -> Germ g t
528+ LamG :: Germ (g , TH. Code Q a ) b -> Germ g (a -> b )
529+ AppG :: Germ g (s -> t ) -> Germ g s -> Germ g t
530+ LitG :: TH. Code Q a -> Germ g a
531+
532+ data Gar g t where
533+ ZGar :: TH. Code Q (t -> a ) -> Gar (h , TH. Code Q t ) a
534+ SGar :: Gar h t -> Gar (h , s ) t
535+
536+ -- This is the compiler. Type-safe and total.
537+ compile :: env -> Germ env t -> TH. Code Q t
538+ compile env (GarG v) = lookg v env
539+ compile env (LamG e) = [|| \ x -> $$ (compile (env, [|| x|| ]) e) || ]
540+ compile env (AppG e1 e2) = [|| $$ (compile env e1) $$ (compile env e2) || ]
541+ compile _env (LitG a) = a
542+
543+ -- Type-safe, total lookup. The final @slot@ determines which slot of
544+ -- a given tuple to pick out.
545+ lookg :: Gar env t -> env -> TH. Code Q t
546+ lookg (ZGar slot) (_, x) = [|| $$ slot $$ x || ]
547+ lookg (SGar v) (env, _) = lookg v env
548+
549+ --------------------------------------------------------------------------------
550+ -- Typed AST support for eval
520551--
521552-- We define a well-typed, well-indexed GADT AST which can be evaluated directly.
522553
@@ -530,10 +561,6 @@ data Var g t where
530561 ZVar :: (t -> a ) -> Var (h , t ) a
531562 SVar :: Var h t -> Var (h , s ) t
532563
533- --------------------------------------------------------------------------------
534- -- Evaluator
535- --
536-
537564-- This is the entire evaluator. Type-safe and total.
538565eval :: env -> Term env t -> t
539566eval env (Var v) = lookp v env
0 commit comments