0 | module Text.ILex.Interfaces
3 | import Data.Linear.Ref1
6 | import Text.ByteBounds
7 | import Text.ILex.Char.UTF8
8 | import Text.ILex.Parser
9 | import Text.ILex.Util
10 | import Text.ParseError
25 | interface HasBBErr (0 s : Type -> Type) (0 e : Type) | s where
27 | error : s q -> Ref q (Maybe $
BBErr e)
32 | interface HasStringLits (0 s : Type -> Type) where
34 | strings : s q -> Ref q (SnocList String)
39 | interface HasStack (0 s : Type -> Type) (0 a : Type) | s where
41 | stack : s q -> Ref q a
48 | go : a -> (s q => F1 q (Index r)) -> (a,Step q r s)
49 | go x f = (x, Run $
\(E x t) => f t)
52 | ign : a -> (a,Step q r s)
56 | goBS : HasBytes s => a -> (s q => ByteString -> F1 q (Index r)) -> (a,Step q r s)
57 | goBS x f = (x, Run $
\(E x t) => let bs # t := getBytes t in f bs t)
60 | goStr : HasBytes s => a -> (s q => String -> F1 q (Index r)) -> (a,Step q r s)
61 | goStr x f = (x, Run $
\(E x t) => let s # t := Parser.getString t in f s t)
65 | writeAs : Ref q a -> a -> r -> F1 q r
66 | writeAs ref v res = write1 ref v >> pure res
70 | push1 : Ref q (SnocList a) -> a -> F1' q
78 | pop1 : Ref q (SnocList a) -> F1' q
81 | sv:<_ => write1 ref sv
87 | replace1 : Ref q a -> a -> F1 q a
88 | replace1 ref v = T1.do
96 | getList : Ref q (SnocList a) -> F1 q (List a)
98 | sv <- replace1 ref [<]
103 | pushStack : HasStack s (SnocList a) => (sk : s q) => a -> F1' q
104 | pushStack = push1 (stack sk)
108 | pushStackAs : HasStack s (SnocList a) => (sk : s q) => a -> v -> F1 q v
109 | pushStackAs v res = pushStack v >> pure res
114 | countdown : Ref q Nat -> (ifSucc, ifZero : a) -> F1 q a
115 | countdown ref s z t =
116 | let S k # t := read1 ref t | Z # t => z # t
117 | in writeAs ref k s t
122 | countdownAct : Ref q Nat -> (ifSucc, ifZero : F1 q a) -> F1 q a
123 | countdownAct ref s z t =
124 | let S k # t := read1 ref t | Z # t => z t
125 | _ # t := write1 ref k t
132 | parameters {auto sk : s q}
133 | {auto pos : HasStringLits s}
138 | getStr : F1 q String
140 | sv <- replace1 (strings sk) [<]
146 | pushStr' : String -> F1' q
147 | pushStr' str = push1 (strings sk) str
152 | pushStr : Cast t (Index r) => t -> String -> F1 q (Index r)
153 | pushStr res str = T1.do
154 | push1 (strings sk) str
160 | pushChar : Cast t (Index r) => t -> Char -> F1 q (Index r)
161 | pushChar res = pushStr res . singleton
166 | pushBits32 : Cast t (Index r) => t -> Bits32 -> F1 q (Index r)
167 | pushBits32 res = pushChar res . cast
173 | parameters {auto sk : s q}
174 | {auto hb : HasBytes s}
179 | startPos : F1 q BytePos
181 | LN f <- read1 (from sk)
183 | 0 => BP (prevOffset sk)
184 | _ => BP (curOffset sk + f)
188 | endPos : F1 q BytePos
190 | let LN rf # t := read1 (from sk) t
191 | LN rt # t := read1 (till sk) t
192 | coff := curOffset sk
195 | 0 => let from := prevOffset sk in endPos from till # t
196 | _ => let from := coff + rf in endPos from till # t
200 | bounds : F1 q ByteBounds
202 | let LN rf # t := read1 (from sk) t
203 | LN rt # t := read1 (till sk) t
204 | coff := curOffset sk
207 | 0 => let from := prevOffset sk in BB (BP from) (endPos from till) # t
208 | _ => let from := coff + rf in BB (BP from) (endPos from till) # t
212 | bounded : F1 q a -> F1 q (ByteBounded a)
214 | let bs # t := Interfaces.bounds t
220 | bounded' : a -> F1 q (ByteBounded a)
222 | let bs # t := Interfaces.bounds t
233 | pushPosition : F1' q
234 | pushPosition = startPos >>= push1 (positions sk)
238 | popPosition : F1' q
239 | popPosition = pop1 (positions sk)
241 | popAndGetBounds : Nat -> F1 q ByteBounds
242 | popAndGetBounds n =
243 | read1 (positions sk) >>= \case
244 | sb:<b => writeAs (positions sk) sb (BB b $
incLen n b)
251 | closeBounds : F1 q ByteBounds
252 | closeBounds = T1.do
254 | read1 (positions sk) >>= \case
255 | sb:<b => writeAs (positions sk) sb (BB b pe)
262 | parameters {auto hs : HasStack s a}
268 | getStack = read1 (stack sk)
273 | putStack : a -> F1' q
274 | putStack = write1 (stack sk)
278 | putStackAs : a -> v -> F1 q v
279 | putStackAs = writeAs (stack sk)
283 | putStackAsC : Cast b v => a -> b -> F1 q v
284 | putStackAsC res = putStackAs res . cast
287 | withStack : (a -> F1 q b) -> F1 q b
288 | withStack f = getStack >>= f
291 | boundsWithStack : HasBytes s => (ByteBounds -> a -> F1 q b) -> F1 q b
292 | boundsWithStack f = bounds >>= withStack . f
295 | posWithStack : HasBytes s => (BytePos -> a -> F1 q b) -> F1 q b
296 | posWithStack f = startPos >>= withStack . f
299 | boundedWithStack : HasBytes s => (ByteBounded x -> a -> F1 q b) -> x -> F1 q b
300 | boundedWithStack f v = bounds >>= withStack . f . B v
305 | modStackAs : (0 s : _) -> HasStack s a => s q => (a -> a) -> v -> F1 q v
306 | modStackAs _ f v = getStack >>= \x => putStackAs (f x) v
311 | -> {auto hb : HasBytes s}
312 | -> {auto hs : HasStack s a}
314 | -> (a -> BytePos -> a)
317 | posModStack s f v = T1.do
320 | putStackAs (f x p) v
326 | parameters {auto hae : HasBBErr s e}
330 | ifNoErrorRaised : F1 q (BBErr e) -> F1 q (BBErr e)
331 | ifNoErrorRaised raise = read1 (error sk) >>= maybe raise pure
334 | unexpectedErr : HasBytes s => List String -> F1 q (InnerError e)
335 | unexpectedErr ss = T1.do
341 | s := String.singleton (cast b)
342 | in case isAscii b of
343 | True => Expected ss s
344 | False => InvalidByte b
345 | _ => Expected ss (toString bs)
348 | unclosedErr : HasBytes s => String -> F1 q (BBErr e)
349 | unclosedErr str = T1.do
350 | bnds <- popAndGetBounds (length str)
351 | pure $
B (Unclosed str) bnds
356 | unclosedIfEOIErr : HasBytes s => String -> List String -> F1 q (BBErr e)
357 | unclosedIfEOIErr s ss =
359 | BS 0 _ => unclosedErr s
360 | bs => bounded (unexpectedErr ss)
366 | unclosedIfNLorEOIErr : HasBytes s => String -> List String -> F1 q (BBErr e)
367 | unclosedIfNLorEOIErr s ss =
369 | BS 0 _ => unclosedErr s
371 | if elem 0x0a bs then unclosedErr s else bounded (unexpectedErr ss)
380 | failWith : BBErr e -> v -> F1 q v
382 | read1 (error sk) >>= \case
384 | Nothing => writeAs (error sk) (Just x) v
389 | failHere : HasBytes s => InnerError e -> v -> F1 q v
390 | failHere x res = T1.do
392 | failWith (B x bs) res
395 | failUnexpected : HasBytes s => List String -> v -> F1 q v
396 | failUnexpected vs v = unexpectedErr vs >>= flip failHere v
399 | failUnclosed : HasBytes s => String -> v -> F1 q v
400 | failUnclosed s v = unclosedErr s >>= flip failWith v
403 | failUnclosedIfEOI : HasBytes s => String -> List String -> v -> F1 q v
404 | failUnclosedIfEOI s ss v = unclosedIfEOIErr s ss >>= flip failWith v
410 | parameters {auto hbp : HasBytes s}
414 | ignore : (a,Step q r s)
418 | step : (s q => F1 q (Index r)) -> (a,Step q r s)
422 | step' : Cast t (Index r) => t -> (a,Step q r s)
423 | step' x = step (pure $
cast x)
426 | bytes : (s q => ByteString -> F1 q (Index r)) -> (a,Step q r s)
430 | string : (s q => String -> F1 q (Index r)) -> (a,Step q r s)
431 | string f = goStr x f
440 | opn : (s q => F1 q (Index r)) -> (a, Step q r s)
441 | opn f = step $
pushPosition >> f
445 | opn' : Cast t (Index r) => t -> (a, Step q r s)
446 | opn' v = opn $
pure (cast v)
454 | close : (s q => F1 q (Index r)) -> (a, Step q r s)
455 | close f = step $
popPosition >> f
464 | {auto hap : HasStringLits s}
465 | -> (s q => String -> F1 q (Index r))
467 | closeStr f = close $
getStr >>= f
475 | closeWithBounds : (s q => ByteBounds -> F1 q (Index r)) -> (a, Step q r s)
476 | closeWithBounds f = step $
closeBounds >>= f
485 | {auto hap : HasStringLits s}
486 | -> (s q => ByteBounded String -> F1 q (Index r))
488 | closeBoundedStr f = closeWithBounds $
\bs => getStr >>= \s => f (B s bs)
490 | parameters {auto hbp : HasBytes s}
499 | (display : a -> String)
500 | -> (act : a -> Step1 q r s)
502 | -> Maybe (RExp True, Step q r s)
503 | val display act v =
505 | in case unpack (display v) of
506 | cs@(_::_) => Just $
step (chars cs) (f %search)
513 | (displays : a -> List String)
514 | -> (act : a -> Step1 q r s)
516 | -> List (RExp True, Step q r s)
517 | valN displays act v =
519 | in mapMaybe (exp f . unpack) (displays v)
521 | exp : Step1 q r s -> List Char -> Maybe (RExp True, Step q r s)
522 | exp f cs@(_::_)= Just $
step (chars cs) (f %search)
529 | (display : a -> String)
530 | -> (field : s q -> Ref q a)
533 | -> Maybe (RExp True, Step q r s)
534 | writeVal display field res =
535 | val display (\v,x => writeAs (field x) v res)
541 | (displays : a -> List String)
542 | -> (field : s q -> Ref q a)
545 | -> List (RExp True, Step q r s)
546 | writeValN displays field res =
547 | valN displays (\v,x => writeAs (field x) v res)
555 | (display : a -> String)
556 | -> (act : a -> Step1 q r s)
558 | -> List (RExp True, Step q r s)
559 | vals display = mapMaybe . val display
568 | (displays : a -> List String)
569 | -> (act : a -> Step1 q r s)
571 | -> List (RExp True, Step q r s)
572 | valsN displays act vs = vs >>= valN displays act
578 | (display : a -> String)
579 | -> (field : s q -> Ref q a)
582 | -> List (RExp True, Step q r s)
583 | writeVals display field = mapMaybe . writeVal display field
589 | (displays : a -> List String)
590 | -> (field : s q -> Ref q a)
593 | -> List (RExp True, Step q r s)
594 | writeValsN displays field res vs = vs >>= writeValN displays field res
597 | jsonSpace : RExp True
598 | jsonSpace = oneof [' ','\t','\n','\r']
601 | jsonSpaces : RExp True
602 | jsonSpaces = plus jsonSpace
605 | jsonSpaced : HasBytes s => Steps q r s -> Steps q r s
606 | jsonSpaced xs = ignore jsonSpaces :: xs
612 | parameters {auto he : HasBBErr s e}
613 | {auto pos : HasBytes s}
616 | raise : InnerError e -> Nat -> s q => v -> F1 q v
617 | raise err n res = T1.do
619 | failWith (B err $
BB ps (incLen n ps)) res
622 | unexpected : List String -> s q -> F1 q (BBErr e)
623 | unexpected strs sk = ifNoErrorRaised (bounded $
unexpectedErr strs)
626 | unclosed : String -> s q -> F1 q (BBErr e)
627 | unclosed str sk = ifNoErrorRaised (unclosedErr str)
632 | unclosedIfEOI : String -> List String -> s q -> F1 q (BBErr e)
633 | unclosedIfEOI s ss sk = ifNoErrorRaised (unclosedIfEOIErr s ss)
639 | unclosedIfNLorEOI : String -> List String -> s q -> F1 q (BBErr e)
640 | unclosedIfNLorEOI s ss sk = ifNoErrorRaised (unclosedIfNLorEOIErr s ss)
645 | -> List (Entry n $
s q -> F1 q (BBErr e))
646 | -> Arr32 n (s q -> F1 q (BBErr e))
647 | errs = arr32 n (unexpected [])
661 | noChunk : s -> F1 q (Maybe a)
662 | noChunk _ t = (Nothing # t)
667 | snocChunk : HasStack s (SnocList a) => s q -> F1 q (Maybe $
List a)
668 | snocChunk sk = T1.do
669 | ss <- replace1 (stack sk) [<]
670 | pure (maybeList ss)