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
38 | cur_ : IBuffer bufSize_
41 | from_ : Ref q (LTENat bufSize_)
42 | till_ : Ref q (LTENat bufSize_)
43 | positions_ : Ref q (SnocList BytePos)
49 | state_ : Ref q (Index r)
52 | strings_ : Ref q (SnocList String)
55 | error_ : Ref q (Maybe $
BBErr e)
57 | %runElab derive "Stack" [FullStack]
61 | init : (0 p : 0 < r) => a -> (n : Nat) -> IBuffer n -> F1 q (Stack e a r q)
62 | init v n buf = T1.do
63 | rf <- ref1 (first n)
64 | rt <- ref1 (first n)
70 | pure (S n empty buf 0 0 rf rt ps sk st ss er)
77 | 0 Tok : Type -> Type
81 | 0 Toks : Type -> Type
85 | 0 Skot : Type -> Type
86 | Skot = SnocList . ByteBounded
89 | 0 L1 : (q,e : Type) -> (a : Type) -> Type
90 | L1 q e a = P1 q (BBErr e) (Toks a)
93 | 0 Lexer : (e : Type) -> Type -> Type
94 | Lexer e a = {0 q : Type} -> L1 q e a
96 | parameters {auto hb : HasBytes s}
97 | {auto hs : HasStack s (Skot a)}
102 | pushBounded : s q => a -> F1 q (Index r)
103 | pushBounded v = bounded' v >>= \b => pushStackAs b 0
106 | tok : a -> (RExp True, Step q r s)
107 | tok v = step x (pushBounded v)
110 | byteTok : (ByteString -> a) -> (RExp True, Step q r s)
111 | byteTok f = bytes x (pushBounded . f)
114 | stringTok : (String -> a) -> (RExp True, Step q r s)
115 | stringTok f = string x (pushBounded . f)
119 | {auto 0 lt : 0 < r}
120 | -> {auto stk : HasStack s (SnocList a)}
121 | -> {auto err : HasBBErr s e}
122 | -> {auto bts : HasBytes s}
125 | -> F1 q (Either (BBErr e) $
List a)
128 | then getList (stack sk) >>= pure . Right
129 | else unexpected [] sk >>= pure . Left
132 | lexer : {r : _} -> (0 lt : 0 < r) => Steps q r (Stack e (Skot a) r) -> L1 q e a
133 | lexer m = P Ini (init [<]) (lex1 [E Ini $
dfa m]) snocChunk (errs []) lexEOI
139 | %runElab deriveParserState "VSz" "VST" ["VIni", "VErr", "VDone"]
143 | data Token : (e, a : Type) -> Type where
150 | Const : a -> Token e a
153 | Txt : (String -> Either e a) -> Token e a
156 | Bytes : (ByteString -> Either e a) -> Token e a
159 | const : a -> Token e a
163 | txt : (String -> a) -> Token e a
164 | txt f = Txt (Right . f)
167 | bytes : (ByteString -> a) -> Token e a
168 | bytes f = Bytes (Right . f)
171 | (RExpOf True b, Token e a)
172 | -> (RExpOf True b, Step q VSz (Stack e (Maybe a) VSz))
176 | Const v => step x (putStackAs (Just v) VDone)
178 | string x $
\s => case f s of
179 | Right v => putStackAs (Just v) VDone
180 | Left e => failHere (Custom e) VErr
182 | bytes x $
\s => case f s of
183 | Right v => putStackAs (Just v) VDone
184 | Left e => failHere (Custom e) VErr
187 | (RExpOf True b, Token e a)
188 | -> Maybe (RExpOf True b, Step q VSz (Stack e (Maybe a) VSz))
189 | ignore (x,Ignore) = Just $
ignore x
192 | valEOI : VST -> Stack e (Maybe a) VSz q -> F1 q (Either (BBErr e) a)
194 | if i == VDone || i == VIni
195 | then replace1 sk.stack_ Nothing >>= \case
196 | Just v => pure (Right v)
197 | Nothing => unexpected [] sk >>= pure . Left
198 | else unexpected [] sk >>= pure . Left
201 | 0 PVal1 : (q,e : Type) -> (a : Type) -> Type
202 | PVal1 q e a = P1 q (BBErr e) a
206 | value : Maybe a -> TokenMap (Token e a) -> PVal1 q e a
208 | let iniSteps := E VIni $
dfa (map toStep m)
209 | doneSteps := E VDone $
dfa (mapMaybe ignore m)
210 | states := lex1 [iniSteps, doneSteps]
211 | in P VIni (init mv) states noChunk (errs []) valEOI