rustyfi_syntax/stream.rs
1//! The parse source for the SATySFi surface grammar.
2//!
3//! The parse source is the eagerly lexed `Vec<Atom>`, wrapped by
4//! [`AtomStream`]: syan core has no `IntoParseStream for Vec<_>`, so the
5//! buffering lives here.
6//!
7//! Neither stream erasure (a `&mut dyn ParseStream` tower) nor a failure
8//! high-water mark belongs here, obsoleted by syan on both counts:
9//! `Parse::parse_stream` takes `&mut S` and recursion reborrows, so `S` is a
10//! genuine fixed point and the instantiation set is finite without erasing
11//! anything (and no stream operation is a virtual call); and `ParseError` is
12//! span-generic, every variant carrying the position it failed at, so the
13//! error reports itself.
14
15use crate::token::Atom;
16use std::convert::Infallible;
17use syan::parse::tape::Tape;
18use syan::parse::ParseStream;
19
20/// A parse source over an eagerly lexed token vector.
21///
22/// Backtracking runs through syan's [`Tape`], which owns the pushback and the
23/// checkpoint scopes, so this is a thin forwarding shim and nothing more.
24pub struct AtomStream {
25 tape: Tape<std::vec::IntoIter<Atom>>,
26}
27
28impl AtomStream {
29 pub fn new(atoms: Vec<Atom>) -> Self {
30 AtomStream {
31 tape: Tape::new(atoms.into_iter()),
32 }
33 }
34}
35
36impl ParseStream for AtomStream {
37 type Atom = Atom;
38 type Error = Infallible;
39
40 fn next(&mut self) -> Option<Self::Atom> {
41 self.tape.next()
42 }
43
44 fn peek(&mut self) -> Option<&Self::Atom> {
45 self.tape.peek()
46 }
47
48 fn push(&mut self, atom: Self::Atom) {
49 self.tape.push(atom);
50 }
51
52 fn checkpoint_raw(&mut self) -> u64 {
53 self.tape.checkpoint()
54 }
55
56 fn rollback_raw(&mut self, raw: u64) {
57 self.tape.rollback(raw);
58 }
59
60 fn commit_raw(&mut self, raw: u64) {
61 self.tape.commit(raw);
62 }
63
64 fn get_error(&mut self) -> Result<(), Self::Error> {
65 Ok(())
66 }
67
68 fn skip_sep(&mut self) -> bool {
69 // Already lexed: there is no separator atom to skip.
70 false
71 }
72}