|  | 
|  | 1 | +||| A closed universe of format descriptions as an inductive type, where the | 
|  | 2 | +||| in-memory representation is tracked as an index on the type. | 
|  | 3 | + | 
|  | 4 | +module Fathom.Closed.IndexedInductiveCustom | 
|  | 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 temperamental 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) ByteStream | 
|  | 28 | +  encode : Encode Rep ByteStream | 
|  | 29 | + | 
|  | 30 | + | 
|  | 31 | +||| Universe of format descriptions indexed by their machine representations | 
|  | 32 | +public export | 
|  | 33 | +data FormatOf : (0 A : Type) -> Type where | 
|  | 34 | +  End : FormatOf Unit | 
|  | 35 | +  Fail : FormatOf Void | 
|  | 36 | +  Pure : {0 A : Type} -> (x : A) -> FormatOf A | 
|  | 37 | +  Skip : {0 A : Type} -> (f : FormatOf A) -> (def : A) -> FormatOf Unit | 
|  | 38 | +  Repeat : {0 A : Type} -> (len : Nat) -> FormatOf A -> FormatOf (Vect len A) | 
|  | 39 | +  Bind : {0 A : Type} -> {0 B : A -> Type} -> (f : FormatOf A) -> ((x : A) -> FormatOf (B x)) -> FormatOf (x : A ** B x) | 
|  | 40 | +  Custom :  (f : CustomFormat) -> FormatOf f.Rep | 
|  | 41 | + | 
|  | 42 | + | 
|  | 43 | +-- Support for do notation | 
|  | 44 | + | 
|  | 45 | +public export | 
|  | 46 | +pure : {0 A : Type} -> (x : A) -> FormatOf A | 
|  | 47 | +pure = Pure | 
|  | 48 | + | 
|  | 49 | +public export | 
|  | 50 | +(>>=) : {0 A : Type} -> {0 B : A -> Type} -> (f : FormatOf A) -> ((x : A) -> FormatOf (B x)) -> FormatOf (x : A ** B x) | 
|  | 51 | +(>>=) = Bind | 
|  | 52 | + | 
|  | 53 | + | 
|  | 54 | +--------------------------- | 
|  | 55 | +-- ENCODER/DECODER PAIRS -- | 
|  | 56 | +--------------------------- | 
|  | 57 | + | 
|  | 58 | + | 
|  | 59 | +export | 
|  | 60 | +decode : {0 A : Type} -> (f : FormatOf A) -> Decode (A, ByteStream) (ByteStream) | 
|  | 61 | +decode End [] = Just ((), []) | 
|  | 62 | +decode End (_::_) = Nothing | 
|  | 63 | +decode Fail _ = Nothing | 
|  | 64 | +decode (Pure x) buffer = | 
|  | 65 | +  Just (x, buffer) | 
|  | 66 | +decode (Skip f _) buffer = do | 
|  | 67 | +  (x, buffer') <- decode f buffer | 
|  | 68 | +  Just ((), buffer') | 
|  | 69 | +decode (Repeat 0 f) buffer = | 
|  | 70 | +  Just ([], buffer) | 
|  | 71 | +decode (Repeat (S len) f) buffer = do | 
|  | 72 | +  (x, buffer') <- decode f buffer | 
|  | 73 | +  (xs, buffer'') <- decode (Repeat len f) buffer' | 
|  | 74 | +  Just (x :: xs, buffer'') | 
|  | 75 | +decode (Bind f1 f2) buffer = do | 
|  | 76 | +  (x, buffer') <- decode f1 buffer | 
|  | 77 | +  (y, buffer'') <- decode (f2 x) buffer' | 
|  | 78 | +  Just ((x ** y), buffer'') | 
|  | 79 | +decode (Custom f) buffer = f.decode buffer | 
|  | 80 | +
 | 
|  | 81 | +-- export | 
|  | 82 | +-- decode : {0 A : Type} -> (f : FormatOf A) -> Decode (A, ByteStream) (ByteStream) | 
|  | 83 | +-- decode End | 
|  | 84 | +--   = \buffer => case buffer of | 
|  | 85 | +--       [] => Just ((), []) | 
|  | 86 | +--       _::_ => Nothing | 
|  | 87 | +-- decode Fail | 
|  | 88 | +--   = const Nothing | 
|  | 89 | +-- decode (Pure x) | 
|  | 90 | +--   = pure (MkSing x) | 
|  | 91 | +-- decode (Skip f _) | 
|  | 92 | +--   = do  _ <- decode f | 
|  | 93 | +--         pure () | 
|  | 94 | +-- decode (Repeat 0 f) = pure [] | 
|  | 95 | +-- decode (Repeat (S len) f) | 
|  | 96 | +--   = do  x <- decode f | 
|  | 97 | +--         xs <- decode (Repeat len f) | 
|  | 98 | +--         pure (x :: xs) | 
|  | 99 | +-- decode (Bind f1 f2) | 
|  | 100 | +--   = do  x <- decode f1 | 
|  | 101 | +--         y <- decode (f2 x) | 
|  | 102 | +--         pure (x ** y) | 
|  | 103 | +
 | 
|  | 104 | +
 | 
|  | 105 | +export | 
|  | 106 | +encode : {0 A : Type} -> (f : FormatOf A) -> Encode A (ByteStream) | 
|  | 107 | +encode End () = Just [] | 
|  | 108 | +encode (Pure x) _ = Just [] | 
|  | 109 | +encode (Skip f def) () = encode f def | 
|  | 110 | +encode (Repeat Z f) [] = Just [] | 
|  | 111 | +encode (Repeat (S len) f) (x :: xs) = | 
|  | 112 | +  [| encode f x <+> encode (Repeat len f) xs |] | 
|  | 113 | +encode (Bind f1 f2) (x ** y) = | 
|  | 114 | +  [| encode f1 x <+> encode (f2 x) y |] | 
|  | 115 | +encode (Custom f) x = f.encode x | 
|  | 116 | +
 | 
|  | 117 | +
 | 
|  | 118 | +-------------------- | 
|  | 119 | +-- CUSTOM FORMATS -- | 
|  | 120 | +-------------------- | 
|  | 121 | +
 | 
|  | 122 | +
 | 
|  | 123 | +public export | 
|  | 124 | +u8 : FormatOf Nat | 
|  | 125 | +u8 = Custom (MkCustomFormat | 
|  | 126 | +  { Rep = Nat | 
|  | 127 | +  , decode = map cast decodeU8 | 
|  | 128 | +  , encode = encodeU8 . cast {to = Bits8} | 
|  | 129 | +  }) | 
|  | 130 | +
 | 
|  | 131 | +
 | 
|  | 132 | +public export | 
|  | 133 | +u16Le : FormatOf Nat | 
|  | 134 | +u16Le = Custom (MkCustomFormat | 
|  | 135 | +  { Rep = Nat | 
|  | 136 | +  , decode = map cast (decodeU16 LE) | 
|  | 137 | +  , encode = encodeU16 LE . cast {to = Bits16} | 
|  | 138 | +  }) | 
|  | 139 | +
 | 
|  | 140 | +
 | 
|  | 141 | +public export | 
|  | 142 | +u16Be : FormatOf Nat | 
|  | 143 | +u16Be = Custom (MkCustomFormat | 
|  | 144 | +  { Rep = Nat | 
|  | 145 | +  , decode = map cast (decodeU16 BE) | 
|  | 146 | +  , encode = encodeU16 BE . cast {to = Bits16} | 
|  | 147 | +  }) | 
|  | 148 | +
 | 
|  | 149 | +
 | 
|  | 150 | +----------------- | 
|  | 151 | +-- EXPERIMENTS -- | 
|  | 152 | +----------------- | 
|  | 153 | +
 | 
|  | 154 | +
 | 
|  | 155 | +public export | 
|  | 156 | +record Format where | 
|  | 157 | +  constructor MkFormat | 
|  | 158 | +  0 Repr : Type | 
|  | 159 | +  Format : FormatOf Repr | 
|  | 160 | +
 | 
|  | 161 | +
 | 
|  | 162 | +either : (cond : Bool) -> FormatOf a -> FormatOf b -> FormatOf (if cond then a else b) | 
|  | 163 | +either True f1 _ = f1 | 
|  | 164 | +either False _ f2 = f2 | 
|  | 165 | +
 | 
|  | 166 | +orPure : (cond : Bool) -> FormatOf a -> (def : a) -> FormatOf a | 
|  | 167 | +orPure True f _ = f | 
|  | 168 | +orPure False _ def = Pure def | 
|  | 169 | +
 | 
|  | 170 | +
 | 
|  | 171 | +-- Reproduction of difficulties in OpenType format | 
|  | 172 | +
 | 
|  | 173 | +
 | 
|  | 174 | +Flag : Type | 
|  | 175 | +Flag = (flag : Nat ** repeat : Nat ** ()) | 
|  | 176 | +
 | 
|  | 177 | +(.repeat) : Flag -> Nat | 
|  | 178 | +(.repeat) (_ ** repeat ** _) = repeat | 
|  | 179 | +
 | 
|  | 180 | +
 | 
|  | 181 | +-- def flag = { | 
|  | 182 | +--     flag <- u8, | 
|  | 183 | +--     repeat <- match ((u8_and flag 8) != (0 : U8)) { | 
|  | 184 | +--       true => u8, | 
|  | 185 | +--       false => succeed U8 0, | 
|  | 186 | +--     }, | 
|  | 187 | +-- }; | 
|  | 188 | +flag : FormatOf Flag | 
|  | 189 | +flag = do | 
|  | 190 | +  flag <- u8 | 
|  | 191 | +  repeat <- case flag of | 
|  | 192 | +    0 => u8 | 
|  | 193 | +    _ => Pure {A = Nat} 0 | 
|  | 194 | +  Pure () | 
|  | 195 | +
 | 
|  | 196 | +
 | 
|  | 197 | +SimpleGlyph : Type | 
|  | 198 | +SimpleGlyph = (flag : Flag ** Nat) | 
|  | 199 | +
 | 
|  | 200 | +
 | 
|  | 201 | +-- def simple_glyph = fun (number_of_contours : U16) => { | 
|  | 202 | +--     ... | 
|  | 203 | +--     let flag_repeat = fun (f : Repr flag) => f.repeat + (1 : U8), | 
|  | 204 | +--     ... | 
|  | 205 | +-- }; | 
|  | 206 | +simple_glyph : FormatOf SimpleGlyph | 
|  | 207 | +simple_glyph = do | 
|  | 208 | +  flag <- flag | 
|  | 209 | +  Pure (flag.repeat + 1) | 
0 commit comments