on 140ac0e help sign in
1179 lines 21 kB history raw
1# 4f: parsing (rule builders)
2### `++bass`
4Parser modifier: LSB
5ordered `++list` as atom of a `++base`.
7Accepts
8-------
10`wuc` is an atom.
12`tyd` is a `++rule`.
14Produces
15--------
17A `++rule`.
19Source
20------
22 ++ bass
23 |* {wuc/@ tyd/rule}
24 %+ cook
25 |= waq/(list @)
26 %+ roll
27 waq
28 =|({p/@ q/@} |.((add p (mul wuc q))))
29 tyd
30 ::
33Examples
34--------
36 > (scan "123" (bass 10 (star dit)))
37 q=123
38 > (scan "123" (bass 8 (star dit)))
39 q=83
40 > `@ub`(scan "123" (bass 8 (star dit)))
41 0b101.0011
45***
47### `++boss`
49Parser modifier: LSB
51Ordered `++list` as atom of a `++base`.
53Accepts
54-------
56`wuc` is an atom.
58`tyd` is a `++rule`.
60Produces
61--------
63A `++rule`.
65Source
66------
68 ++ boss
69 |* {wuc/@ tyd/rule}
70 %+ cook
71 |= waq/(list @)
72 %+ reel
73 waq
74 =|({p/@ q/@} |.((add p (mul wuc q))))
75 tyd
76 ::
78Examples
79--------
81 > (scan "123" (boss 10 (star dit)))
82 q=321
83 > `@t`(scan "bam" (boss 256 (star alp)))
84 'bam'
85 > `@ux`(scan "bam" (boss 256 (star alp)))
86 0x6d.6162
89***
90### `++cold`
92Replace with constant
94Parser modifier. Accepts a `++rule` `sef` and produces a parser that
95produces a constant `cus`, assuming `sef` is successful.
97Accepts
98-------
100`cus` is a constant noun.
102`sef` is a `++rule`.
104Produces
105--------
107An `++edge`.
109Source
110------
112 ++ cold :: replace w+ constant
113 ~/ %cold
114 |* {cus/* sef/rule}
115 ~/ %fun
116 |= tub/nail
117 =+ vex=(sef tub)
118 ?~ q.vex
119 vex
120 [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
122Examples
123--------
125 > ((cold %foo (just 'a')) [[1 1] "abc"])
126 [p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
127 > ((cold %foo (just 'a')) [[1 1] "bc"])
128 [p=[p=1 q=1] q=~]
132***
133### `++cook`
135Apply gate
137Parser modifier. Produces a parser that takes a (successful) result of a
138`++rule` `sef` and slams it through `poq`.
140Accepts
141-------
143`poq` is a gate.
145`sef` is a `++rule`.
147Produces
148--------
150An `++rule`.
152Source
153------
155 ++ cook :: apply gate
156 ~/ %cook
157 |* {poq/$-(* *) sef/rule}
158 ~/ %fun
159 |= tub/nail
160 =+ vex=(sef tub)
161 ?~ q.vex
162 vex
163 [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
164 ::
166Examples
167--------
169 > ((cook ,@ud (just 'a')) [[1 1] "abc"])
170 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
171 > ((cook ,@tas (just 'a')) [[1 1] "abc"])
172 [p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
173 > ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
174 [p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
175 > ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
176 [p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
180***
181### `++easy`
183Always parse
185Parser generator. Produces a parser that succeeds with given noun `huf`
186without consuming any text.
188Accepts
189-------
191`huf` is a noun.
193Produces
194--------
196A `++rule`.
198Source
199------
201 ++ easy :: always parse
202 ~/ %easy
203 |* huf=*
204 ~/ %fun
205 |= tub=nail
206 ^- (like ,_huf)
207 [p=p.tub q=[~ u=[p=huf q=tub]]]
208 ::
210Examples
211--------
213 > ((easy %foo) [[1 1] "abc"])
214 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
215 > ((easy %foo) [[1 1] "bc"])
216 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
217 > ((easy 'a') [[1 1] "bc"])
218 [p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
222***
223### `++full`
225Parse to end
227Parser modifier. Accepts a `++rule` `sef`, and produces a parser that succeeds only
228when the of `tub` is fully consumed using `sef`.
230Accepts
231-------
233`sef` is a `++rule`.
235Produces
236--------
238A `++rule`.
240Source
241------
243 ++ full :: parse to end
244 |* sef=_rule
245 |= tub=nail
246 =+ vex=(sef tub)
247 ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
248 ::
250Examples
251--------
253 > ((full (just 'a')) [[1 1] "ab"])
254 [p=[p=1 q=2] q=~]
255 > ((full (jest 'ab')) [[1 1] "ab"])
256 [p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
257 > ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
258 [p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
262***
263### `++funk`
265Add to tape
267Parser modifier: prepend text to `++tape` before applying parser.
269Accepts
270-------
272`pre` is a `++tape`
274`sef` is a `++rule`
276Produces
277--------
279A `++rule`.
281Source
282------
284 ++ funk :: add to tape first
285 |* {pre/tape sef/rule}
286 |= tub/nail
287 (sef p.tub (weld pre q.tub))
289Examples
290--------
292 > ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
293 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
294 > ((funk "parse" (just 'a')) [[1 4] " me"])
295 [p=[p=1 q=4] q=~]
299***
300### `++here`
302Place-based apply
304Parser modifier. Similar to `++cook` in that it produces a parser that takes a
305(successful) result of `sef` and slams it through `hez`. `hez` accepts a
306`++pint` `a` and a noun `b`, which is what the parser parsed.
308Accepts
309-------
311`hez` is a gate.
313`sef` is a `++rule`
315Produces
316--------
318A `++rule`.
320Source
321------
323 ++ here :: place-based apply
324 ~/ %here
325 |* {hez/_|=({a/pint b/*} [a b]) sef/rule}
326 ~/ %fun
327 |= tub/nail
328 =+ vex=(sef tub)
329 ?~ q.vex
330 vex
331 [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
332 ::
334Examples
335--------
337 > (scan "abc" (star alf))
338 "abc"
339 > (scan "abc" (here |*(^ +<) (star alf)))
340 [[[p=1 q=1] p=1 q=4] "abc"]
341 > (scan "abc" (star (here |*(^ +<) alf)))
342 ~[[[[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]]
346***
347### `++ifix`
349Infix
351Parser modifier: surround with pair of `++rule`s, the output of which is
352discarded.
354Accepts
355-------
357`fel` is a pair of `++rule`s.
359`hof` is a `++rule`.
361Produces
362--------
364A `++rule`.
366Source
367------
369 ++ ifix
370 |* {fel/{rule rule} hof/rule}
371 ~! +<
372 ~! +<:-.fel
373 ~! +<:+.fel
374 ;~(pfix -.fel ;~(sfix hof +.fel))
375 ::
377Examples
378--------
380 > (scan "-40-" (ifix [hep hep] dem))
381 q=40
382 > (scan "4my4" (ifix [dit dit] (star alf)))
383 "my"
387***
388### `++jest`
390Match a cord
392Match and consume a cord.
394Accepts
395-------
397`daf` is a `@t`.
399Produces
400--------
402An `++edge`.
404Source
405------
407 ++ jest :: match a cord
408 |= daf/@t
409 |= tub/nail
410 =+ fad=daf
411 |- ^- (like @t)
412 ?: =(`@`0 daf)
413 [p=p.tub q=[~ u=[p=fad q=tub]]]
414 ?: |(?=($~ q.tub) !=((end 3 1 daf) i.q.tub))
415 (fail tub)
416 $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
417 ::
419Examples
420--------
422 > ((jest 'abc') [[1 1] "abc"])
423 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
424 > (scan "abc" (jest 'abc'))
425 'abc'
426 > (scan "abc" (jest 'acb'))
427 ! {1 2}
428 ! 'syntax-error'
429 ! exit
430 > ((jest 'john doe') [[1 1] "john smith"])
431 [p=[p=1 q=6] q=~]
432 > ((jest 'john doe') [[1 1] "john doe"])
433 [p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
437***
438### `++just`
440Match a char
442Match and consume a single character.
444Accepts
445-------
447`daf` is a `++char`
449Produces
450--------
452A `++rule`.
454Source
455------
457 ++ just :: XX redundant, jest
458 ~/ %just :: match a char
459 |= daf/char
460 ~/ %fun
461 |= tub/nail
462 ^- (like char)
463 ?~ q.tub
464 (fail tub)
465 ?. =(daf i.q.tub)
466 (fail tub)
467 (next tub)
468 ::
471Examples
472--------
474 > ((just 'a') [[1 1] "abc"])
475 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
476 > (scan "abc" (just 'a'))
477 ! {1 2}
478 ! 'syntax-error'
479 ! exit
480 > (scan "a" (just 'a'))
481 ~~a
482 > (scan "%" (just '%'))
483 ~~~25.
487***
488### `++knee`
490Recursive parsers
492Used for recursive parsers, which would otherwise be infinite when
493compiled.
495Accepts
496-------
498`gar` is a noun.
500`sef` is a gate that accepts a `++rule`
502Produces
503--------
505A `++rule`.
507Source
508------
510 ++ knee :: callbacks
511 |* {gar/* sef/_|.(*rule)}
512 |= tub/nail
513 ^- (like _gar)
514 ((sef) tub)
515 ::
517Examples
518--------
520 > |-(;~(plug prn ;~(pose $ (easy ~))))
521 ! rest-loop
522 ! exit
523 > |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
524 < 1.obo
525 [ c=c=tub=[p=[p=@ud q=@ud] q=""]
526 b
527 < 1.bes
528 [ c=tub=[p=[p=@ud q=@ud] q=""]
529 b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
530 a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
531 v=<414.fvk 101.jzo 1.ypj %164>
532 ]
533 >
534 a
535 ... 450 lines omitted ...
536 ]
537 >
538 > (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
539 [~~a "bcd"]
543***
544### `++mask`
546Match char
548Parser generator. Matches the next character if it is in a list of
549characters.
551Accepts
552-------
554`bud` is a list of `++char`
556Produces
557--------
559A `++rule`.
561Source
562------
564 ++ mask :: match char in set
565 ~/ %mask
566 |= bud/(list char)
567 ~/ %fun
568 |= tub/nail
569 ^- (like char)
570 ?~ q.tub
571 (fail tub)
572 ?. (lien bud |=(a/char =(i.q.tub a)))
573 (fail tub)
574 (next tub)
575 ::
577Examples
578--------
580 > (scan "a" (mask "cba"))
581 ~~a
582 > ((mask "abc") [[1 1] "abc"])
583 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
584 > ((mask "abc") [[1 1] "bbc"])
585 [p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
586 > ((mask "abc") [[1 1] "dbc"])
587 [p=[p=1 q=1] q=~]
591***
592### `++more`
594Parse list with delimiter
596Parser modifier: Parse a list of matches using a delimiter `++rule`.
598Accepts
599-------
601`bus` is a `++rule`.
603`fel` is a `++rule`.
605Produces
606--------
608A `++rule`.
610Source
611------
613 ++ more
614 |* {bus/rule fel/rule}
615 ;~(pose (most bus fel) (easy ~))
616 ::
618Examples
619--------
621 > (scan "" (more ace dem))
622 ~
623 > (scan "40 20" (more ace dem))
624 [q=40 ~[q=20]]
625 > (scan "40 20 60 1 5" (more ace dem))
626 [q=40 ~[q=20 q=60 q=1 q=5]]
630***
631### `++most`
633Parse list of at least one match
635Parser modifier: parse a `++list` of at least one match using a delimiter `++rule`.
637Accepts
638-------
640`bus` is a `++rule`.
642`fel` is a `++rule`.
644Produces
645--------
647A `++rule`.
649Source
650------
652 ++ most
653 |* {bus/rule fel/rule}
654 ;~(plug fel (star ;~(pfix bus fel)))
655 ::
657Examples
658--------
660 > (scan "40 20" (most ace dem))
661 [q=40 ~[q=20]]
662 > (scan "40 20 60 1 5" (most ace dem))
663 [q=40 ~[q=20 q=60 q=1 q=5]]
664 > (scan "" (most ace dem))
665 ! {1 1}
666 ! exit
670***
671### `++next`
673Consume char
675Consume any character, producing it as a result.
677Accepts
678-------
680`tub` is a `++nail`
682Produces
683--------
685An `++edge`.
687Source
688------
690 ++ next :: consume a char
691 |= tub/nail
692 ^- (like char)
693 ?~ q.tub
694 (fail tub)
695 =+ zac=(lust i.q.tub p.tub)
696 [zac [~ i.q.tub [zac t.q.tub]]]
697 ::
699Examples
700--------
702 > (next [[1 1] "ebc"])
703 [p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
704 > (next [[1 1] "john jumps jones"])
705 [p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
709***
711### `++plus`
713List of at least one match.
715Parser modifier: parse `++list` of at least one match.
717Accepts
718-------
720`fel` is a `++rule`.
722Produces
723--------
725A `++rule`.
727Source
728------
730 ++ plus |*(fel/rule ;~(plug fel (star fel)))
733Examples
734--------
736 > (scan ">>>>" (cook lent (plus gar)))
737 4
738 > (scan "- - " (plus ;~(pose ace hep)))
739 [~~- " - "]
740 > `tape`(scan "- - " (plus ;~(pose ace hep)))
741 "- - "
742 > `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
743 ['-' [' ' [' ' ['-' [' ' ~]]]]]
747***
748### `++sear`
750Conditional `++cook`
752Conditional `++cook`. Slams the result through a gate that produces
753a unit; if that unit is empty, fail.
755Accepts
756-------
758`tub` is a `++nail`.
759Produces
760--------
762A `++rule`.
764Source
765------
767 ++ sear :: conditional cook
768 |* {pyq/$-(* (unit)) sef/rule}
769 |= tub/nail
770 =+ vex=(sef tub)
771 ?~ q.vex
772 vex
773 =+ gey=(pyq p.u.q.vex)
774 ?~ gey
775 [p=p.vex q=~]
776 [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
777 ::
780Examples
781--------
783 > ((sear |=(a/* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
784 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
785 > ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
786 [p=[p=1 q=2] q=~]
790***
791### `++shim`
793Char in range
795Match characters (`++char`) within a range.
797Accepts
798-------
800`les` is an atom.
802`mos` is an atom.
804Produces
805--------
807A `++rule`.
809Source
810------
812 ++ shim :: match char in range
813 ~/ %shim
814 |= {les/@ mos/@}
815 ~/ %fun
816 |= tub/nail
817 ^- (like char)
818 ?~ q.tub
819 (fail tub)
820 ?. ?&((gte i.q.tub les) (lte i.q.tub mos))
821 (fail tub)
822 (next tub)
823 ::
825Examples
826--------
828 > ((shim 'a' 'z') [[1 1] "abc"])
829 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
830 > ((shim 'a' 'Z') [[1 1] "abc"])
831 [p=[p=1 q=1] q=~]
832 > ((shim 'a' 'Z') [[1 1] "Abc"])
833 [p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
837***
838### `++slug`
840Use gate to parse delimited list
842Parser modifier: By composing with a gate, parse a delimited `++list` of
843matches.
845Accepts
846-------
848`bus` is a `++rule`.
850`fel` is a `++rule`.
852Produces
853--------
855A `++rule`.
857Source
858------
860 ++ slug
861 |* raq/_|*({a/* b/*} [a b])
862 |* {bus/rule fel/rule}
863 ;~((comp raq) fel (stir +<+.raq raq ;~(pfix bus fel)))
864 ::
867Examples
868--------
870 > (scan "20+5+110" ((slug add) lus dem))
871 135
872 > `@t`(scan "a b c" ((slug |=(a/[@ @t] (cat 3 a))) ace alp))
873 'abc'
877***
878### `++stag`
880Add label
882Add a label to an edge parsed by a rule.
884Accepts
885-------
887`gob` is a noun.
889`sef` is a rule.
891Produces
892--------
894A `++rule`.
896Source
897------
899 ++ stag :: add a label
900 ~/ %stag
901 |* {gob/* sef/rule}
902 ~/ %fun
903 |= tub/nail
904 =+ vex=(sef tub)
905 ?~ q.vex
906 vex
907 [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
908 ::
910Examples
911--------
913 > ((stag %foo (just 'a')) [[1 1] "abc"])
914 [p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
915 > ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
916 [p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
917 > ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
918 [p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
922***
923### `++star`
925List of matches
927Parser modifier: parse `++list` of matches.
929Accepts
930-------
932`fel` is a `++rule`.
934Produces
935--------
937 ++ star :: 0 or more times
938 |* fel/rule
939 (stir `(list _(wonk *fel))`~ |*({a/* b/*} [a b]) fel)
941Examples
942--------
944 > (scan "aaaaa" (just 'a'))
945 ! {1 2}
946 ! 'syntax-error'
947 ! exit
948 > (scan "aaaaa" (star (just 'a')))
949 "aaaaa"
950 > (scan "abcdef" (star (just 'a')))
951 ! {1 2}
952 ! 'syntax-error'
953 ! exit
954 > (scan "abcabc" (star (jest 'abc')))
955 <|abc abc|>
956 > (scan "john smith" (star (shim 0 200)))
957 "john smith"
961***
962### `++stet`
964Add faces
966Add faces `[p q]` to range-parser pairs in a list.
968Accepts
969-------
971`leh` is a list of range-parsers.
973Produces
974--------
978Source
979------
981 ++ stet
982 |* leh/(list {?(@ {@ @}) rule})
983 |-
984 ?~ leh
985 ~
986 [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
987 ::
989Examples
990--------
992 > (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
993 [[1 10] (cold %foo (just 'a'))]~]))
994 ~[
995 [p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
996 [p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
997 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
998 [p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
999 ]
1000 > [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
1001 [ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
1002 [[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
1005 > (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
1006 ~[
1007 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1008 [p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1013***
1014### `++stew`
1016Switch by first
1018 ++ stew :: switch by first char
1019 ~/ %stew
1020 |* leh/(list {p/?(@ {@ @}) q/rule}) :: char+range keys
1021 =+ ^= wor :: range complete lth
1022 |= {ort/?(@ {@ @}) wan/?(@ {@ @})}
1023 ?@ ort
1024 ?@(wan (lth ort wan) (lth ort -.wan))
1025 ?@(wan (lth +.ort wan) (lth +.ort -.wan))
1026 =+ ^= hel :: build parser map
1027 =+ hel=`(tree _?>(?=(^ leh) i.leh))`~
1028 |- ^+ hel
1029 ?~ leh
1031 =+ yal=$(leh t.leh)
1032 |- ^+ hel
1033 ?~ yal
1034 [i.leh ~ ~]
1035 ?: (wor p.i.leh p.n.yal)
1036 =+ nuc=$(yal l.yal)
1037 ?> ?=(^ nuc)
1038 ?: (vor p.n.yal p.n.nuc)
1039 [n.yal nuc r.yal]
1040 [n.nuc l.nuc [n.yal r.nuc r.yal]]
1041 =+ nuc=$(yal r.yal)
1042 ?> ?=(^ nuc)
1043 ?: (vor p.n.yal p.n.nuc)
1044 [n.yal l.yal nuc]
1045 [n.nuc [n.yal l.yal l.nuc] r.nuc]
1046 ~% %fun ..^$ ~
1047 |= tub/nail
1048 ?~ q.tub
1049 (fail tub)
1050 |-
1051 ?~ hel
1052 (fail tub)
1053 ?: ?@ p.n.hel
1054 =(p.n.hel i.q.tub)
1055 ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
1056 :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
1057 (q.n.hel tub)
1058 ?: (wor i.q.tub p.n.hel)
1059 $(hel l.hel)
1060 $(hel r.hel)
1061 ::
1065Parser generator. From an associative `++list` of characters or character
1066ranges to `++rule`s, construct a `++map`, and parse `++tape`s only
1067with `++rules` associated with a range that the `++tape`'s first character falls in.
1071***
1072### `++stir`
1074Parse repeatedly
1076Parse with `++rule` as many times as possible, and fold over results with a
1077binary gate.
1079Accepts
1080-------
1082`rud` is a noun.
1084`raq` is a gate that takes two nouns and produces a cell.
1086`fel` is a rule.
1088Produces
1089--------
1091A rule.
1093Source
1094------
1096 ++ stun :: parse several times
1097 |* {lig/{@ @} fel/rule}
1098 |= tub/nail
1099 ^- (like (list _(wonk (fel))))
1100 ?: =(0 +.lig)
1101 [p.tub [~ ~ tub]]
1102 =+ vex=(fel tub)
1103 ?~ q.vex
1104 ?: =(0 -.lig)
1105 [p.vex [~ ~ tub]]
1106 vex
1107 =+ ^= wag %= $
1108 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1109 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1110 tub q.u.q.vex
1111 ==
1112 ?~ q.wag
1113 wag
1114 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1117Examples
1118--------
1120 > (scan "abc" (stir *@ add prn))
1121 294
1122 > (roll "abc" add)
1123 b=294
1127***
1128### `++stun`
1130Parse several times
1132Parse bounded number of times.
1134Accepts
1135-------
1137`[les=@ mos=@]` is a cell of atoms indicating the bounds.
1139`fel` is a `++rule`.
1141Produces
1142--------
1144A `++rule`.
1146Source
1147------
1149 ++ stun :: parse several times
1150 |* {lig/{@ @} fel/rule}
1151 |= tub/nail
1152 ^- (like (list _(wonk (fel))))
1153 ?: =(0 +.lig)
1154 [p.tub [~ ~ tub]]
1155 =+ vex=(fel tub)
1156 ?~ q.vex
1157 ?: =(0 -.lig)
1158 [p.vex [~ ~ tub]]
1159 vex
1160 =+ ^= wag %= $
1161 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1162 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1163 tub q.u.q.vex
1164 ==
1165 ?~ q.wag
1166 wag
1167 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1169Examples
1170--------
1172 > ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
1173 [p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
1174 > ((stun [5 10] prn) [1 1] "aquickbro")
1175 [p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
1176 > ((stun [5 10] prn) [1 1] "aqui")
1177 [p=[p=1 q=5] q=~]
1179***