on master help sign in
Fix resource language, add extra test for it
commit0de6d2d9f0b9a64d32be09ece7a4e78a89b086aa authorEdwin Brady <eb@cs.st-andrews.ac.uk> dateSat 29 Sep 2012, 11:49 (14 years ago) parent7b4fb2a
5 files changed+232−2
src/Core/Unify.hs+4−2 test/test014/expected+2 test/test014/resimp.idr+156 test/test014/run+4 test/test014/test014.idr+66
src/Core/Unify.hs+4−2
@@ -143,12 +143,14 @@ unify ctxt env topx topy
143143
144144 -- If there are any clashes of constructors, deem it unrecoverable, otherwise some
145145 -- more work may help.
146+ -- FIXME: Depending on how overloading gets used, this may cause problems. Better
147+ -- rethink overloading properly...
146148
147149 recoverable (P (DCon _ _) x _) (P (DCon _ _) y _)
148150 | x == y = True
149151 | otherwise = False
150− recoverable (P (DCon _ _) x _) (P (TCon _ _) y _) = False
151− recoverable (P (TCon _ _) x _) (P (DCon _ _) y _) = False
152+-- recoverable (P (DCon _ _) x _) (P (TCon _ _) y _) = False
153+-- recoverable (P (TCon _ _) x _) (P (DCon _ _) y _) = False
152154 recoverable p@(P _ _ _) (App f a) = recoverable p f
153155 recoverable (App f a) p@(P _ _ _) = recoverable f p
154156 recoverable (App f a) (App f' a')
test/test014/expectednew file+2
@@ -0,0 +1,2 @@
1+foo
2+
test/test014/resimp.idrnew file+156
@@ -0,0 +1,156 @@
1+module resimp
2+
3+-- IO operations which read a resource
4+data Reader : Set -> Set where
5+ MkReader : IO a -> Reader a
6+
7+getReader : Reader a -> IO a
8+getReader (MkReader x) = x
9+
10+ior : IO a -> Reader a
11+ior = MkReader
12+
13+-- IO operations which update a resource
14+data Updater : Set -> Set where
15+ MkUpdater : IO a -> Updater a
16+
17+getUpdater : Updater a -> IO a
18+getUpdater (MkUpdater x) = x
19+
20+iou : IO a -> Updater a
21+iou = MkUpdater
22+
23+-- IO operations which create a resource
24+data Creator : Set -> Set where
25+ MkCreator : IO a -> Creator a
26+
27+getCreator : Creator a -> IO a
28+getCreator (MkCreator x) = x
29+
30+ioc : IO a -> Creator a
31+ioc = MkCreator
32+
33+infixr 5 :->
34+
35+using (i: Fin n, gam : Vect Ty n, gam' : Vect Ty n, gam'' : Vect Ty n)
36+
37+ data Ty = R Set
38+ | Val Set
39+ | Choice Set Set
40+ | (:->) Set Ty
41+
42+ interpTy : Ty -> Set
43+ interpTy (R t) = IO t
44+ interpTy (Val t) = t
45+ interpTy (Choice x y) = Either x y
46+ interpTy (a :-> b) = a -> interpTy b
47+
48+ data HasType : Vect Ty n -> Fin n -> Ty -> Set where
49+ stop : HasType (a :: gam) fO a
50+ pop : HasType gam i b -> HasType (a :: gam) (fS i) b
51+
52+ data Env : Vect Ty n -> Set where
53+ Nil : Env Nil
54+ (::) : interpTy a -> Env gam -> Env (a :: gam)
55+
56+ envLookup : HasType gam i a -> Env gam -> interpTy a
57+ envLookup stop (x :: xs) = x
58+ envLookup (pop k) (x :: xs) = envLookup k xs
59+
60+ update : (gam : Vect Ty n) -> HasType gam i b -> Ty -> Vect Ty n
61+ update (x :: xs) stop y = y :: xs
62+ update (x :: xs) (pop k) y = x :: update xs k y
63+
64+ envUpdate : (p:HasType gam i a) -> (val:interpTy b) ->
65+ Env gam -> Env (update gam p b)
66+ envUpdate stop val (x :: xs) = val :: xs
67+ envUpdate (pop k) val (x :: xs) = x :: envUpdate k val xs
68+
69+ envTail : Env (a :: gam) -> Env gam
70+ envTail (x :: xs) = xs
71+
72+ data Args : Vect Ty n -> List Set -> Set where
73+ ANil : Args gam []
74+ ACons : HasType gam i a ->
75+ Args gam as -> Args gam (interpTy a :: as)
76+
77+ funTy : List Set -> Ty -> Ty
78+ funTy list.Nil t = t
79+ funTy (a :: as) t = a :-> funTy as t
80+
81+ data Res : Vect Ty n -> Vect Ty n -> Ty -> Set where
82+
83+{-- Resource creation and usage. 'Let' creates a resource - the type
84+ at the end means that the resource must have been consumed by the time
85+ it goes out of scope, where "consumed" simply means that it has been
86+ replaced with a value of type '()'. --}
87+
88+ Let : Creator (interpTy a) ->
89+ Res (a :: gam) (Val () :: gam') (R t) ->
90+ Res gam gam' (R t)
91+ Update : (a -> Updater b) -> (p:HasType gam i (Val a)) ->
92+ Res gam (update gam p (Val b)) (R ())
93+ Use : (a -> Reader b) -> HasType gam i (Val a) ->
94+ Res gam gam (R b)
95+
96+{-- Control structures --}
97+
98+ Lift : IO a -> Res gam gam (R a)
99+ Check : (p:HasType gam i (Choice (interpTy a) (interpTy b))) ->
100+ (failure:Res (update gam p a) (update gam p c) T) ->
101+ (success:Res (update gam p b) (update gam p c) T) ->
102+ Res gam (update gam p c) T
103+ While : Res gam gam (R Bool) ->
104+ Res gam gam (R ()) -> Res gam gam (R ())
105+ Return : a -> Res gam gam (R a)
106+ (>>=) : Res gam gam' (R a) -> (a -> Res gam' gam'' (R t)) ->
107+ Res gam gam'' (R t)
108+
109+
110+ interp : Env gam -> {static} Res gam gam' t ->
111+ (Env gam' -> interpTy t -> IO u) -> IO u
112+
113+ interp env (Let val scope) k
114+ = do x <- getCreator val
115+ interp (x :: env) scope
116+ (\env', scope' => k (envTail env') scope')
117+ interp env (Update method x) k
118+ = do x' <- getUpdater (method (envLookup x env))
119+ k (envUpdate x x' env) (return ())
120+ interp env (Use method x) k
121+ = do x' <- getReader (method (envLookup x env))
122+ k env (return x')
123+ interp env (Lift io) k
124+ = k env io
125+ interp env (Check x left right) k =
126+ either (envLookup x env)
127+ (\a => interp (envUpdate x a env) left k)
128+ (\b => interp (envUpdate x b env) right k)
129+ interp env (While test body) k
130+ = interp env test
131+ (\env', result =>
132+ do r <- result
133+ if (not r)
134+ then (k env' (return ()))
135+ else (interp env' body
136+ (\env'', body' =>
137+ do v <- body' -- make sure it's evalled
138+ interp env'' (While test body) k )))
139+ interp env (Return v) k = k env (return v)
140+ interp env (v >>= f) k
141+ = interp env v (\env', v' => do n <- v'
142+ interp env' (f n) k)
143+
144+-- run : {static} Res [] [] (R t) -> IO t
145+-- run prog = interp [] prog (\env, res => res)
146+
147+syntax run [prog] = interp [] prog (\env, res => res)
148+
149+dsl res
150+ variable = id
151+ let = Let
152+ index_first = stop
153+ index_next = pop
154+
155+syntax RES [x] = {gam:Vect Ty n} -> Res gam gam (R x)
156+
test/test014/runnew file+4
@@ -0,0 +1,4 @@
1+#!/bin/bash
2+idris test014.idr -o test014
3+./test014
4+rm -f test014 test014.ibc
test/test014/test014.idrnew file+66
@@ -0,0 +1,66 @@
1+module main
2+
3+import resimp
4+
5+data Purpose = Reading | Writing
6+
7+pstring : Purpose -> String
8+pstring Reading = "r"
9+pstring Writing = "w"
10+
11+data FILE : Purpose -> Set where
12+ OpenH : File -> FILE p
13+
14+syntax ifM [test] then [t] else [e]
15+ = test >>= (\b => if b then t else e)
16+
17+open : String -> (p:Purpose) -> Creator (Either () (FILE p))
18+open fn p = ioc (do h <- fopen fn (pstring p)
19+ ifM validFile h
20+ then return (Right (OpenH h))
21+ else return (Left ()))
22+
23+close : FILE p -> Updater ()
24+close (OpenH h) = iou (closeFile h)
25+
26+readLine : FILE Reading -> Reader String
27+readLine (OpenH h) = ior (fread h)
28+
29+eof : FILE Reading -> Reader Bool
30+eof (OpenH h) = ior (feof h)
31+
32+syntax rclose [h] = Update close h
33+syntax rreadLine [h] = Use readLine h
34+syntax reof [h] = Use eof h
35+
36+syntax rputStrLn [s] = Lift (putStrLn s)
37+
38+syntax if opened [f] then [e] else [t] = Check f t e
39+
40+
41+
42+
43+
44+
45+
46+
47+
48+
49+
50+
51+
52+
53+
54+--------
55+
56+readH : String -> RES ()
57+readH fn = res (do let x = open fn Reading
58+ if opened x then
59+ do str <- rreadLine x
60+ rputStrLn str
61+ rclose x
62+ else rputStrLn "Error")
63+
64+main : IO ()
65+main = run (readH "test")
66+