1pub use grammar::ParseNodeShape;
2
3use indexing::container_traits::{Contiguous, Trustworthy};
4use indexing::{self, scope, Container};
5use std::cmp::{Ordering, Reverse};
6use std::collections::{BTreeSet, BinaryHeap, HashMap, VecDeque};
7use std::fmt;
8use std::hash::{Hash, Hasher};
9use std::io::{self, Write};
10use std::ops::{self, Deref, RangeInclusive};
11use std::str;
12
13#[derive(Copy, Clone, PartialEq, Eq, Debug)]
14pub struct Range<'i>(pub indexing::Range<'i>);
15
16impl<'i> Deref for Range<'i> {
17 type Target = indexing::Range<'i>;
18 fn deref(&self) -> &Self::Target {
19 &self.0
20 }
21}
22
23impl<'i> PartialOrd for Range<'i> {
24 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
25 (self.start(), self.end()).partial_cmp(&(other.start(), other.end()))
26 }
27}
28
29impl<'i> Ord for Range<'i> {
30 fn cmp(&self, other: &Self) -> Ordering {
31 (self.start(), self.end()).cmp(&(other.start(), other.end()))
32 }
33}
34
35impl<'i> Hash for Range<'i> {
36 fn hash<H: Hasher>(&self, state: &mut H) {
37 (self.start(), self.end()).hash(state);
38 }
39}
40
41impl<'i> Range<'i> {
42 pub fn subtract_suffix(self, other: Self) -> Self {
43 assert_eq!(self.end(), other.end());
44 Range(self.split_at(other.start() - self.start()).0)
45 }
46}
47
48#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
49pub struct LineColumn {
50 pub line: usize,
51 pub column: usize,
52}
53
54impl fmt::Debug for LineColumn {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 write!(f, "{}:{}", 1 + self.line, 1 + self.column)
57 }
58}
59
60impl LineColumn {
61 fn count(prefix: &str) -> Self {
62 let (line, column) = prefix
63 .split("\n")
64 .enumerate()
65 .last()
66 .map_or((0, 0), |(i, s)| (i, s.chars().count()));
67 LineColumn { line, column }
68 }
69}
70
71#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
72pub struct LineColumnRange {
73 pub start: LineColumn,
74 pub end: LineColumn,
75}
76
77impl fmt::Debug for LineColumnRange {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 write!(f, "{:?}-{:?}", self.start, self.end)
80 }
81}
82
83pub struct Str(str);
84
85impl<'a> From<&'a str> for &'a Str {
86 fn from(s: &'a str) -> Self {
87 unsafe { &*(s as *const str as *const Str) }
88 }
89}
90
91unsafe impl Trustworthy for Str {
92 type Item = u8;
93 fn base_len(&self) -> usize {
94 self.0.len()
95 }
96}
97
98unsafe impl Contiguous for Str {
99 fn begin(&self) -> *const Self::Item {
100 self.0.as_ptr()
101 }
102 fn end(&self) -> *const Self::Item {
103 unsafe { self.begin().offset(self.0.len() as isize) }
104 }
105 fn as_slice(&self) -> &[Self::Item] {
106 self.0.as_bytes()
107 }
108}
109
110pub trait Input: Sized {
111 type Container: Trustworthy;
112 type Slice: ?Sized;
113 type SourceInfo: fmt::Debug;
114 fn to_container(self) -> Self::Container;
115 fn slice<'a, 'i>(
116 input: &'a Container<'i, Self::Container>,
117 range: Range<'i>,
118 ) -> &'a Self::Slice;
119 fn source_info<'i>(
120 input: &Container<'i, Self::Container>,
121 range: Range<'i>,
122 ) -> Self::SourceInfo;
123}
124
125impl<'a, T> Input for &'a [T] {
126 type Container = Self;
127 type Slice = [T];
128 type SourceInfo = ops::Range<usize>;
129 fn to_container(self) -> Self::Container {
130 self
131 }
132 fn slice<'b, 'i>(
133 input: &'b Container<'i, Self::Container>,
134 range: Range<'i>,
135 ) -> &'b Self::Slice {
136 &input[range.0]
137 }
138 fn source_info<'i>(_: &Container<'i, Self::Container>, range: Range<'i>) -> Self::SourceInfo {
139 range.as_range()
140 }
141}
142
143impl<'a> Input for &'a str {
144 type Container = &'a Str;
145 type Slice = str;
146 type SourceInfo = LineColumnRange;
147 fn to_container(self) -> Self::Container {
148 self.into()
149 }
150 fn slice<'b, 'i>(
151 input: &'b Container<'i, Self::Container>,
152 range: Range<'i>,
153 ) -> &'b Self::Slice {
154 unsafe { str::from_utf8_unchecked(&input[range.0]) }
155 }
156 fn source_info<'i>(
157 input: &Container<'i, Self::Container>,
158 range: Range<'i>,
159 ) -> Self::SourceInfo {
160 let prefix_range = Range(input.range().split_at(range.start()).0);
161 let start = LineColumn::count(Self::slice(input, prefix_range));
162 let mut end = LineColumn::count(Self::slice(input, range));
165 end.line += start.line;
166 if end.line == start.line {
167 end.column += start.column;
168 }
169 LineColumnRange { start, end }
170 }
171}
172
173pub trait InputMatch<Pat> {
174 fn match_left(&self, pat: Pat) -> Option<usize>;
175 fn match_right(&self, pat: Pat) -> Option<usize>;
176}
177
178impl<'a, T: PartialEq> InputMatch<&'a [T]> for [T] {
179 fn match_left(&self, pat: &[T]) -> Option<usize> {
180 if self.starts_with(pat) {
181 Some(pat.len())
182 } else {
183 None
184 }
185 }
186 fn match_right(&self, pat: &[T]) -> Option<usize> {
187 if self.ends_with(pat) {
188 Some(pat.len())
189 } else {
190 None
191 }
192 }
193}
194
195impl<T: PartialOrd> InputMatch<RangeInclusive<T>> for [T] {
196 fn match_left(&self, pat: RangeInclusive<T>) -> Option<usize> {
197 let x = self.first()?;
198 if pat.start() <= x && x <= pat.end() {
199 Some(1)
200 } else {
201 None
202 }
203 }
204 fn match_right(&self, pat: RangeInclusive<T>) -> Option<usize> {
205 let x = self.last()?;
206 if pat.start() <= x && x <= pat.end() {
207 Some(1)
208 } else {
209 None
210 }
211 }
212}
213
214impl<'a> InputMatch<&'a str> for str {
215 fn match_left(&self, pat: &str) -> Option<usize> {
216 if self.starts_with(pat) {
217 Some(pat.len())
218 } else {
219 None
220 }
221 }
222 fn match_right(&self, pat: &str) -> Option<usize> {
223 if self.ends_with(pat) {
224 Some(pat.len())
225 } else {
226 None
227 }
228 }
229}
230
231impl InputMatch<RangeInclusive<char>> for str {
232 fn match_left(&self, pat: RangeInclusive<char>) -> Option<usize> {
233 let c = self.chars().next()?;
234 if *pat.start() <= c && c <= *pat.end() {
235 Some(c.len_utf8())
236 } else {
237 None
238 }
239 }
240 fn match_right(&self, pat: RangeInclusive<char>) -> Option<usize> {
241 let c = self.chars().rev().next()?;
242 if *pat.start() <= c && c <= *pat.end() {
243 Some(c.len_utf8())
244 } else {
245 None
246 }
247 }
248}
249
250pub struct Parser<'i, P: ParseNodeKind, C: CodeLabel, I: Input> {
251 input: Container<'i, I::Container>,
252 pub threads: Threads<'i, C>,
253 pub gss: GraphStack<'i, C>,
254 pub memoizer: Memoizer<'i, C>,
255 pub sppf: ParseForest<'i, P>,
256}
257
258impl<'i, P: ParseNodeKind, C: CodeLabel, I: Input> Parser<'i, P, C, I> {
259 pub fn with<R>(input: I, f: impl for<'i2> FnOnce(Parser<'i2, P, C, I>, Range<'i2>) -> R) -> R {
260 scope(input.to_container(), |input| {
261 let range = input.range();
262 f(
263 Parser {
264 input,
265 threads: Threads {
266 queue: BinaryHeap::new(),
267 seen: BTreeSet::new(),
268 },
269 gss: GraphStack {
270 returns: HashMap::new(),
271 },
272 memoizer: Memoizer {
273 lengths: HashMap::new(),
274 },
275 sppf: ParseForest {
276 possibilities: HashMap::new(),
277 },
278 },
279 Range(range),
280 )
281 })
282 }
283 pub fn input(&self, range: Range<'i>) -> &I::Slice {
284 I::slice(&self.input, range)
285 }
286 pub fn source_info(&self, range: Range<'i>) -> I::SourceInfo {
287 I::source_info(&self.input, range)
288 }
289 pub fn input_consume_left<Pat>(&self, range: Range<'i>, pat: Pat) -> Option<Range<'i>>
290 where
291 I::Slice: InputMatch<Pat>,
292 {
293 self.input(range)
294 .match_left(pat)
295 .map(|n| Range(range.split_at(n).1))
296 }
297 pub fn input_consume_right<Pat>(&self, range: Range<'i>, pat: Pat) -> Option<Range<'i>>
298 where
299 I::Slice: InputMatch<Pat>,
300 {
301 self.input(range)
302 .match_right(pat)
303 .map(|n| Range(range.split_at(range.len() - n).0))
304 }
305 pub fn call(&mut self, call: Call<'i, C>, next: Continuation<'i, C>) {
306 let returns = self.gss.returns.entry(call).or_default();
307 if returns.insert(next) {
308 if returns.len() > 1 {
309 if let Some(lengths) = self.memoizer.lengths.get(&call) {
310 for &len in lengths {
311 self.threads.spawn(next, Range(call.range.split_at(len).1));
312 }
313 }
314 } else {
315 self.threads.spawn(
316 Continuation {
317 code: call.callee,
318 fn_input: call.range,
319 state: 0,
320 },
321 call.range,
322 );
323 }
324 }
325 }
326 pub fn ret(&mut self, from: Continuation<'i, C>, remaining: Range<'i>) {
327 let call = Call {
328 callee: from.code.enclosing_fn(),
329 range: from.fn_input,
330 };
331 if self
332 .memoizer
333 .lengths
334 .entry(call)
335 .or_default()
336 .insert(call.range.subtract_suffix(remaining).len())
337 {
338 if let Some(returns) = self.gss.returns.get(&call) {
339 for &next in returns {
340 self.threads.spawn(next, remaining);
341 }
342 }
343 }
344 }
345}
346
347pub struct Threads<'i, C: CodeLabel> {
348 queue: BinaryHeap<Call<'i, Continuation<'i, C>>>,
349 seen: BTreeSet<Call<'i, Continuation<'i, C>>>,
350}
351
352impl<'i, C: CodeLabel> Threads<'i, C> {
353 pub fn spawn(&mut self, next: Continuation<'i, C>, range: Range<'i>) {
354 let t = Call {
355 callee: next,
356 range,
357 };
358 if self.seen.insert(t) {
359 self.queue.push(t);
360 }
361 }
362 pub fn steal(&mut self) -> Option<Call<'i, Continuation<'i, C>>> {
363 if let Some(t) = self.queue.pop() {
364 loop {
365 let old = self.seen.iter().rev().next().cloned();
366 if let Some(old) = old {
367 if !t.range.contains(old.range.start()).is_some() {
369 self.seen.remove(&old);
370 continue;
371 }
372 }
373 break;
374 }
375 Some(t)
376 } else {
377 self.seen.clear();
378 None
379 }
380 }
381}
382
383#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
384pub struct Continuation<'i, C: CodeLabel> {
385 pub code: C,
386 pub fn_input: Range<'i>,
387 pub state: usize,
388}
389
390#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
391pub struct Call<'i, C> {
392 pub callee: C,
393 pub range: Range<'i>,
394}
395
396impl<'i, C: fmt::Display> fmt::Display for Call<'i, C> {
397 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
398 write!(
399 f,
400 "{}({}..{})",
401 self.callee,
402 self.range.start(),
403 self.range.end()
404 )
405 }
406}
407
408impl<'i, C: PartialOrd> PartialOrd for Call<'i, C> {
409 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
410 (Reverse(self.range), &self.callee).partial_cmp(&(Reverse(other.range), &other.callee))
411 }
412}
413
414impl<'i, C: Ord> Ord for Call<'i, C> {
415 fn cmp(&self, other: &Self) -> Ordering {
416 (Reverse(self.range), &self.callee).cmp(&(Reverse(other.range), &other.callee))
417 }
418}
419
420pub struct GraphStack<'i, C: CodeLabel> {
421 returns: HashMap<Call<'i, C>, BTreeSet<Continuation<'i, C>>>,
422}
423
424impl<'i, C: CodeLabel> GraphStack<'i, C> {
425 pub fn dump_graphviz(&self, out: &mut Write) -> io::Result<()> {
426 writeln!(out, "digraph gss {{")?;
427 writeln!(out, " graph [rankdir=RL]")?;
428 for (call, returns) in &self.returns {
429 for next in returns {
430 writeln!(
431 out,
432 r#" "{:?}" -> "{:?}" [label="{:?}"]"#,
433 call,
434 Call {
435 callee: next.code.enclosing_fn(),
436 range: next.fn_input
437 },
438 next.code
439 )?;
440 }
441 }
442 writeln!(out, "}}")
443 }
444}
445
446pub struct Memoizer<'i, C: CodeLabel> {
447 lengths: HashMap<Call<'i, C>, BTreeSet<usize>>,
448}
449
450impl<'i, C: CodeLabel> Memoizer<'i, C> {
451 pub fn results<'a>(
452 &'a self,
453 call: Call<'i, C>,
454 ) -> impl DoubleEndedIterator<Item = Range<'i>> + 'a {
455 self.lengths
456 .get(&call)
457 .into_iter()
458 .flat_map(move |lengths| {
459 lengths
460 .iter()
461 .map(move |&len| Range(call.range.split_at(len).0))
462 })
463 }
464 pub fn longest_result(&self, call: Call<'i, C>) -> Option<Range<'i>> {
465 self.results(call).rev().next()
466 }
467}
468
469pub struct ParseForest<'i, P: ParseNodeKind> {
470 pub possibilities: HashMap<ParseNode<'i, P>, BTreeSet<usize>>,
471}
472
473#[derive(Debug)]
474pub struct MoreThanOne;
475
476impl<'i, P: ParseNodeKind> ParseForest<'i, P> {
477 pub fn add(&mut self, kind: P, range: Range<'i>, possibility: usize) {
478 self.possibilities
479 .entry(ParseNode { kind, range })
480 .or_default()
481 .insert(possibility);
482 }
483
484 pub fn one_choice(&self, node: ParseNode<'i, P>) -> Result<ParseNode<'i, P>, MoreThanOne> {
485 match node.kind.shape() {
486 ParseNodeShape::Choice => {
487 let choices = &self.possibilities[&node];
488 if choices.len() > 1 {
489 return Err(MoreThanOne);
490 }
491 let &choice = choices.iter().next().unwrap();
492 Ok(ParseNode {
493 kind: P::from_usize(choice),
494 range: node.range,
495 })
496 }
497 shape => unreachable!("one_choice({}): non-choice shape {}", node, shape),
498 }
499 }
500
501 pub fn all_choices<'a>(
502 &'a self,
503 node: ParseNode<'i, P>,
504 ) -> impl Iterator<Item = ParseNode<'i, P>> + Clone + 'a {
505 match node.kind.shape() {
506 ParseNodeShape::Choice => self
507 .possibilities
508 .get(&node)
509 .into_iter()
510 .flatten()
511 .cloned()
512 .map(move |i| ParseNode {
513 kind: P::from_usize(i),
514 range: node.range,
515 }),
516 shape => unreachable!("all_choices({}): non-choice shape {}", node, shape),
517 }
518 }
519
520 pub fn one_split(
521 &self,
522 node: ParseNode<'i, P>,
523 ) -> Result<(ParseNode<'i, P>, ParseNode<'i, P>), MoreThanOne> {
524 match node.kind.shape() {
525 ParseNodeShape::Split(left_kind, right_kind) => {
526 let splits = &self.possibilities[&node];
527 if splits.len() > 1 {
528 return Err(MoreThanOne);
529 }
530 let &split = splits.iter().next().unwrap();
531 let (left, right, _) = node.range.split_at(split);
532 Ok((
533 ParseNode {
534 kind: left_kind,
535 range: Range(left),
536 },
537 ParseNode {
538 kind: right_kind,
539 range: Range(right),
540 },
541 ))
542 }
543 shape => unreachable!("one_split({}): non-split shape {}", node, shape),
544 }
545 }
546
547 pub fn all_splits<'a>(
548 &'a self,
549 node: ParseNode<'i, P>,
550 ) -> impl Iterator<Item = (ParseNode<'i, P>, ParseNode<'i, P>)> + Clone + 'a {
551 match node.kind.shape() {
552 ParseNodeShape::Split(left_kind, right_kind) => self
553 .possibilities
554 .get(&node)
555 .into_iter()
556 .flatten()
557 .cloned()
558 .map(move |i| {
559 let (left, right, _) = node.range.split_at(i);
560 (
561 ParseNode {
562 kind: left_kind,
563 range: Range(left),
564 },
565 ParseNode {
566 kind: right_kind,
567 range: Range(right),
568 },
569 )
570 }),
571 shape => unreachable!("all_splits({}): non-split shape {}", node, shape),
572 }
573 }
574
575 pub fn dump_graphviz(&self, out: &mut Write) -> io::Result<()> {
576 writeln!(out, "digraph sppf {{")?;
577 let mut queue: VecDeque<_> = self.possibilities.keys().cloned().collect();
578 let mut seen: BTreeSet<_> = queue.iter().cloned().collect();
579 let mut p = 0;
580 while let Some(source) = queue.pop_front() {
581 writeln!(out, " {:?} [shape=box]", source.to_string())?;
582 let mut add_children = |children: &[(&str, ParseNode<'i, P>)]| -> io::Result<()> {
583 writeln!(out, r#" p{} [label="" shape=point]"#, p)?;
584 writeln!(out, " {:?} -> p{}:n", source.to_string(), p)?;
585 for &(port, child) in children {
586 writeln!(
587 out,
588 " p{}:{} -> {:?}:n [dir=none]",
589 p,
590 port,
591 child.to_string()
592 )?;
593 if seen.insert(child) {
594 queue.push_back(child);
595 }
596 }
597 p += 1;
598 Ok(())
599 };
600 match source.kind.shape() {
601 ParseNodeShape::Opaque => {}
602
603 ParseNodeShape::Alias(_) => {
604 add_children(&[("s", source.unpack_alias())])?;
605 }
606
607 ParseNodeShape::Opt(_) => {
608 if let Some(child) = source.unpack_opt() {
609 add_children(&[("s", child)])?;
610 }
611 }
612
613 ParseNodeShape::Choice => {
614 for child in self.all_choices(source) {
615 add_children(&[("s", child)])?;
616 }
617 }
618
619 ParseNodeShape::Split(..) => {
620 for (left, right) in self.all_splits(source) {
621 add_children(&[("sw", left), ("se", right)])?;
622 }
623 }
624 }
625 }
626 writeln!(out, "}}")
627 }
628}
629
630#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
631pub struct ParseNode<'i, P: ParseNodeKind> {
632 pub kind: P,
633 pub range: Range<'i>,
634}
635
636impl<'i, P: ParseNodeKind> ParseNode<'i, P> {
637 pub fn unpack_alias(self) -> Self {
638 match self.kind.shape() {
639 ParseNodeShape::Alias(inner) => ParseNode {
640 kind: inner,
641 range: self.range,
642 },
643 shape => unreachable!("unpack_alias({}): non-alias shape {}", self, shape),
644 }
645 }
646
647 pub fn unpack_opt(self) -> Option<Self> {
648 match self.kind.shape() {
649 ParseNodeShape::Opt(inner) => {
650 if self.range.is_empty() {
651 None
652 } else {
653 Some(ParseNode {
654 kind: inner,
655 range: self.range,
656 })
657 }
658 }
659 shape => unreachable!("unpack_opt({}): non-opt shape {}", self, shape),
660 }
661 }
662}
663
664impl<'i, P: ParseNodeKind> fmt::Display for ParseNode<'i, P> {
665 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
666 write!(
667 f,
668 "{} @ {}..{}",
669 self.kind,
670 self.range.start(),
671 self.range.end()
672 )
673 }
674}
675
676impl<'i, P: ParseNodeKind> fmt::Debug for ParseNode<'i, P> {
677 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
678 write!(
679 f,
680 "{} @ {}..{}",
681 self.kind,
682 self.range.start(),
683 self.range.end()
684 )
685 }
686}
687
688pub trait ParseNodeKind: fmt::Display + Ord + Hash + Copy + 'static {
689 fn shape(self) -> ParseNodeShape<Self>;
690 fn from_usize(i: usize) -> Self;
691 fn to_usize(self) -> usize;
692}
693
694pub trait CodeLabel: fmt::Debug + Ord + Hash + Copy + 'static {
695 fn enclosing_fn(self) -> Self;
696}
697
698pub mod nd {
701 use std::iter;
702 use std::marker::PhantomData;
703
704 pub trait Arrow: Copy {
705 type Input;
706 type Output;
707 type Iter: Iterator<Item = Self::Output> + Clone;
708 fn apply(&self, x: Self::Input) -> Self::Iter;
709
710 fn map<F: Fn(Self::Output) -> R, R>(self, f: F) -> Map<Self, F> {
711 Map(self, f)
712 }
713 fn then<B: Arrow<Input = Self::Output>>(self, b: B) -> Then<Self, B> {
714 Then(self, b)
715 }
716 fn pairs<B: Arrow>(self, b: B) -> Pairs<Self, B>
717 where
718 Self::Output: Copy,
719 B::Input: Copy,
720 {
721 Pairs(self, b)
722 }
723 }
724
725 macro_rules! derive_copy {
726 ($name:ident<$($param:ident $(: $bound:ident)*),*>) => {
727 impl<$($param $(: $bound)*),*> Copy for $name<$($param),*> {}
728 impl<$($param $(: $bound)*),*> Clone for $name<$($param),*> {
729 fn clone(&self) -> Self {
730 *self
731 }
732 }
733 }
734 }
735
736 pub struct Id<T>(PhantomData<T>);
737 derive_copy!(Id<T>);
738 impl<T> Id<T> {
739 pub fn new() -> Self {
740 Id(PhantomData)
741 }
742 }
743 impl<T: Clone> Arrow for Id<T> {
744 type Input = T;
745 type Output = T;
746 type Iter = iter::Once<T>;
747 fn apply(&self, x: T) -> Self::Iter {
748 iter::once(x)
749 }
750 }
751
752 pub struct FromIter<T, F>(F, PhantomData<T>);
753 derive_copy!(FromIter<T, F: Copy>);
754 impl<T, F> FromIter<T, F> {
755 pub fn new(f: F) -> Self {
756 FromIter(f, PhantomData)
757 }
758 }
759 impl<T, F: Copy + Fn(T) -> I, I: Iterator + Clone> Arrow for FromIter<T, F> {
760 type Input = T;
761 type Output = I::Item;
762 type Iter = I;
763 fn apply(&self, x: T) -> I {
764 self.0(x)
765 }
766 }
767
768 pub struct FromIterK<K, T, F>(K, F, PhantomData<T>);
769 derive_copy!(FromIterK<K: Copy, T, F: Copy>);
770 impl<K, T, F> FromIterK<K, T, F> {
771 pub fn new(k: K, f: F) -> Self {
772 FromIterK(k, f, PhantomData)
773 }
774 }
775 impl<K: Copy, T, F: Copy + Fn(K, T) -> I, I: Iterator + Clone> Arrow for FromIterK<K, T, F> {
776 type Input = T;
777 type Output = I::Item;
778 type Iter = I;
779 fn apply(&self, x: T) -> I {
780 self.1(self.0, x)
781 }
782 }
783
784 #[derive(Copy, Clone)]
785 pub struct Map<A, F>(A, F);
786 impl<A: Arrow, F: Copy + Fn(A::Output) -> R, R> Arrow for Map<A, F> {
787 type Input = A::Input;
788 type Output = R;
789 type Iter = iter::Map<A::Iter, F>;
790 fn apply(&self, x: Self::Input) -> Self::Iter {
791 self.0.apply(x).map(self.1)
792 }
793 }
794
795 #[derive(Clone)]
796 pub struct ThenIter<A: Arrow, B: Arrow<Input = A::Output>> {
797 a_iter: A::Iter,
798 b_arrow: B,
799 b_iter: Option<B::Iter>,
800 b_iter_backwards: Option<B::Iter>,
803 }
804 impl<A: Arrow, B: Arrow<Input = A::Output>> Iterator for ThenIter<A, B> {
805 type Item = B::Output;
806 fn next(&mut self) -> Option<Self::Item> {
807 loop {
808 if let Some(ref mut b_iter) = self.b_iter {
809 if let x @ Some(_) = b_iter.next() {
810 return x;
811 }
812 }
813 match self.a_iter.next() {
814 None => {
817 return match self.b_iter_backwards {
818 Some(ref mut b_iter) => b_iter.next(),
819 None => None,
820 }
821 }
822 Some(x) => self.b_iter = Some(self.b_arrow.apply(x)),
823 }
824 }
825 }
826 }
827
828 #[derive(Copy, Clone)]
829 pub struct Then<A, B>(A, B);
830 impl<A: Arrow, B: Arrow<Input = A::Output>> Arrow for Then<A, B> {
831 type Input = A::Input;
832 type Output = B::Output;
833 type Iter = ThenIter<A, B>;
834 fn apply(&self, x: Self::Input) -> Self::Iter {
835 ThenIter {
836 a_iter: self.0.apply(x),
837 b_arrow: self.1,
838 b_iter: None,
839 b_iter_backwards: None,
840 }
841 }
842 }
843
844 #[derive(Clone)]
845 pub struct PairsIter<A: Arrow, B: Arrow>
846 where
847 A::Output: Copy,
848 B::Input: Copy,
849 {
850 a_iter: A::Iter,
851 b_iter0: B::Iter,
852 a_output_b_iter: Option<(A::Output, B::Iter)>,
853 }
854 impl<A: Arrow, B: Arrow> Iterator for PairsIter<A, B>
855 where
856 A::Output: Copy,
857 B::Input: Copy,
858 {
859 type Item = (A::Output, B::Output);
860 fn next(&mut self) -> Option<Self::Item> {
861 loop {
862 if let Some((x, ref mut b_iter)) = self.a_output_b_iter {
863 if let Some(y) = b_iter.next() {
864 return Some((x, y));
865 }
866 }
867 match self.a_iter.next() {
868 None => return None,
869 Some(x) => {
870 self.a_output_b_iter = Some((x, self.b_iter0.clone()));
871 }
872 }
873 }
874 }
875 }
876
877 #[derive(Copy, Clone)]
878 pub struct Pairs<A, B>(A, B);
879 impl<A: Arrow, B: Arrow> Arrow for Pairs<A, B>
880 where
881 A::Output: Copy,
882 B::Input: Copy,
883 {
884 type Input = (A::Input, B::Input);
885 type Output = (A::Output, B::Output);
886 type Iter = PairsIter<A, B>;
887 fn apply(&self, (x, y): Self::Input) -> Self::Iter {
888 PairsIter {
889 a_iter: self.0.apply(x),
890 b_iter0: self.1.apply(y),
891 a_output_b_iter: None,
892 }
893 }
894 }
895}
896
897pub use crate::traverse;
899
900#[macro_export]
901macro_rules! traverse {
902 (typeof($leaf:ty) _) => { $leaf };
903 (typeof($leaf:ty) ?) => { Option<traverse!(typeof($leaf) _)> };
904 (typeof($leaf:ty) ($l_shape:tt, $r_shape:tt)) => { (traverse!(typeof($leaf) $l_shape), traverse!(typeof($leaf) $r_shape)) };
905 (typeof($leaf:ty) { $($i:tt $_i:ident: $kind:pat => $shape:tt,)* }) => { ($(traverse!(typeof($leaf) $shape),)*) };
906 (typeof($leaf:ty) [$shape:tt]) => { (traverse!(typeof($leaf) $shape),) };
907
908 (one($sppf:ident, $node:ident) _) => {
909 $node
910 };
911 (one($sppf:ident, $node:ident) ?) => {
912 Some($node)
913 };
914 (one($sppf:ident, $node:ident) ($l_shape:tt, $r_shape:tt)) => {
915 {
916 let (left, right) = $sppf.one_split($node)?;
917 (
918 traverse!(one($sppf, left) $l_shape),
919 traverse!(one($sppf, right) $r_shape),
920 )
921 }
922 };
923 (one($sppf:ident, $node:ident) { $($i:tt $_i:ident: $kind:pat => $shape:tt,)* }) => {
924 {
925 let node = $sppf.one_choice($node)?;
926 let mut r = <($(traverse!(typeof(_) $shape),)*)>::default();
927 match node.kind {
928 $($kind => r.$i = traverse!(one($sppf, node) $shape),)*
929 _ => unreachable!(),
930 }
931 r
932 }
933 };
934 (one($sppf:ident, $node:ident) [$shape:tt]) => {
935 {
936 let mut r = <(traverse!(typeof(_) $shape),)>::default();
937 if let Some(node) = $node.unpack_opt() {
938 r.0 = traverse!(one($sppf, node) $shape);
939 }
940 r
941 }
942 };
943
944 (all($sppf:ident) _) => {
945 $crate::runtime::nd::Id::new()
946 };
947 (all($sppf:ident) ?) => {
948 $crate::runtime::nd::Id::new().map(Some)
949 };
950 (all($sppf:ident) ($l_shape:tt, $r_shape:tt)) => {
951 $crate::runtime::nd::FromIterK::new($sppf, $crate::runtime::ParseForest::all_splits)
952 .then(traverse!(all($sppf) $l_shape).pairs(traverse!(all($sppf) $r_shape)))
953 };
954 (all($sppf:ident) { $($i:tt $_i:ident: $kind:pat => $shape:tt,)* }) => {
955 $crate::runtime::nd::FromIter::new(move |node| {
956 #[derive(Clone)]
957 enum Iter<$($_i),*> {
958 $($_i($_i)),*
959 }
960 impl<$($_i: Iterator),*> Iterator for Iter<$($_i),*>
961 where $($_i::Item: Default),*
962 {
963 type Item = ($($_i::Item),*);
964 fn next(&mut self) -> Option<Self::Item> {
965 let mut r = Self::Item::default();
966 match self {
967 $(Iter::$_i(iter) => r.$i = iter.next()?),*
968 }
969 Some(r)
970 }
971 }
972 $sppf.all_choices(node).flat_map(move |node| {
973 match node.kind {
974 $($kind => Iter::$_i(traverse!(all($sppf) $shape).apply(node)),)*
975 _ => unreachable!(),
976 }
977 })
978 })
979 };
980 (all($sppf:ident) [$shape:tt]) => {
981 $crate::runtime::nd::FromIter::new(move |node| {
982 match $crate::runtime::ParseNode::unpack_opt(node) {
983 Some(node) => {
984 Some(traverse!(all($sppf) $shape).apply(node).map(|x| (x,)))
985 .into_iter().flatten().chain(None)
986 }
987 None => {
988 None.into_iter().flatten().chain(Some(<_>::default()))
989 }
990 }
991 })
992 }
993}