packages feed

compdata-0.8: examples/Examples/Automata/SimpComp.hs

{-# LANGUAGE TemplateHaskell, FlexibleContexts, MultiParamTypeClasses,
  TypeOperators, FlexibleInstances, UndecidableInstances,
  ScopedTypeVariables, TypeSynonymInstances, RankNTypes #-}

module Examples.Automata.Compiler where


import Data.Comp.Automata hiding (DUpState, (<*>), runDUpState, dUpState)
import Data.Comp.Zippable
import Data.Comp.Derive
import Data.Comp.Ops
import Data.Comp hiding (height)
import Prelude hiding (foldl)



type Var = String

data Sig a = Const Int | Plus a a
data Let a = Let Var a a
           | Var Var


$(derive [makeFunctor, makeFoldable, smartConstructors, makeShowF] [''Sig, ''Let])

instance Zippable Sig where
    fzip _ (Const i) = Const i
    fzip (Cons a (Cons b _)) (Plus x y) = Plus (a,x) (b,y)

instance Zippable Let where
    fzip (Cons a (Cons b _)) (Let v x y) = Let v (a,x) (b,y)
    fzip _ (Var v) = Var v


instance (Zippable f, Zippable g) => Zippable (f :+: g) where
    fzip x (Inl v) = Inl $ fzip x v
    fzip x (Inr v) = Inr $ fzip x v

evalSt :: UpState Sig Int
evalSt (Const i) = i
evalSt (Plus x y) = x + y

type Addr = Int

data Instr = Acc Int
           | Load Addr
           | Store Addr
           | Add Addr
             deriving (Show)

type Code = [Instr]



type DUpState f q p = (q :< p) => f p -> q

dUpState :: Functor f => UpState f q -> DUpState f q p
dUpState st = st . fmap pr


heightSt :: UpState Sig Int
heightSt (Const _) = 0
heightSt (Plus x y) = 1 + max x y

codeSt :: (Int :< q) => DUpState Sig Code q
codeSt (Const x) = [Acc x]
codeSt (Plus x y) = pr x ++ [Store a] ++ pr y ++ [Add a] where a = pr y

-- | This combinator constructs the product of two GDUTA.
(<*>) :: (p :< pq, q :< pq)
             => DUpState f p pq -> DUpState f q pq -> DUpState f (p,q) pq
(sp <*> sq) t = (sp t, sq t)
    
runDUpState :: Functor f => DUpState f q q -> Term f -> q
runDUpState = cata

code :: Term Sig -> Code
code = fst . runDUpState (codeSt <*> dUpState heightSt)