on 8564483 help sign in
1184 lines 21 kB history raw
1---
2navhome: /docs
3---
6# 4f: parsing (rule builders)
7### `++bass`
9Parser modifier: LSB
10ordered `++list` as atom of a `++base`.
12Accepts
13-------
15`wuc` is an atom.
17`tyd` is a `++rule`.
19Produces
20--------
22A `++rule`.
24Source
25------
27 ++ bass
28 |* {wuc/@ tyd/rule}
29 %+ cook
30 |= waq/(list @)
31 %+ roll
32 waq
33 =|({p/@ q/@} |.((add p (mul wuc q))))
34 tyd
35 ::
38Examples
39--------
41 > (scan "123" (bass 10 (star dit)))
42 q=123
43 > (scan "123" (bass 8 (star dit)))
44 q=83
45 > `@ub`(scan "123" (bass 8 (star dit)))
46 0b101.0011
50***
52### `++boss`
54Parser modifier: LSB
56Ordered `++list` as atom of a `++base`.
58Accepts
59-------
61`wuc` is an atom.
63`tyd` is a `++rule`.
65Produces
66--------
68A `++rule`.
70Source
71------
73 ++ boss
74 |* {wuc/@ tyd/rule}
75 %+ cook
76 |= waq/(list @)
77 %+ reel
78 waq
79 =|({p/@ q/@} |.((add p (mul wuc q))))
80 tyd
81 ::
83Examples
84--------
86 > (scan "123" (boss 10 (star dit)))
87 q=321
88 > `@t`(scan "bam" (boss 256 (star alp)))
89 'bam'
90 > `@ux`(scan "bam" (boss 256 (star alp)))
91 0x6d.6162
94***
95### `++cold`
97Replace with constant
99Parser modifier. Accepts a `++rule` `sef` and produces a parser that
100produces a constant `cus`, assuming `sef` is successful.
102Accepts
103-------
105`cus` is a constant noun.
107`sef` is a `++rule`.
109Produces
110--------
112An `++edge`.
114Source
115------
117 ++ cold :: replace w+ constant
118 ~/ %cold
119 |* {cus/* sef/rule}
120 ~/ %fun
121 |= tub/nail
122 =+ vex=(sef tub)
123 ?~ q.vex
124 vex
125 [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
127Examples
128--------
130 > ((cold %foo (just 'a')) [[1 1] "abc"])
131 [p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
132 > ((cold %foo (just 'a')) [[1 1] "bc"])
133 [p=[p=1 q=1] q=~]
137***
138### `++cook`
140Apply gate
142Parser modifier. Produces a parser that takes a (successful) result of a
143`++rule` `sef` and slams it through `poq`.
145Accepts
146-------
148`poq` is a gate.
150`sef` is a `++rule`.
152Produces
153--------
155An `++rule`.
157Source
158------
160 ++ cook :: apply gate
161 ~/ %cook
162 |* {poq/$-(* *) sef/rule}
163 ~/ %fun
164 |= tub/nail
165 =+ vex=(sef tub)
166 ?~ q.vex
167 vex
168 [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
169 ::
171Examples
172--------
174 > ((cook ,@ud (just 'a')) [[1 1] "abc"])
175 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
176 > ((cook ,@tas (just 'a')) [[1 1] "abc"])
177 [p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
178 > ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
179 [p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
180 > ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
181 [p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
185***
186### `++easy`
188Always parse
190Parser generator. Produces a parser that succeeds with given noun `huf`
191without consuming any text.
193Accepts
194-------
196`huf` is a noun.
198Produces
199--------
201A `++rule`.
203Source
204------
206 ++ easy :: always parse
207 ~/ %easy
208 |* huf=*
209 ~/ %fun
210 |= tub=nail
211 ^- (like ,_huf)
212 [p=p.tub q=[~ u=[p=huf q=tub]]]
213 ::
215Examples
216--------
218 > ((easy %foo) [[1 1] "abc"])
219 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
220 > ((easy %foo) [[1 1] "bc"])
221 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
222 > ((easy 'a') [[1 1] "bc"])
223 [p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
227***
228### `++full`
230Parse to end
232Parser modifier. Accepts a `++rule` `sef`, and produces a parser that succeeds only
233when the of `tub` is fully consumed using `sef`.
235Accepts
236-------
238`sef` is a `++rule`.
240Produces
241--------
243A `++rule`.
245Source
246------
248 ++ full :: parse to end
249 |* sef=_rule
250 |= tub=nail
251 =+ vex=(sef tub)
252 ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
253 ::
255Examples
256--------
258 > ((full (just 'a')) [[1 1] "ab"])
259 [p=[p=1 q=2] q=~]
260 > ((full (jest 'ab')) [[1 1] "ab"])
261 [p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
262 > ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
263 [p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
267***
268### `++funk`
270Add to tape
272Parser modifier: prepend text to `++tape` before applying parser.
274Accepts
275-------
277`pre` is a `++tape`
279`sef` is a `++rule`
281Produces
282--------
284A `++rule`.
286Source
287------
289 ++ funk :: add to tape first
290 |* {pre/tape sef/rule}
291 |= tub/nail
292 (sef p.tub (weld pre q.tub))
294Examples
295--------
297 > ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
298 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
299 > ((funk "parse" (just 'a')) [[1 4] " me"])
300 [p=[p=1 q=4] q=~]
304***
305### `++here`
307Place-based apply
309Parser modifier. Similar to `++cook` in that it produces a parser that takes a
310(successful) result of `sef` and slams it through `hez`. `hez` accepts a
311`++pint` `a` and a noun `b`, which is what the parser parsed.
313Accepts
314-------
316`hez` is a gate.
318`sef` is a `++rule`
320Produces
321--------
323A `++rule`.
325Source
326------
328 ++ here :: place-based apply
329 ~/ %here
330 |* {hez/_|=({a/pint b/*} [a b]) sef/rule}
331 ~/ %fun
332 |= tub/nail
333 =+ vex=(sef tub)
334 ?~ q.vex
335 vex
336 [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
337 ::
339Examples
340--------
342 > (scan "abc" (star alf))
343 "abc"
344 > (scan "abc" (here |*(^ +<) (star alf)))
345 [[[p=1 q=1] p=1 q=4] "abc"]
346 > (scan "abc" (star (here |*(^ +<) alf)))
347 ~[[[[p=1 q=1] p=1 q=2] ~~a] [[[p=1 q=2] p=1 q=3] ~~b] [[[p=1 q=3] p=1 q=4] ~~c]]
351***
352### `++ifix`
354Infix
356Parser modifier: surround with pair of `++rule`s, the output of which is
357discarded.
359Accepts
360-------
362`fel` is a pair of `++rule`s.
364`hof` is a `++rule`.
366Produces
367--------
369A `++rule`.
371Source
372------
374 ++ ifix
375 |* {fel/{rule rule} hof/rule}
376 ~! +<
377 ~! +<:-.fel
378 ~! +<:+.fel
379 ;~(pfix -.fel ;~(sfix hof +.fel))
380 ::
382Examples
383--------
385 > (scan "-40-" (ifix [hep hep] dem))
386 q=40
387 > (scan "4my4" (ifix [dit dit] (star alf)))
388 "my"
392***
393### `++jest`
395Match a cord
397Match and consume a cord.
399Accepts
400-------
402`daf` is a `@t`.
404Produces
405--------
407An `++edge`.
409Source
410------
412 ++ jest :: match a cord
413 |= daf/@t
414 |= tub/nail
415 =+ fad=daf
416 |- ^- (like @t)
417 ?: =(`@`0 daf)
418 [p=p.tub q=[~ u=[p=fad q=tub]]]
419 ?: |(?=($~ q.tub) !=((end 3 1 daf) i.q.tub))
420 (fail tub)
421 $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
422 ::
424Examples
425--------
427 > ((jest 'abc') [[1 1] "abc"])
428 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
429 > (scan "abc" (jest 'abc'))
430 'abc'
431 > (scan "abc" (jest 'acb'))
432 ! {1 2}
433 ! 'syntax-error'
434 ! exit
435 > ((jest 'john doe') [[1 1] "john smith"])
436 [p=[p=1 q=6] q=~]
437 > ((jest 'john doe') [[1 1] "john doe"])
438 [p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
442***
443### `++just`
445Match a char
447Match and consume a single character.
449Accepts
450-------
452`daf` is a `++char`
454Produces
455--------
457A `++rule`.
459Source
460------
462 ++ just :: XX redundant, jest
463 ~/ %just :: match a char
464 |= daf/char
465 ~/ %fun
466 |= tub/nail
467 ^- (like char)
468 ?~ q.tub
469 (fail tub)
470 ?. =(daf i.q.tub)
471 (fail tub)
472 (next tub)
473 ::
476Examples
477--------
479 > ((just 'a') [[1 1] "abc"])
480 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
481 > (scan "abc" (just 'a'))
482 ! {1 2}
483 ! 'syntax-error'
484 ! exit
485 > (scan "a" (just 'a'))
486 ~~a
487 > (scan "%" (just '%'))
488 ~~~25.
492***
493### `++knee`
495Recursive parsers
497Used for recursive parsers, which would otherwise be infinite when
498compiled.
500Accepts
501-------
503`gar` is a noun.
505`sef` is a gate that accepts a `++rule`
507Produces
508--------
510A `++rule`.
512Source
513------
515 ++ knee :: callbacks
516 |* {gar/* sef/_|.(*rule)}
517 |= tub/nail
518 ^- (like _gar)
519 ((sef) tub)
520 ::
522Examples
523--------
525 > |-(;~(plug prn ;~(pose $ (easy ~))))
526 ! rest-loop
527 ! exit
528 > |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
529 < 1.obo
530 [ c=c=tub=[p=[p=@ud q=@ud] q=""]
531 b
532 < 1.bes
533 [ c=tub=[p=[p=@ud q=@ud] q=""]
534 b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
535 a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
536 v=<414.fvk 101.jzo 1.ypj %164>
537 ]
538 >
539 a
540 ... 450 lines omitted ...
541 ]
542 >
543 > (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
544 [~~a "bcd"]
548***
549### `++mask`
551Match char
553Parser generator. Matches the next character if it is in a list of
554characters.
556Accepts
557-------
559`bud` is a list of `++char`
561Produces
562--------
564A `++rule`.
566Source
567------
569 ++ mask :: match char in set
570 ~/ %mask
571 |= bud/(list char)
572 ~/ %fun
573 |= tub/nail
574 ^- (like char)
575 ?~ q.tub
576 (fail tub)
577 ?. (lien bud |=(a/char =(i.q.tub a)))
578 (fail tub)
579 (next tub)
580 ::
582Examples
583--------
585 > (scan "a" (mask "cba"))
586 ~~a
587 > ((mask "abc") [[1 1] "abc"])
588 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
589 > ((mask "abc") [[1 1] "bbc"])
590 [p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
591 > ((mask "abc") [[1 1] "dbc"])
592 [p=[p=1 q=1] q=~]
596***
597### `++more`
599Parse list with delimiter
601Parser modifier: Parse a list of matches using a delimiter `++rule`.
603Accepts
604-------
606`bus` is a `++rule`.
608`fel` is a `++rule`.
610Produces
611--------
613A `++rule`.
615Source
616------
618 ++ more
619 |* {bus/rule fel/rule}
620 ;~(pose (most bus fel) (easy ~))
621 ::
623Examples
624--------
626 > (scan "" (more ace dem))
627 ~
628 > (scan "40 20" (more ace dem))
629 [q=40 ~[q=20]]
630 > (scan "40 20 60 1 5" (more ace dem))
631 [q=40 ~[q=20 q=60 q=1 q=5]]
635***
636### `++most`
638Parse list of at least one match
640Parser modifier: parse a `++list` of at least one match using a delimiter `++rule`.
642Accepts
643-------
645`bus` is a `++rule`.
647`fel` is a `++rule`.
649Produces
650--------
652A `++rule`.
654Source
655------
657 ++ most
658 |* {bus/rule fel/rule}
659 ;~(plug fel (star ;~(pfix bus fel)))
660 ::
662Examples
663--------
665 > (scan "40 20" (most ace dem))
666 [q=40 ~[q=20]]
667 > (scan "40 20 60 1 5" (most ace dem))
668 [q=40 ~[q=20 q=60 q=1 q=5]]
669 > (scan "" (most ace dem))
670 ! {1 1}
671 ! exit
675***
676### `++next`
678Consume char
680Consume any character, producing it as a result.
682Accepts
683-------
685`tub` is a `++nail`
687Produces
688--------
690An `++edge`.
692Source
693------
695 ++ next :: consume a char
696 |= tub/nail
697 ^- (like char)
698 ?~ q.tub
699 (fail tub)
700 =+ zac=(lust i.q.tub p.tub)
701 [zac [~ i.q.tub [zac t.q.tub]]]
702 ::
704Examples
705--------
707 > (next [[1 1] "ebc"])
708 [p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
709 > (next [[1 1] "john jumps jones"])
710 [p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
714***
716### `++plus`
718List of at least one match.
720Parser modifier: parse `++list` of at least one match.
722Accepts
723-------
725`fel` is a `++rule`.
727Produces
728--------
730A `++rule`.
732Source
733------
735 ++ plus |*(fel/rule ;~(plug fel (star fel)))
738Examples
739--------
741 > (scan ">>>>" (cook lent (plus gar)))
742 4
743 > (scan "- - " (plus ;~(pose ace hep)))
744 [~~- " - "]
745 > `tape`(scan "- - " (plus ;~(pose ace hep)))
746 "- - "
747 > `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
748 ['-' [' ' [' ' ['-' [' ' ~]]]]]
752***
753### `++sear`
755Conditional `++cook`
757Conditional `++cook`. Slams the result through a gate that produces
758a unit; if that unit is empty, fail.
760Accepts
761-------
763`tub` is a `++nail`.
764Produces
765--------
767A `++rule`.
769Source
770------
772 ++ sear :: conditional cook
773 |* {pyq/$-(* (unit)) sef/rule}
774 |= tub/nail
775 =+ vex=(sef tub)
776 ?~ q.vex
777 vex
778 =+ gey=(pyq p.u.q.vex)
779 ?~ gey
780 [p=p.vex q=~]
781 [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
782 ::
785Examples
786--------
788 > ((sear |=(a/* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
789 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
790 > ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
791 [p=[p=1 q=2] q=~]
795***
796### `++shim`
798Char in range
800Match characters (`++char`) within a range.
802Accepts
803-------
805`les` is an atom.
807`mos` is an atom.
809Produces
810--------
812A `++rule`.
814Source
815------
817 ++ shim :: match char in range
818 ~/ %shim
819 |= {les/@ mos/@}
820 ~/ %fun
821 |= tub/nail
822 ^- (like char)
823 ?~ q.tub
824 (fail tub)
825 ?. ?&((gte i.q.tub les) (lte i.q.tub mos))
826 (fail tub)
827 (next tub)
828 ::
830Examples
831--------
833 > ((shim 'a' 'z') [[1 1] "abc"])
834 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
835 > ((shim 'a' 'Z') [[1 1] "abc"])
836 [p=[p=1 q=1] q=~]
837 > ((shim 'a' 'Z') [[1 1] "Abc"])
838 [p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
842***
843### `++slug`
845Use gate to parse delimited list
847Parser modifier: By composing with a gate, parse a delimited `++list` of
848matches.
850Accepts
851-------
853`bus` is a `++rule`.
855`fel` is a `++rule`.
857Produces
858--------
860A `++rule`.
862Source
863------
865 ++ slug
866 |* raq/_|*({a/* b/*} [a b])
867 |* {bus/rule fel/rule}
868 ;~((comp raq) fel (stir +<+.raq raq ;~(pfix bus fel)))
869 ::
872Examples
873--------
875 > (scan "20+5+110" ((slug add) lus dem))
876 135
877 > `@t`(scan "a b c" ((slug |=(a/[@ @t] (cat 3 a))) ace alp))
878 'abc'
882***
883### `++stag`
885Add label
887Add a label to an edge parsed by a rule.
889Accepts
890-------
892`gob` is a noun.
894`sef` is a rule.
896Produces
897--------
899A `++rule`.
901Source
902------
904 ++ stag :: add a label
905 ~/ %stag
906 |* {gob/* sef/rule}
907 ~/ %fun
908 |= tub/nail
909 =+ vex=(sef tub)
910 ?~ q.vex
911 vex
912 [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
913 ::
915Examples
916--------
918 > ((stag %foo (just 'a')) [[1 1] "abc"])
919 [p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
920 > ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
921 [p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
922 > ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
923 [p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
927***
928### `++star`
930List of matches
932Parser modifier: parse `++list` of matches.
934Accepts
935-------
937`fel` is a `++rule`.
939Produces
940--------
942 ++ star :: 0 or more times
943 |* fel/rule
944 (stir `(list _(wonk *fel))`~ |*({a/* b/*} [a b]) fel)
946Examples
947--------
949 > (scan "aaaaa" (just 'a'))
950 ! {1 2}
951 ! 'syntax-error'
952 ! exit
953 > (scan "aaaaa" (star (just 'a')))
954 "aaaaa"
955 > (scan "abcdef" (star (just 'a')))
956 ! {1 2}
957 ! 'syntax-error'
958 ! exit
959 > (scan "abcabc" (star (jest 'abc')))
960 <|abc abc|>
961 > (scan "john smith" (star (shim 0 200)))
962 "john smith"
966***
967### `++stet`
969Add faces
971Add faces `[p q]` to range-parser pairs in a list.
973Accepts
974-------
976`leh` is a list of range-parsers.
978Produces
979--------
983Source
984------
986 ++ stet
987 |* leh/(list {?(@ {@ @}) rule})
988 |-
989 ?~ leh
990 ~
991 [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
992 ::
994Examples
995--------
997 > (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
998 [[1 10] (cold %foo (just 'a'))]~]))
999 ~[
1000 [p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1001 [p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1002 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1003 [p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1005 > [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
1006 [ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
1007 [[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
1010 > (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
1011 ~[
1012 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1013 [p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1018***
1019### `++stew`
1021Switch by first
1023 ++ stew :: switch by first char
1024 ~/ %stew
1025 |* leh/(list {p/?(@ {@ @}) q/rule}) :: char+range keys
1026 =+ ^= wor :: range complete lth
1027 |= {ort/?(@ {@ @}) wan/?(@ {@ @})}
1028 ?@ ort
1029 ?@(wan (lth ort wan) (lth ort -.wan))
1030 ?@(wan (lth +.ort wan) (lth +.ort -.wan))
1031 =+ ^= hel :: build parser map
1032 =+ hel=`(tree _?>(?=(^ leh) i.leh))`~
1033 |- ^+ hel
1034 ?~ leh
1036 =+ yal=$(leh t.leh)
1037 |- ^+ hel
1038 ?~ yal
1039 [i.leh ~ ~]
1040 ?: (wor p.i.leh p.n.yal)
1041 =+ nuc=$(yal l.yal)
1042 ?> ?=(^ nuc)
1043 ?: (vor p.n.yal p.n.nuc)
1044 [n.yal nuc r.yal]
1045 [n.nuc l.nuc [n.yal r.nuc r.yal]]
1046 =+ nuc=$(yal r.yal)
1047 ?> ?=(^ nuc)
1048 ?: (vor p.n.yal p.n.nuc)
1049 [n.yal l.yal nuc]
1050 [n.nuc [n.yal l.yal l.nuc] r.nuc]
1051 ~% %fun ..^$ ~
1052 |= tub/nail
1053 ?~ q.tub
1054 (fail tub)
1055 |-
1056 ?~ hel
1057 (fail tub)
1058 ?: ?@ p.n.hel
1059 =(p.n.hel i.q.tub)
1060 ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
1061 :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
1062 (q.n.hel tub)
1063 ?: (wor i.q.tub p.n.hel)
1064 $(hel l.hel)
1065 $(hel r.hel)
1066 ::
1070Parser generator. From an associative `++list` of characters or character
1071ranges to `++rule`s, construct a `++map`, and parse `++tape`s only
1072with `++rules` associated with a range that the `++tape`'s first character falls in.
1076***
1077### `++stir`
1079Parse repeatedly
1081Parse with `++rule` as many times as possible, and fold over results with a
1082binary gate.
1084Accepts
1085-------
1087`rud` is a noun.
1089`raq` is a gate that takes two nouns and produces a cell.
1091`fel` is a rule.
1093Produces
1094--------
1096A rule.
1098Source
1099------
1101 ++ stun :: parse several times
1102 |* {lig/{@ @} fel/rule}
1103 |= tub/nail
1104 ^- (like (list _(wonk (fel))))
1105 ?: =(0 +.lig)
1106 [p.tub [~ ~ tub]]
1107 =+ vex=(fel tub)
1108 ?~ q.vex
1109 ?: =(0 -.lig)
1110 [p.vex [~ ~ tub]]
1111 vex
1112 =+ ^= wag %= $
1113 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1114 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1115 tub q.u.q.vex
1116 ==
1117 ?~ q.wag
1118 wag
1119 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1122Examples
1123--------
1125 > (scan "abc" (stir *@ add prn))
1126 294
1127 > (roll "abc" add)
1128 b=294
1132***
1133### `++stun`
1135Parse several times
1137Parse bounded number of times.
1139Accepts
1140-------
1142`[les=@ mos=@]` is a cell of atoms indicating the bounds.
1144`fel` is a `++rule`.
1146Produces
1147--------
1149A `++rule`.
1151Source
1152------
1154 ++ stun :: parse several times
1155 |* {lig/{@ @} fel/rule}
1156 |= tub/nail
1157 ^- (like (list _(wonk (fel))))
1158 ?: =(0 +.lig)
1159 [p.tub [~ ~ tub]]
1160 =+ vex=(fel tub)
1161 ?~ q.vex
1162 ?: =(0 -.lig)
1163 [p.vex [~ ~ tub]]
1164 vex
1165 =+ ^= wag %= $
1166 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1167 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1168 tub q.u.q.vex
1169 ==
1170 ?~ q.wag
1171 wag
1172 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1174Examples
1175--------
1177 > ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
1178 [p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
1179 > ((stun [5 10] prn) [1 1] "aquickbro")
1180 [p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
1181 > ((stun [5 10] prn) [1 1] "aqui")
1182 [p=[p=1 q=5] q=~]
1184***