0 | module Text.ILex.Stack
2 | import Data.Linear.Ref1
4 | import Text.ByteBounds
5 | import Text.ILex.Derive
6 | import Text.ILex.Interfaces
7 | import Text.ILex.Parser
8 | import Text.ILex.Util
9 | import Text.ParseError
15 | %language ElabReflection
32 | record Stack (e,a : Type) (r : Bits32) (q : Type) where
36 | prev_ : Ref q ByteString
37 | cur_ : Ref q ByteString
39 | relpos_ : Ref q Integer
41 | positions_ : Ref q (SnocList BytePos)
47 | state_ : Ref q (Index r)
50 | strings_ : Ref q (SnocList String)
53 | error_ : Ref q (Maybe $
BBErr e)
55 | %runElab derive "Stack" [FullStack]
59 | init : (0 p : 0 < r) => a -> F1 q (Stack e a r q)
71 | pure (S pr fl ro rr ll ps sk st ss er)
78 | 0 Tok : Type -> Type
82 | 0 Toks : Type -> Type
86 | 0 Skot : Type -> Type
87 | Skot = SnocList . ByteBounded
90 | 0 L1 : (q,e : Type) -> (a : Type) -> Type
91 | L1 q e a = P1 q (BBErr e) (Toks a)
94 | 0 Lexer : (e : Type) -> Type -> Type
95 | Lexer e a = {0 q : Type} -> L1 q e a
97 | parameters {auto hb : HasBytes s}
98 | {auto hs : HasStack s (Skot a)}
100 | {auto 0 lt : 0 < r}
103 | pushBounded : s q => a -> F1 q (Index r)
104 | pushBounded v = bounded' v >>= \b => pushStackAs b 0
107 | tok : a -> (RExp True, Step q r s)
108 | tok v = step x (pushBounded v)
111 | byteTok : (ByteString -> a) -> (RExp True, Step q r s)
112 | byteTok f = bytes x (pushBounded . f)
115 | stringTok : (String -> a) -> (RExp True, Step q r s)
116 | stringTok f = string x (pushBounded . f)
120 | {auto 0 lt : 0 < r}
121 | -> {auto stk : HasStack s (SnocList a)}
122 | -> {auto err : HasBBErr s e}
123 | -> {auto bts : HasBytes s}
126 | -> F1 q (Either (BBErr e) $
List a)
129 | then getList (stack sk) >>= pure . Right
130 | else unexpected [] sk >>= pure . Left
133 | lexer : {r : _} -> (0 lt : 0 < r) => Steps q r (Stack e (Skot a) r) -> L1 q e a
134 | lexer m = P Ini (init [<]) (lex1 [E Ini $
dfa m]) snocChunk (errs []) lexEOI
140 | %runElab deriveParserState "VSz" "VST" ["VIni", "VErr", "VDone"]
144 | data Token : (e, a : Type) -> Type where
151 | Const : a -> Token e a
154 | Txt : (String -> Either e a) -> Token e a
157 | Bytes : (ByteString -> Either e a) -> Token e a
160 | const : a -> Token e a
164 | txt : (String -> a) -> Token e a
165 | txt f = Txt (Right . f)
168 | bytes : (ByteString -> a) -> Token e a
169 | bytes f = Bytes (Right . f)
172 | (RExpOf True b, Token e a)
173 | -> (RExpOf True b, Step q VSz (Stack e (Maybe a) VSz))
176 | Ignore => step' x VIni
177 | Const v => step x (putStackAs (Just v) VDone)
179 | string x $
\s => case f s of
180 | Right v => putStackAs (Just v) VDone
181 | Left e => failHere (Custom e) VErr
183 | bytes x $
\s => case f s of
184 | Right v => putStackAs (Just v) VDone
185 | Left e => failHere (Custom e) VErr
188 | (RExpOf True b, Token e a)
189 | -> Maybe (RExpOf True b, Step q VSz (Stack e (Maybe a) VSz))
190 | ignore (x,Ignore) = Just $
step' x VDone
193 | valEOI : VST -> Stack e (Maybe a) VSz q -> F1 q (Either (BBErr e) a)
195 | if i == VDone || i == VIni
196 | then replace1 sk.stack_ Nothing >>= \case
197 | Just v => pure (Right v)
198 | Nothing => unexpected [] sk >>= pure . Left
199 | else unexpected [] sk >>= pure . Left
202 | 0 PVal1 : (q,e : Type) -> (a : Type) -> Type
203 | PVal1 q e a = P1 q (BBErr e) a
207 | value : Maybe a -> TokenMap (Token e a) -> PVal1 q e a
209 | let iniSteps := E VIni $
dfa (map toStep m)
210 | doneSteps := E VDone $
dfa (mapMaybe ignore m)
211 | states := lex1 [iniSteps, doneSteps]
212 | in P VIni (init mv) states noChunk (errs []) valEOI