Idris-dev/test/dsl002/Resimp.idr

177 lines
5.3 KiB
Idris
Raw Normal View History

2012-10-22 23:37:35 +04:00
module Resimp
import Data.Vect
import public Data.Fin
-- IO operations which read a resource
data Reader : Type -> Type where
MkReader : IO a -> Reader a
getReader : Reader a -> IO a
getReader (MkReader x) = x
ior : IO a -> Reader a
ior = MkReader
-- IO operations which update a resource
data Updater : Type -> Type where
MkUpdater : IO a -> Updater a
getUpdater : Updater a -> IO a
getUpdater (MkUpdater x) = x
iou : IO a -> Updater a
iou = MkUpdater
-- IO operations which create a resource
data Creator : Type -> Type where
MkCreator : IO a -> Creator a
getCreator : Creator a -> IO a
getCreator (MkCreator x) = x
ioc : IO a -> Creator a
ioc = MkCreator
2013-11-01 17:33:45 +04:00
infixr 5 :->
using (i: Fin n, gam : Vect n Ty, gam' : Vect n Ty, gam'' : Vect n Ty)
data Ty = R Type
| Val Type
| Choice Type Type
| (:->) Type Ty
interpTy : Ty -> Type
interpTy (R t) = IO t
interpTy (Val t) = t
interpTy (Choice x y) = Either x y
interpTy (a :-> b) = a -> interpTy b
data HasType : Vect n Ty -> Fin n -> Ty -> Type where
stop : HasType (a :: gam) FZ a
pop : HasType gam i b -> HasType (a :: gam) (FS i) b
data Env : Vect n Ty -> Type where
Nil : Env Nil
(::) : interpTy a -> Env gam -> Env (a :: gam)
envLookup : HasType gam i a -> Env gam -> interpTy a
envLookup stop (x :: xs) = x
envLookup (pop k) (x :: xs) = envLookup k xs
update : (gam : Vect n Ty) -> HasType gam i b -> Ty -> Vect n Ty
update (x :: xs) stop y = y :: xs
update (x :: xs) (pop k) y = x :: update xs k y
update Nil stop _ impossible
total
2013-11-01 17:33:45 +04:00
envUpdate : (p:HasType gam i a) -> (val:interpTy b) ->
Env gam -> Env (update gam p b)
envUpdate stop val (x :: xs) = val :: xs
envUpdate (pop k) val (x :: xs) = x :: envUpdate k val xs
envUpdate stop _ Nil impossible
total
2013-11-01 17:33:45 +04:00
envUpdateVal : (p:HasType gam i a) -> (val:b) ->
Env gam -> Env (update gam p (Val b))
envUpdateVal stop val (x :: xs) = val :: xs
envUpdateVal (pop k) val (x :: xs) = x :: envUpdateVal k val xs
envUpdateVal stop _ Nil impossible
envTail : Env (a :: gam) -> Env gam
envTail (x :: xs) = xs
data Args : Vect n Ty -> List Type -> Type where
ANil : Args gam []
2013-11-01 17:33:45 +04:00
ACons : HasType gam i a ->
Args gam as -> Args gam (interpTy a :: as)
funTy : List Type -> Ty -> Ty
funTy list.Nil t = t
funTy (a :: as) t = a :-> funTy as t
data Res : Vect n Ty -> Vect n Ty -> Ty -> Type where
{-- Resource creation and usage. 'Let' creates a resource - the type
at the end means that the resource must have been consumed by the time
it goes out of scope, where "consumed" simply means that it has been
replaced with a value of type '()'. --}
2013-11-01 17:33:45 +04:00
Let : Creator (interpTy a) ->
Res (a :: gam) (Val () :: gam') (R t) ->
Res gam gam' (R t)
2013-11-01 17:33:45 +04:00
Update : (a -> Updater b) -> (p:HasType gam i (Val a)) ->
Res gam (update gam p (Val b)) (R ())
2013-11-01 17:33:45 +04:00
Use : (a -> Reader b) -> HasType gam i (Val a) ->
Res gam gam (R b)
{-- Control structures --}
Lift : IO a -> Res gam gam (R a)
2013-11-01 17:33:45 +04:00
Check : (p:HasType gam i (Choice (interpTy a) (interpTy b))) ->
(failure:Res (update gam p a) (update gam p c) t) ->
(success:Res (update gam p b) (update gam p c) t) ->
Res gam (update gam p c) t
2013-11-01 17:33:45 +04:00
While : Res gam gam (R Bool) ->
Res gam gam (R ()) -> Res gam gam (R ())
Return : a -> Res gam gam (R a)
2013-11-01 17:33:45 +04:00
(>>=) : Res gam gam' (R a) -> (a -> Res gam' gam'' (R t)) ->
Res gam gam'' (R t)
ioret : a -> IO a
ioret = return
interp : Env gam -> [static] (e : Res gam gam' t) ->
(Env gam' -> interpTy t -> IO u) -> IO u
interp env (Let val scope) k
= do x <- getCreator val
interp (x :: env) scope
(\env', scope' => k (envTail env') scope')
interp env (Update method x) k
= do x' <- getUpdater (method (envLookup x env))
2013-11-01 17:33:45 +04:00
k (envUpdateVal x x' env) (return ())
interp env (Use method x) k
= do x' <- getReader (method (envLookup x env))
k env (return x')
2013-11-01 17:33:45 +04:00
interp env (Lift io) k
= k env io
interp env (Check x left right) k =
either (\a => interp (envUpdate x a env) left k)
(\b => interp (envUpdate x b env) right k)
(envLookup x env)
interp env (While test body) k
= interp env test
(\env', result =>
do r <- result
2013-11-01 17:33:45 +04:00
if (not r)
then (k env' (return ()))
2013-11-01 17:33:45 +04:00
else (interp env' body
(\env'', body' =>
do v <- body' -- make sure it's evalled
interp env'' (While test body) k )))
interp env (Return v) k = k env (return v)
interp env (v >>= f) k
= interp env v (\env', v' => do n <- v'
interp env' (f n) k)
2015-03-02 07:34:17 +03:00
let_ : _ -> Creator (interpTy a) ->
Res (a :: gam) (Val () :: gam') (R t) ->
Res gam gam' (R t)
let_ _ = Let
-- run : {static} Res [] [] (R t) -> IO t
-- run prog = interp [] prog (\env, res => res)
syntax run [prog] = interp [] prog (\env, res => res)
dsl res
variable = id
2015-03-02 07:34:17 +03:00
let = let_
index_first = stop
index_next = pop
syntax RES [x] = {gam:Vect n Ty} -> Res gam gam (R x)