{-# LANGUAGE TypeSynonymInstances #-} {- This code is derived from: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.92.495&rep=rep1&type=pdf The idea is to use it for expressing DSP dataflow algorithms that can translate directly to C. For this we use an ANF-style representation. -} -- No conditionals yet data Code = Let String Code Code | Ref String | Prim String [String] deriving Show letCode var expr body = Let var expr (body var) var n = "r" ++ show n p1 = Prim "+" ["a", "b"] b1 = \x -> (Prim "+" [x, x]) c1 = letCode "x0" p1 b1 -- A modification of the state-continuation monad in [1] where the -- state is only used to generate unique variable names. newtype Gen s c = Gen { runGen :: s -> (s -> c -> c) -> c } -- retSK a = \s k -> k s a -- bindSK a f = Gen $ \s k -> runGen a s (\s' x -> f x s' k) -- retSKs :: Num s => Code -> (Gen s Code) -- retSKs a = Gen $ \s k -> let v = (var s) in Let v a (k (s + 1) (Ref v)) -- bindSKs a f = bindSK a (\x -> bindSK (retSKs x) f) -- FIXME: wrapping isn't correct --instance Monad Gen where -- return = retSKs -- (Contstate a) >>= f = Contstate $ bindSKs a (\x -> runSK $ f x) bindN a f = \s k -> a s (\s' x -> let z = var s' in Let z x (f z s' k))