Skip to content

Commit 02bace9

Browse files
committed
Experiment with custom IR universes
1 parent 5bc6398 commit 02bace9

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed

experiments/idris/fathom.ipkg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ package fathom
1515
-- modules to install
1616
modules = Fathom
1717
, Fathom.Base
18-
, Fathom.Closed.InductiveRecursive
1918
, Fathom.Closed.IndexedInductive
19+
, Fathom.Closed.InductiveRecursive
20+
, Fathom.Closed.InductiveRecursiveCustom
2021
, Fathom.Open.Record
2122

2223
-- main file (i.e. file to load at REPL)
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
||| Experimenting with an approach to extending inductive-recusive format
2+
||| descriptions with custom formats.
3+
4+
module Fathom.Closed.InductiveRecursiveCustom
5+
6+
7+
import Data.Colist
8+
import Data.Vect
9+
10+
import Fathom.Base
11+
12+
13+
-------------------------
14+
-- FORMAT DESCRIPTIONS --
15+
-------------------------
16+
17+
18+
||| A custom format description.
19+
|||
20+
||| We’d prefer to just import `Fathom.Open.Record`, but Idris’ imports are a
21+
||| bit tempramental and result in ambiguities when importing modules that
22+
||| contain types of the same name as those defined in the current module.
23+
public export
24+
record CustomFormat where
25+
constructor MkCustomFormat
26+
Rep : Type
27+
decode : Decode Rep ByteStream
28+
encode : Encode Rep ByteStream
29+
30+
31+
mutual
32+
||| Universe of format descriptions
33+
public export
34+
data Format : Type where
35+
End : Format
36+
Fail : Format
37+
Pure : {0 A : Type} -> A -> Format
38+
Skip : (f : Format) -> (def : Rep f) -> Format
39+
Repeat : Nat -> Format -> Format
40+
Bind : (f : Format) -> (Rep f -> Format) -> Format
41+
Custom : (f : CustomFormat) -> Format
42+
43+
44+
||| In-memory representation of format descriptions
45+
public export
46+
Rep : Format -> Type
47+
Rep End = Unit
48+
Rep Fail = Void
49+
Rep (Skip _ _) = Unit
50+
Rep (Repeat len f) = Vect len (Rep f)
51+
Rep (Pure x) = Sing x
52+
Rep (Bind f1 f2) = (x : Rep f1 ** Rep (f2 x))
53+
Rep (Custom f) = f.Rep
54+
55+
56+
---------------------------
57+
-- ENCODER/DECODER PAIRS --
58+
---------------------------
59+
60+
61+
export
62+
decode : (f : Format) -> Decode (Rep f) ByteStream
63+
decode End [] = Just ((), [])
64+
decode End (_::_) = Nothing
65+
decode Fail _ = Nothing
66+
decode (Pure x) buffer =
67+
Just (MkSing x, buffer)
68+
decode (Skip f _) buffer = do
69+
(x, buffer') <- decode f buffer
70+
Just ((), buffer')
71+
decode (Repeat 0 f) buffer =
72+
Just ([], buffer)
73+
decode (Repeat (S len) f) buffer = do
74+
(x, buffer') <- decode f buffer
75+
(xs, buffer'') <- decode (Repeat len f) buffer'
76+
Just (x :: xs, buffer'')
77+
decode (Bind f1 f2) buffer = do
78+
(x, buffer') <- decode f1 buffer
79+
(y, buffer'') <- decode (f2 x) buffer'
80+
Just ((x ** y), buffer'')
81+
decode (Custom f) buffer = f.decode buffer
82+
83+
84+
export
85+
encode : (f : Format) -> Encode (Rep f) ByteStream
86+
encode End () _ = Just []
87+
encode (Pure x) (MkSing _) buffer = Just buffer
88+
encode (Skip f def) () buffer = do
89+
encode f def buffer
90+
encode (Repeat Z f) [] buffer = Just buffer
91+
encode (Repeat (S len) f) (x :: xs) buffer = do
92+
buffer' <- encode (Repeat len f) xs buffer
93+
encode f x buffer'
94+
encode (Bind f1 f2) (x ** y) buffer = do
95+
buffer' <- encode (f2 x) y buffer
96+
encode f1 x buffer'
97+
encode (Custom f) x buffer = f.encode x buffer
98+
99+
100+
--------------------
101+
-- CUSTOM FORMATS --
102+
--------------------
103+
104+
105+
u8 : Format
106+
u8 = Custom (MkCustomFormat
107+
{ Rep = Bits8
108+
, decode = \buffer =>
109+
case buffer of
110+
[] => Nothing
111+
x :: buffer => Just (x, buffer)
112+
, encode = \x, buffer =>
113+
Just (x :: buffer)
114+
})
115+
116+
117+
-----------------
118+
-- EXPERIMENTS --
119+
-----------------
120+
121+
122+
||| A format description refined with a fixed representation
123+
public export
124+
FormatOf : (0 Rep : Type) -> Type
125+
FormatOf rep = Refine Format (\f => Rep f = rep)
126+
127+
128+
toFormatOf : (f : Format) -> FormatOf (Rep f)
129+
toFormatOf f = refine f
130+
131+
132+
export
133+
either : (cond : Bool) -> (f1 : Format) -> (f2 : Format) -> FormatOf (if cond then Rep f1 else Rep f2)
134+
either True f1 _ = refine f1
135+
either False _ f2 = refine f2
136+
137+
138+
export
139+
orPure : (cond : Bool) -> FormatOf a -> (def : a) -> FormatOf (if cond then a else Sing def)
140+
orPure True f _ = f
141+
orPure False _ def = refine (Pure def)
142+
143+
144+
export
145+
orPure' : (cond : Bool) -> FormatOf a -> (def : a) -> FormatOf (if cond then a else Sing def)
146+
orPure' True f _ = f
147+
orPure' False _ def = refine (Pure def)
148+
149+
150+
foo : (cond : Bool) -> (f : Format) -> Rep f -> Format
151+
foo cond f def = case orPure cond (toFormatOf f) def of
152+
MkRefine f' prf =>
153+
Bind f' (\x => case cond of
154+
True => ?todo1
155+
False => ?todo2)

0 commit comments

Comments
 (0)