0 | module Text.ILex.Interfaces
3 | import Data.Linear.Ref1
7 | import Text.ILex.Char.UTF8
8 | import Text.ILex.Parser
9 | import Text.ILex.Util
10 | import Text.ParseError
26 | interface HasPosition (0 s : Type -> Type) where
28 | line : s q -> Ref q Nat
29 | col : s q -> Ref q Nat
30 | positions : s q -> Ref q (SnocList Position)
35 | interface HasError (0 s : Type -> Type) (0 e : Type) | s where
37 | error : s q -> Ref q (Maybe $
BoundedErr e)
42 | interface HasStringLits (0 s : Type -> Type) where
44 | strings : s q -> Ref q (SnocList String)
49 | interface HasStack (0 s : Type -> Type) (0 a : Type) | s where
51 | stack : s q -> Ref q a
58 | go : a -> (s q => F1 q (Index r)) -> (a,Step q r s)
59 | go x f = (x,Go $
\(x # t) => f t)
62 | goBS : HasBytes s => a -> (s q => ByteString -> F1 q (Index r)) -> (a,Step q r s)
63 | goBS x f = (x, Rd $
\(x # t) => let bs # t := read1 (bytes x) t in f bs t)
66 | goStr : HasBytes s => a -> (s q => String -> F1 q (Index r)) -> (a,Step q r s)
70 | let bs # t := read1 (bytes x) t
77 | writeAs : Ref q a -> a -> r -> F1 q r
78 | writeAs ref v res = write1 ref v >> pure res
82 | push1 : Ref q (SnocList a) -> a -> F1' q
90 | pop1 : Ref q (SnocList a) -> F1' q
93 | sv:<_ => write1 ref sv
99 | replace1 : Ref q a -> a -> F1 q a
100 | replace1 ref v = T1.do
108 | getList : Ref q (SnocList a) -> F1 q (List a)
109 | getList ref = T1.do
110 | sv <- replace1 ref [<]
116 | getStack : HasStack s a => (sk : s q) => F1 q a
117 | getStack = read1 (stack sk)
122 | putStack : HasStack s a => (sk : s q) => a -> F1' q
123 | putStack = write1 (stack sk)
127 | putStackAs : HasStack s a => (sk : s q) => a -> v -> F1 q v
128 | putStackAs = writeAs (stack sk)
132 | putStackAsC : Cast b v => HasStack s a => (sk : s q) => a -> b -> F1 q v
133 | putStackAsC res = putStackAs res . cast
137 | modStackAs : (0 s : _) -> HasStack s a => (sk : s q) => (a -> a) -> v -> F1 q v
138 | modStackAs _ f v = getStack >>= \x => putStackAs (f x) v
142 | pushStack : HasStack s (SnocList a) => (sk : s q) => a -> F1' q
143 | pushStack = push1 (stack sk)
147 | pushStackAs : HasStack s (SnocList a) => (sk : s q) => a -> v -> F1 q v
148 | pushStackAs v res = pushStack v >> pure res
153 | countdown : Ref q Nat -> (ifSucc, ifZero : a) -> F1 q a
154 | countdown ref s z t =
155 | let S k # t := read1 ref t | Z # t => z # t
156 | in writeAs ref k s t
161 | countdownAct : Ref q Nat -> (ifSucc, ifZero : F1 q a) -> F1 q a
162 | countdownAct ref s z t =
163 | let S k # t := read1 ref t | Z # t => z t
164 | _ # t := write1 ref k t
171 | parameters {auto sk : s q}
172 | {auto pos : HasStringLits s}
177 | getStr : F1 q String
179 | sv <- replace1 (strings sk) [<]
185 | pushStr' : String -> F1' q
186 | pushStr' str = push1 (strings sk) str
191 | pushStr : Cast t (Index r) => t -> String -> F1 q (Index r)
192 | pushStr res str = T1.do
193 | push1 (strings sk) str
199 | pushChar : Cast t (Index r) => t -> Char -> F1 q (Index r)
200 | pushChar res = pushStr res . singleton
205 | pushBits32 : Cast t (Index r) => t -> Bits32 -> F1 q (Index r)
206 | pushBits32 res = pushChar res . cast
212 | parameters {auto sk : s q}
213 | {auto pos : HasPosition s}
218 | getPosition : F1 q Position
219 | getPosition = T1.do
220 | l <- read1 (line sk)
221 | c <- read1 (col sk)
227 | inccol : Nat -> F1 q ()
228 | inccol n = let c := col sk in read1 c >>= write1 c . (n+)
233 | setcol : Nat -> F1 q ()
234 | setcol n = write1 (col sk) n
240 | incline : Nat -> F1 q ()
242 | l <- read1 (line sk)
243 | write1 (line sk) (n + l)
251 | incML : ByteString -> F1 q ()
254 | let P l c := incBytes bs p
262 | tokenBounds : Nat -> F1 q Bounds
263 | tokenBounds n = T1.do
277 | pushPosition : F1' q
278 | pushPosition = getPosition >>= push1 (positions sk)
282 | popPosition : F1' q
283 | popPosition = pop1 (positions sk)
285 | popAndGetBounds : Nat -> F1 q Bounds
286 | popAndGetBounds n =
287 | read1 (positions sk) >>= \case
288 | sb:<b => writeAs (positions sk) sb (BS b $
addCol n b)
289 | [<] => pure NoBounds
295 | closeBounds : F1 q Bounds
296 | closeBounds = T1.do
298 | read1 (positions sk) >>= \case
299 | sb:<b => writeAs (positions sk) sb (BS b pe)
300 | [<] => pure NoBounds
302 | parameters {auto pos : HasPosition s}
307 | newline : RExpOf True b -> (v : s q => F1 q (Index r)) -> (RExpOf True b, Step q r s)
308 | newline x f = go x $
f <* incline 1
312 | newline' : Cast t (Index r) => RExpOf True b -> t -> (RExpOf True b, Step q r s)
313 | newline' x v = go x $
incline 1 >> pure (cast v)
321 | -> (v : s q => F1 q (Index r))
322 | -> (RExpOf True b, Step q r s)
323 | newlines n x f = go x $
f <* incline n
327 | newlines' : Nat -> RExpOf True b -> (v : Index r) -> (RExpOf True b, Step q r s)
328 | newlines' n x v = go x $
incline n >> pure v
337 | -> (v : s q => F1 q (Index r))
338 | -> (RExpOf True b, Step q r s)
339 | linecol l c x f = go x $
f <* incline l <* setcol c
343 | linecol' : (line,col : Nat) -> RExpOf True b -> Index r -> (RExpOf True b, Step q r s)
344 | linecol' l c x v = go x $
incline l >> setcol c >> pure v
346 | parameters {auto hae : HasError s e}
351 | failWith : (sk : s q) => BoundedErr e -> v -> F1 q v
352 | failWith = writeAs (error sk) . Just
357 | failHere : HasBytes s => HasPosition s => (sk : s q) => InnerError e -> v -> F1 q v
358 | failHere x res = T1.do
360 | bs <- read1 (bytes sk)
361 | failWith (B x $
BS p (incBytes bs p)) res
367 | parameters (x : RExpOf True b)
369 | {auto 0 prf : ConstSize n x}
370 | {auto pos : HasPosition s}
377 | cexpr : (s q => F1 q (Index r)) -> (RExpOf True b, Step q r s)
378 | cexpr f = go x $
inccol n >> f
382 | cexpr' : Cast t (Index r) => t -> (RExpOf True b, Step q r s)
383 | cexpr' v = cexpr $
pure (cast v)
392 | copen : (s q => F1 q (Index r)) -> (RExpOf True b, Step q r s)
393 | copen f = go x $
pushPosition >> inccol n >> f
397 | copen' : Cast t (Index r) => t -> (RExpOf True b, Step q r s)
398 | copen' v = copen $
pure (cast v)
406 | cclose : (s q => F1 q (Index r)) -> (RExpOf True b, Step q r s)
407 | cclose f = go x $
inccol n >> popPosition >> f
416 | {auto hap : HasStringLits s}
417 | -> (s q => String -> F1 q (Index r))
418 | -> (RExpOf True b, Step q r s)
419 | ccloseStr f = cclose $
getStr >>= f
427 | ccloseWithBounds : (s q => Bounds -> F1 q (Index r)) -> (RExpOf True b, Step q r s)
428 | ccloseWithBounds f = go x $
inccol {q} n >> closeBounds >>= f
437 | {auto hap : HasStringLits s}
438 | -> (s q => Bounded String -> F1 q (Index r))
439 | -> (RExpOf True b, Step q r s)
440 | ccloseBoundedStr f = ccloseWithBounds $
\bs => getStr >>= \s => f (B s bs)
442 | parameters {auto pos : HasPosition s}
451 | (display : a -> String)
452 | -> (act : a -> Step1 q r s)
454 | -> Maybe (RExp True, Step q r s)
455 | val display act v =
457 | in case unpack (display v) of
459 | let 0 prf := charsConstSize cs
460 | in Just $
cexpr (chars cs) (\t => f (%search # t))
467 | (displays : a -> List String)
468 | -> (act : a -> Step1 q r s)
470 | -> List (RExp True, Step q r s)
471 | valN displays act v =
473 | in mapMaybe (exp f . unpack) (displays v)
475 | exp : Step1 q r s -> List Char -> Maybe (RExp True, Step q r s)
477 | let 0 prf := charsConstSize cs
478 | in Just $
cexpr (chars cs) (\t => f (%search # t))
485 | (display : a -> String)
486 | -> (field : s q -> Ref q a)
489 | -> Maybe (RExp True, Step q r s)
490 | writeVal display field res =
491 | val display (\v => \(x # t) => writeAs (field x) v res t)
497 | (displays : a -> List String)
498 | -> (field : s q -> Ref q a)
501 | -> List (RExp True, Step q r s)
502 | writeValN displays field res =
503 | valN displays (\v => \(x # t) => writeAs (field x) v res t)
511 | (display : a -> String)
512 | -> (act : a -> Step1 q r s)
514 | -> List (RExp True, Step q r s)
515 | vals display = mapMaybe . val display
524 | (displays : a -> List String)
525 | -> (act : a -> Step1 q r s)
527 | -> List (RExp True, Step q r s)
528 | valsN displays act vs = vs >>= valN displays act
534 | (display : a -> String)
535 | -> (field : s q -> Ref q a)
538 | -> List (RExp True, Step q r s)
539 | writeVals display field = mapMaybe . writeVal display field
545 | (displays : a -> List String)
546 | -> (field : s q -> Ref q a)
549 | -> List (RExp True, Step q r s)
550 | writeValsN displays field res vs = vs >>= writeValN displays field res
556 | parameters (x : RExpOf True b)
557 | {auto pos : HasPosition s}
558 | {auto pos : HasBytes s}
563 | read : (s q => String -> F1 q (Index r)) -> (RExpOf True b, Step q r s)
564 | read f = goStr x $
\s => f s <* inccol (length s)
569 | readline : (s q => String -> F1 q (Index r)) -> (RExpOf True b, Step q r s)
570 | readline f = goStr x $
\s => f s <* incline 1
575 | read' : Cast t (Index r) => t -> (RExpOf True b, Step q r s)
578 | , Rd $
\(sk # t) =>
579 | let bs # t := read1 (bytes sk) t
580 | _ # t := inccol (length $
toString bs) t
587 | conv : (s q => ByteString -> F1 q (Index r)) -> (RExpOf True b, Step q r s)
588 | conv f = goBS x $
\bs => f bs <* inccol (size bs)
593 | convline : (s q => ByteString -> F1 q (Index r)) -> (RExpOf True b, Step q r s)
594 | convline f = goBS x $
\bs => f bs <* incline 1
605 | multiline : (s q => ByteString -> F1 q (Index r)) -> (RExpOf True b, Step q r s)
606 | multiline f = goBS x $
\bs => f bs <* incML bs
610 | conv' : Cast t (Index r) => t -> (RExpOf True b, Step q r s)
613 | , Rd $
\(sk # t) =>
614 | let bs # t := read1 (bytes sk) t
615 | _ # t := inccol (size bs) t
624 | multiline' : Index r -> (RExpOf True b, Step q r s)
627 | , Rd $
\(sk # t) =>
628 | let bs # t := read1 (bytes sk) t
629 | _ # t := incML bs t
635 | {auto hp : HasPosition s}
636 | -> {auto hb : HasBytes s}
637 | -> {auto cs : Cast b (Index r)}
642 | [ conv' (plus $
oneof [' ','\t']) v
643 | , newline' ('\n' <|> '\r' <|> "\r\n") v
650 | parameters {auto he : HasError s e}
651 | {auto pos : HasPosition s}
652 | {auto pos : HasBytes s}
655 | raise : InnerError e -> Nat -> s q => v -> F1 q v
656 | raise err n res = T1.do
658 | let bs := BS ps (addCol n ps)
659 | failWith (B err bs) res
662 | unexpected : List String -> s q -> F1 q (BoundedErr e)
663 | unexpected strs sk =
664 | read1 (error sk) >>= \case
667 | bs <- read1 (bytes sk)
669 | let bnds1 := BS ps $
incCol ps
671 | BS 0 _ => pure (B EOI bnds1)
674 | s := String.singleton (cast b)
675 | in case isAscii b of
676 | True => pure (B (Expected strs s) bnds1)
677 | False => pure (B (InvalidByte b) bnds1)
679 | let str := toString bs
680 | bnds := BS ps (incBytes bs ps)
681 | in pure (B (Expected strs str) bnds)
684 | unclosed : String -> s q -> F1 q (BoundedErr e)
685 | unclosed str sk = T1.do
686 | bnds <- popAndGetBounds (length str)
687 | pure $
B (Unclosed str) bnds
692 | unclosedIfEOI : String -> List String -> s q -> F1 q (BoundedErr e)
693 | unclosedIfEOI s ss sk =
694 | read1 (bytes sk) >>= \case
695 | BS 0 _ => unclosed s sk
696 | _ => unexpected ss sk
702 | unclosedIfNLorEOI : String -> List String -> s q -> F1 q (BoundedErr e)
703 | unclosedIfNLorEOI s ss sk =
704 | read1 (bytes sk) >>= \case
705 | BS 0 _ => unclosed s sk
706 | bs => if elem 0x0a bs then unclosed s sk else unexpected ss sk
711 | -> List (Entry n $
s q -> F1 q (BoundedErr e))
712 | -> Arr32 n (s q -> F1 q (BoundedErr e))
713 | errs = arr32 n (unexpected [])
727 | noChunk : s -> F1 q (Maybe a)
728 | noChunk _ t = (Nothing # t)
733 | snocChunk : HasStack s (SnocList a) => s q -> F1 q (Maybe $
List a)
734 | snocChunk sk = T1.do
735 | ss <- replace1 (stack sk) [<]
736 | pure (maybeList ss)