module Compiler.Hoopl.Fuel
( Fuel
, FuelMonad, withFuel, getFuel, setFuel
, freshLabel
, runWithFuel
)
where
import Compiler.Hoopl.Label
type Fuel = Int
newtype FuelMonad a = FM { unFM :: Fuel -> [Label] -> (a, Fuel, [Label]) }
instance Monad FuelMonad where
return x = FM (\f u -> (x,f,u))
m >>= k = FM (\f u -> case unFM m f u of (r,f',u') -> unFM (k r) f' u')
withFuel :: Maybe a -> FuelMonad (Maybe a)
withFuel Nothing = return Nothing
withFuel (Just r) = FM (\f u -> if f==0 then (Nothing, f, u)
else (Just r, f1, u))
getFuel :: FuelMonad Fuel
getFuel = FM (\f u -> (f,f,u))
setFuel :: Fuel -> FuelMonad ()
setFuel f = FM (\_ u -> ((), f, u))
runWithFuel :: Fuel -> FuelMonad a -> a
runWithFuel fuel m = a
where (a, _, _) = unFM m fuel allLabels
freshLabel :: FuelMonad Label
freshLabel = FM (\f (l:ls) -> (l, f, ls))