|  | 
|  | 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