1use thiserror::Error;
17
18use super::pest_grammar::*;
19
20use Lexeme as L;
21use Rule as R;
22
23#[derive(Debug, Error)]
24pub enum Error {
25 #[error("Pest error: {0}")]
26 Pest(#[from] pest::error::Error<Rule>),
27}
28
29#[derive(Clone, Copy, Debug)]
30pub struct FormIx {
31 pub parent: u32,
33 pub ix: u32,
35}
36
37impl FormIx {
38 fn root(ix: u32) -> Self {
39 Self { parent: 0, ix }
40 }
41 fn child(&self, ix: u32) -> Self {
42 Self {
43 parent: self.ix,
44 ix,
45 }
46 }
47}
48
49#[derive(Debug)]
50pub enum Lexeme<'a> {
51 Whitespace {
53 source: &'a str,
54 },
55 Comment {
57 source: &'a str,
63 },
64 Meta {
66 form_ix: FormIx,
69 data_ix: FormIx,
71 source: &'a str,
74 },
75 Discard {
76 form_ix: FormIx,
77 source: &'a str,
78 },
79 Quote {
80 form_ix: FormIx,
81 source: &'a str,
82 },
83 VarQuote {
84 form_ix: FormIx,
85 source: &'a str,
86 },
87 Synquote {
88 form_ix: FormIx,
89 source: &'a str,
90 },
91 Unquote {
92 form_ix: FormIx,
93 source: &'a str,
94 },
95 SplicingUnquote {
96 form_ix: FormIx,
97 source: &'a str,
98 },
99 Nil {
100 form_ix: FormIx,
101 source: &'a str,
102 },
103 Boolean {
104 form_ix: FormIx,
105 value: bool,
106 source: &'a str,
107 },
108 Numeric {
109 form_ix: FormIx,
110 class: NumberClass,
111 value: NumericValue<'a>,
112 source: &'a str,
113 },
114 Char {
115 form_ix: FormIx,
116 syntax: CharSyntax,
117 value: char,
118 source: &'a str,
119 },
120 String {
121 form_ix: FormIx,
122 value: Box<[StringFragment<'a>]>,
123 source: &'a str,
124 },
125 Regex {
126 form_ix: FormIx,
127 source: &'a str,
128 },
129 SymbolicValuePrefix {
130 form_ix: FormIx,
131 source: &'a str,
132 },
133 SymbolicValue {
134 form_ix: FormIx,
135 value: SymbolicValue<'a>,
136 source: &'a str,
137 },
138 Symbol {
139 form_ix: FormIx,
140 namespace: Option<&'a str>,
141 name: &'a str,
142 source: &'a str,
143 },
144 Tag {
145 form_ix: FormIx,
146 namespace: Option<&'a str>,
147 name: &'a str,
148 source: &'a str,
149 },
150 Keyword {
151 form_ix: FormIx,
152 alias: bool,
153 namespace: Option<&'a str>,
154 name: &'a str,
155 source: &'a str,
156 },
157 StartList {
158 form_ix: FormIx,
159 source: &'a str,
160 },
161 EndList {
162 form_ix: FormIx,
163 source: &'a str,
164 },
165 StartVector {
166 form_ix: FormIx,
167 source: &'a str,
168 },
169 EndVector {
170 form_ix: FormIx,
171 source: &'a str,
172 },
173 StartSet {
174 form_ix: FormIx,
175 source: &'a str,
176 },
177 EndSet {
178 form_ix: FormIx,
179 source: &'a str,
180 },
181 MapQualifier {
182 form_ix: FormIx,
183 source: &'a str,
184 },
185 StartMap {
186 form_ix: FormIx,
187 alias: bool,
188 namespace: Option<&'a str>,
189 source: &'a str,
190 },
191 EndMap {
192 form_ix: FormIx,
193 source: &'a str,
194 },
195 StartAnonymousFn {
196 form_ix: FormIx,
197 source: &'a str,
198 },
199 EndAnonymousFn {
200 form_ix: FormIx,
201 source: &'a str,
202 },
203 ReaderConditionalPrefix {
204 form_ix: FormIx,
205 source: &'a str,
206 },
207 StartReaderConditional {
208 form_ix: FormIx,
209 splicing: bool,
210 source: &'a str,
211 },
212 EndReaderConditional {
213 form_ix: FormIx,
214 source: &'a str,
215 },
216 TaggedLiteral {
217 form_ix: FormIx,
218 tag_ix: FormIx,
219 arg_ix: FormIx,
220 source: &'a str,
221 },
222 Residual(Pair<'a>),
223}
224
225#[derive(Clone, Copy, Debug)]
226pub enum CharSyntax {
227 Name,
228 Octal,
229 CodePoint,
230 Simple,
231}
232
233#[derive(Clone, Copy, Debug)]
234pub enum SymbolicValue<'a> {
235 PosInf,
236 NegInf,
237 NaN,
238 Other(&'a str),
239}
240
241#[derive(Clone, Copy, Debug)]
242pub enum NumericValue<'a> {
243 Int {
244 positive: bool,
245 radix: u32,
246 value: &'a str,
247 },
248 Float {
249 value: &'a str,
250 },
251 Fraction {
252 positive: bool,
253 numerator: &'a str,
254 denominator: &'a str,
255 },
256}
257
258#[derive(Clone, Copy, Debug)]
260pub enum NumberClass {
261 Long,
262 Double,
263 BigInt,
264 BigDecimal,
265 Ratio,
266}
267
268#[derive(Clone, Copy, Debug)]
269pub enum StringFragment<'a> {
270 Unescaped { value: &'a str },
271 Escaped { code: u32 },
272}
273
274type Lexemes<'a> = Vec<Lexeme<'a>>;
275
276#[allow(clippy::result_large_err)]
277pub fn lex(input: &str) -> Result<Lexemes, Error> {
278 let mut helper = Helper::default();
279 let mut pairs = Grammar::parse(R::top_level, input)?;
280 let Some(top_level_pair) = pairs.next() else {
281 panic!("at least one top-level");
282 };
283 if pairs.next().is_some() {
284 panic!("at most one top-level");
285 }
286 helper.top_level(top_level_pair);
287 Ok(helper.into_lexemes())
288}
289
290#[derive(Debug, Default)]
291struct Helper<'a> {
292 form_count: u32,
293 lexemes: Lexemes<'a>,
294}
295
296impl<'a> Helper<'a> {
297 fn push(&mut self, lexeme: Lexeme<'a>) {
298 self.lexemes.push(lexeme)
299 }
300
301 fn into_lexemes(mut self) -> Lexemes<'a> {
302 self.lexemes.shrink_to_fit();
303 self.lexemes
304 }
305
306 fn next_form_ix(&mut self, parent: Option<FormIx>) -> FormIx {
307 self.form_count += 1;
308 parent
309 .map(|p| p.child(self.form_count))
310 .unwrap_or_else(|| FormIx::root(self.form_count))
311 }
312
313 fn whitespace(&mut self, pair: Pair<'a>) {
314 self.push(L::Whitespace {
315 source: pair.as_str(),
316 });
317 }
318
319 fn comment(&mut self, pair: Pair<'a>) {
320 self.push(L::Comment {
321 source: pair.as_str(),
322 });
323 }
324
325 fn top_level(&mut self, parent: Pair<'a>) {
326 for child in parent.into_inner() {
327 match child.as_rule() {
328 R::COMMENT => self.comment(child),
329 R::WHITESPACE => self.whitespace(child),
330 R::form => {
331 let current = self.next_form_ix(None);
332 self.form(child, current);
333 }
334 R::EOI => (),
335 _ => self.push(L::Residual(child)),
336 }
337 }
338 }
339
340 fn form(&mut self, parent: Pair<'a>, current: FormIx) {
341 for child in parent.into_inner() {
342 match child.as_rule() {
343 R::COMMENT => self.comment(child),
344 R::WHITESPACE => self.whitespace(child),
345 R::quote_unquote_form => self.quote_unquote_form(child, current),
346 R::preform => self.preforms(child, current),
347 R::form => self.form(child, current),
348 R::expr => self.expr(child, current),
349 _ => self.push(L::Residual(child)),
350 }
351 }
352 }
353
354 fn quote_unquote_form(&mut self, parent: Pair<'a>, parent_ix: FormIx) {
355 let child_ix = self.next_form_ix(Some(parent_ix));
356 for child in parent.into_inner() {
357 match child.as_rule() {
358 R::COMMENT => self.comment(child),
359 R::WHITESPACE => self.whitespace(child),
360 R::quote_unquote_prefix => self.push(match child.as_str() {
361 "'" => L::Quote {
362 form_ix: parent_ix,
363 source: child.as_str(),
364 },
365 "#'" => L::VarQuote {
366 form_ix: parent_ix,
367 source: child.as_str(),
368 },
369 "`" => L::Synquote {
370 form_ix: parent_ix,
371 source: child.as_str(),
372 },
373 "~@" => L::SplicingUnquote {
374 form_ix: parent_ix,
375 source: child.as_str(),
376 },
377 "~" => L::Unquote {
378 form_ix: parent_ix,
379 source: child.as_str(),
380 },
381 _ => unreachable!("quote-unquote prefix case analysis"),
382 }),
383 R::form => self.form(child, child_ix),
384 _ => self.push(L::Residual(child)),
385 }
386 }
387 }
388
389 fn preforms(&mut self, parent: Pair<'a>, current: FormIx) {
390 for child in parent.into_inner() {
391 match child.as_rule() {
392 R::COMMENT => self.comment(child),
393 R::WHITESPACE => self.whitespace(child),
394 R::discarded_form => self.discarded_form(child),
395 R::meta_form => self.meta_form(child, current),
396 _ => self.push(L::Residual(child)),
397 }
398 }
399 }
400
401 fn discarded_form(&mut self, parent: Pair<'a>) {
402 let form_ix = self.next_form_ix(None);
403 for child in parent.into_inner() {
404 match child.as_rule() {
405 R::COMMENT => self.comment(child),
406 R::WHITESPACE => self.whitespace(child),
407 R::discard_prefix => self.push(L::Discard {
408 form_ix,
409 source: child.as_str(),
410 }),
411 R::preform => self.preforms(child, form_ix),
412 R::form => self.form(child, form_ix),
413 _ => self.push(L::Residual(child)),
414 }
415 }
416 }
417
418 fn meta_form(&mut self, parent: Pair<'a>, form_ix: FormIx) {
419 let data_ix = self.next_form_ix(None);
420 for child in parent.into_inner() {
421 match child.as_rule() {
422 R::COMMENT => self.comment(child),
423 R::WHITESPACE => self.whitespace(child),
424 R::meta_prefix => self.push(L::Meta {
425 form_ix,
426 data_ix,
427 source: child.as_str(),
428 }),
429 R::form => self.form(child, data_ix),
430 _ => self.push(L::Residual(child)),
431 }
432 }
433 }
434
435 fn expr(&mut self, parent: Pair<'a>, form_ix: FormIx) {
436 for child in parent.into_inner() {
437 match child.as_rule() {
438 R::COMMENT => self.comment(child),
439 R::WHITESPACE => self.whitespace(child),
440 R::nil => self.push(L::Nil {
441 form_ix,
442 source: child.as_str(),
443 }),
444 R::boolean => self.push(L::Boolean {
445 form_ix,
446 value: child.as_str() == "true",
447 source: child.as_str(),
448 }),
449 R::number => self.number(child, form_ix),
450 R::char => self.char(child, form_ix),
451 R::string => self.string(child, form_ix),
452 R::regex => self.regex(child, form_ix),
453 R::symbolic_value => self.symbolic_value(child, form_ix),
454 R::symbol => self.symbol(child, form_ix),
455 R::keyword => self.keyword(child, form_ix),
456 R::list => self.list(child, form_ix),
457 R::vector => self.vector(child, form_ix),
458 R::anonymous_fn => self.anonymous_fn(child, form_ix),
459 R::set => self.set(child, form_ix),
460 R::map => self.map(child, form_ix),
461 R::reader_conditional => self.reader_conditional(child, form_ix),
462 R::tagged_literal => self.tagged_literal(child, form_ix),
463 _ => self.push(L::Residual(child)),
464 }
465 }
466 }
467
468 fn char(&mut self, parent: Pair<'a>, form_ix: FormIx) {
469 let source = parent.as_str();
470 for child in parent.into_inner() {
471 match child.as_rule() {
472 R::char_name => self.push(L::Char {
473 form_ix,
474 syntax: CharSyntax::Name,
475 value: match child.as_str() {
476 "newline" => '\n',
477 "space" => ' ',
478 "tab" => '\t',
479 "formfeed" => '\u{0C}',
480 "backspace" => '\u{08}',
481 _ => unreachable!("char name case analysis"),
482 },
483 source,
484 }),
485 R::char_octal => self.push(L::Char {
486 form_ix,
487 syntax: CharSyntax::Octal,
488 value: char::from_u32(
489 u32::from_str_radix(child.as_str(), 8).unwrap(),
490 )
491 .unwrap(),
492 source,
493 }),
494 R::char_code_point => self.push(L::Char {
495 form_ix,
496 syntax: CharSyntax::CodePoint,
497 value: char::from_u32(
498 u32::from_str_radix(child.as_str(), 16).unwrap(),
499 )
500 .unwrap(),
501 source,
502 }),
503 _ => self.push(L::Residual(child)),
504 }
505 }
506 }
507
508 fn number(&mut self, parent: Pair<'a>, form_ix: FormIx) {
509 let mut positive = true;
510 let literal = parent.as_str();
511 for child in parent.into_inner() {
512 match child.as_rule() {
513 R::sign => positive = child.as_str() == "+",
514 R::unsigned_bigfloat => {
515 self.unsigned_floats(child, form_ix, literal, true)
516 }
517 R::unsigned_float => {
518 self.unsigned_floats(child, form_ix, literal, false)
519 }
520 R::unsigned_ratio => {
521 self.unsigned_ratio(child, form_ix, literal, positive)
522 }
523 R::unsigned_radix_int => {
524 self.unsigned_radix_int(child, form_ix, literal, positive)
525 }
526 R::unsigned_int => self.unsigned_int(child, form_ix, literal, positive),
527 _ => self.push(L::Residual(child)),
528 }
529 }
530 }
531
532 fn unsigned_floats(
533 &mut self,
534 _parent: Pair<'a>,
535 form_ix: FormIx,
536 literal: &'a str,
537 big: bool,
538 ) {
539 self.push(if big {
540 L::Numeric {
541 form_ix,
542 class: NumberClass::BigDecimal,
543 value: NumericValue::Float {
544 value: &literal[..literal.len() - 1],
545 },
546 source: literal,
547 }
548 } else {
549 L::Numeric {
550 form_ix,
551 class: NumberClass::Double,
552 value: NumericValue::Float { value: literal },
553 source: literal,
554 }
555 })
556 }
557
558 fn unsigned_ratio(
559 &mut self,
560 parent: Pair<'a>,
561
562 form_ix: FormIx,
563 literal: &'a str,
564 positive: bool,
565 ) {
566 let mut numerator = None;
567 let mut denominator = None;
568 for child in parent.into_inner() {
569 match child.as_rule() {
570 R::numerator => numerator = Some(child.as_str()),
571 R::denominator => denominator = Some(child.as_str()),
572 _ => self.push(L::Residual(child)),
573 }
574 }
575 self.push(L::Numeric {
576 form_ix,
577 source: literal,
578 class: NumberClass::Ratio,
579 value: NumericValue::Fraction {
580 positive,
581 numerator: numerator.unwrap(),
582 denominator: denominator.unwrap(),
583 },
584 })
585 }
586 fn unsigned_radix_int(
587 &mut self,
588 parent: Pair<'a>,
589
590 form_ix: FormIx,
591 literal: &'a str,
592 positive: bool,
593 ) {
594 let mut radix = None;
595 for child in parent.into_inner() {
596 match child.as_rule() {
597 R::radix => radix = Some(child.as_str()),
598 R::radix_digits => self.push(L::Numeric {
599 form_ix,
600 source: literal,
601 class: NumberClass::Long,
602 value: NumericValue::Int {
603 positive,
604 radix: radix.unwrap().parse::<u32>().unwrap(),
605 value: child.as_str(),
606 },
607 }),
608 _ => self.push(L::Residual(child)),
609 }
610 }
611 }
612
613 fn unsigned_int(
614 &mut self,
615 parent: Pair<'a>,
616 form_ix: FormIx,
617 literal: &'a str,
618 positive: bool,
619 ) {
620 let mut class = NumberClass::Long;
621 let mut value = None;
622 for child in parent.into_inner() {
623 match child.as_rule() {
624 R::oct_digits => {
625 value = Some(NumericValue::Int {
626 positive,
627 radix: 8,
628 value: child.as_str(),
629 })
630 }
631 R::hex_digits => {
632 value = Some(NumericValue::Int {
633 positive,
634 radix: 16,
635 value: child.as_str(),
636 })
637 }
638 R::unsigned_dec => {
639 value = Some(NumericValue::Int {
640 positive,
641 radix: 10,
642 value: child.as_str(),
643 })
644 }
645 R::bigint_suffix => class = NumberClass::BigInt,
646 _ => self.push(L::Residual(child)),
647 }
648 }
649 self.push(L::Numeric {
650 form_ix,
651 source: literal,
652 class,
653 value: value.unwrap(),
654 })
655 }
656
657 fn string(&mut self, parent: Pair<'a>, form_ix: FormIx) {
658 let mut fragments = Vec::new();
659 let literal = parent.as_str();
660 for child in parent.into_inner() {
661 match child.as_rule() {
662 R::unescaped => fragments.push(StringFragment::Unescaped {
663 value: child.as_str(),
664 }),
665 R::esc_char => {
666 let value = &child.as_str()[1..];
667 let code = match value {
668 "b" => 0x08,
669 "t" => 0x09,
670 "n" => 0x0A,
671 "f" => 0x0C,
672 "r" => 0x0D,
673 "\"" => 0x22,
674 "\\" => 0x5C,
675 e => unreachable!("inexhaustive: {}", e),
676 };
677 fragments.push(StringFragment::Escaped { code })
678 }
679 R::esc_octet => {
680 let value = &child.as_str()[1..];
681 let code = u32::from_str_radix(value, 8).unwrap();
682 fragments.push(StringFragment::Escaped { code })
683 }
684 R::esc_code_point => {
685 let value = &child.as_str()[2..];
686 let code = u32::from_str_radix(value, 16).unwrap();
687 fragments.push(StringFragment::Escaped { code })
688 }
689 _ => self.push(L::Residual(child)),
690 }
691 }
692 fragments.shrink_to_fit();
693 self.push(L::String {
694 form_ix,
695 source: literal,
696 value: fragments.into_boxed_slice(),
697 });
698 }
699
700 fn regex(&mut self, parent: Pair<'a>, form_ix: FormIx) {
701 for child in parent.into_inner() {
702 match child.as_rule() {
703 R::regex_content => self.push(L::Regex {
704 form_ix,
705 source: child.as_str(),
706 }),
707 _ => self.push(L::Residual(child)),
708 }
709 }
710 }
711
712 fn symbolic_value(&mut self, parent: Pair<'a>, form_ix: FormIx) {
713 for child in parent.into_inner() {
714 match child.as_rule() {
715 R::COMMENT => self.comment(child),
716 R::WHITESPACE => self.whitespace(child),
717 R::symbolic_value_prefix => self.push(L::SymbolicValuePrefix {
718 form_ix,
719 source: child.as_str(),
720 }),
721 R::unqualified_symbol => self.push(L::SymbolicValue {
722 form_ix,
723 value: match child.as_str() {
724 "Inf" => SymbolicValue::PosInf,
725 "-Inf" => SymbolicValue::NegInf,
726 "NaN" => SymbolicValue::NaN,
727 _ => SymbolicValue::Other(child.as_str()),
728 },
729 source: child.as_str(),
730 }),
731 _ => self.push(L::Residual(child)),
732 }
733 }
734 }
735
736 fn symbol(&mut self, parent: Pair<'a>, form_ix: FormIx) {
737 let source = parent.as_str();
738 let mut namespace = None;
739 for child in parent.into_inner() {
740 match child.as_rule() {
741 R::namespace => namespace = Some(child.as_str()),
742 R::qualified_symbol | R::unqualified_symbol => self.push(L::Symbol {
743 form_ix,
744 namespace,
745 name: child.as_str(),
746 source,
747 }),
748 _ => self.push(L::Residual(child)),
749 }
750 }
751 }
752
753 fn tag(&mut self, parent: Pair<'a>, form_ix: FormIx) {
754 let source = parent.as_str();
755 let mut namespace = None;
756 for child in parent.into_inner() {
757 match child.as_rule() {
758 R::namespace => namespace = Some(child.as_str()),
759 R::qualified_symbol | R::unqualified_symbol => self.push(L::Tag {
760 form_ix,
761 namespace,
762 name: child.as_str(),
763 source,
764 }),
765 _ => self.push(L::Residual(child)),
766 }
767 }
768 }
769
770 fn keyword(&mut self, parent: Pair<'a>, form_ix: FormIx) {
771 let source = parent.as_str();
772 let mut namespace = None;
773 let mut alias = false;
774 for child in parent.into_inner() {
775 match child.as_rule() {
776 R::keyword_prefix => alias = child.as_str() == "::",
777 R::namespace => namespace = Some(child.as_str()),
778 R::qualified_symbol | R::unqualified_keyword => self.push(L::Keyword {
779 form_ix,
780 alias,
781 namespace,
782 name: child.as_str(),
783 source,
784 }),
785 _ => self.push(L::Residual(child)),
786 }
787 }
788 }
789
790 fn list(&mut self, parent: Pair<'a>, parent_ix: FormIx) {
791 let source = parent.as_str();
792 self.body(
793 parent,
794 parent_ix,
795 L::StartList {
796 form_ix: parent_ix,
797 source: &source[..1],
798 },
799 L::EndList {
800 form_ix: parent_ix,
801 source: &source[source.len() - 1..],
802 },
803 );
804 }
805
806 fn vector(&mut self, parent: Pair<'a>, parent_ix: FormIx) {
807 let source = parent.as_str();
808 self.body(
809 parent,
810 parent_ix,
811 L::StartVector {
812 form_ix: parent_ix,
813 source: &source[..1],
814 },
815 L::EndVector {
816 form_ix: parent_ix,
817 source: &source[source.len() - 1..],
818 },
819 );
820 }
821
822 fn anonymous_fn(&mut self, parent: Pair<'a>, parent_ix: FormIx) {
823 let source = parent.as_str();
824 self.body(
825 parent,
826 parent_ix,
827 L::StartAnonymousFn {
828 form_ix: parent_ix,
829 source: &source[..2],
830 },
831 L::EndAnonymousFn {
832 form_ix: parent_ix,
833 source: &source[source.len() - 1..],
834 },
835 );
836 }
837
838 fn set(&mut self, parent: Pair<'a>, parent_ix: FormIx) {
839 let source = parent.as_str();
840 self.body(
841 parent,
842 parent_ix,
843 L::StartSet {
844 form_ix: parent_ix,
845 source: &source[..2],
846 },
847 L::EndSet {
848 form_ix: parent_ix,
849 source: &source[source.len() - 1..],
850 },
851 );
852 }
853
854 fn map(&mut self, parent: Pair<'a>, form_ix: FormIx) {
855 let mut alias = false;
856 let mut namespace = None;
857 for child in parent.into_inner() {
858 match child.as_rule() {
859 R::COMMENT => self.comment(child),
860 R::WHITESPACE => self.whitespace(child),
861 R::map_qualifier => {
862 self.push(L::MapQualifier {
863 form_ix,
864 source: child.as_str(),
865 });
866 for child2 in child.into_inner() {
867 match child2.as_rule() {
868 R::map_qualifier_prefix => alias = child2.as_str() == "#::",
869 R::namespace => namespace = Some(child2.as_str()),
870 _ => self.push(L::Residual(child2)),
871 }
872 }
873 }
874 R::unqualified_map => {
875 let source = child.as_str();
876 self.body(
877 child,
878 form_ix,
879 L::StartMap {
880 form_ix,
881 alias,
882 namespace,
883 source: &source[..1],
884 },
885 L::EndMap {
886 form_ix,
887 source: &source[source.len() - 1..],
888 },
889 )
890 }
891 R::discarded_form => self.discarded_form(child),
892 _ => self.push(L::Residual(child)),
893 }
894 }
895 }
896
897 fn reader_conditional(&mut self, parent: Pair<'a>, form_ix: FormIx) {
898 let mut splicing = false;
899 for child in parent.into_inner() {
900 match child.as_rule() {
901 R::COMMENT => self.comment(child),
902 R::WHITESPACE => self.whitespace(child),
903 R::reader_conditional_prefix => splicing = child.as_str() == "#?@",
904 R::reader_conditional_body => {
905 let source = child.as_str();
906 self.body(
907 child,
908 form_ix,
909 L::StartReaderConditional {
910 form_ix,
911 splicing,
912 source: &source[1..],
913 },
914 L::EndReaderConditional {
915 form_ix,
916 source: &source[source.len() - 1..],
917 },
918 )
919 }
920 R::discarded_form => self.discarded_form(child),
921 _ => self.push(L::Residual(child)),
922 }
923 }
924 }
925
926 fn body(
927 &mut self,
928 parent: Pair<'a>,
929 parent_ix: FormIx,
930 start_lexeme: Lexeme<'a>,
931 end_lexeme: Lexeme<'a>,
932 ) {
933 self.push(start_lexeme);
934 for child in parent.into_inner() {
935 match child.as_rule() {
936 R::COMMENT => self.comment(child),
937 R::WHITESPACE => self.whitespace(child),
938 R::form => {
939 let child_ix = self.next_form_ix(Some(parent_ix));
940 self.form(child, child_ix)
941 }
942 R::discarded_form => self.discarded_form(child),
943 _ => self.push(L::Residual(child)),
944 }
945 }
946 self.push(end_lexeme);
947 }
948
949 fn tagged_literal(&mut self, parent: Pair<'a>, form_ix: FormIx) {
950 let tag_ix = self.next_form_ix(Some(form_ix));
951 let arg_ix = self.next_form_ix(Some(form_ix));
952 self.push(L::TaggedLiteral {
953 form_ix,
954 tag_ix,
955 arg_ix,
956 source: &parent.as_str()[..1],
960 });
961 for child in parent.into_inner() {
962 match child.as_rule() {
963 R::COMMENT => self.comment(child),
964 R::WHITESPACE => self.whitespace(child),
965 R::tagged_literal_tag => {
966 for child2 in child.into_inner() {
967 match child2.as_rule() {
968 R::COMMENT => self.comment(child2),
969 R::WHITESPACE => self.whitespace(child2),
970 R::preform => self.preforms(child2, tag_ix),
971 R::symbol => self.tag(child2, tag_ix),
972 _ => self.push(L::Residual(child2)),
973 }
974 }
975 }
976 R::form => self.form(child, arg_ix),
977 _ => self.push(L::Residual(child)),
978 }
979 }
980 }
981}