1use std::rc::{Rc};
2
3use super::{bracket, stmt, parsers, EndOfFile, Location, Token, Stream, Characters, Parse};
4
5fn make_parser<'a>(source: impl 'a + Stream, word_parser: &'a parsers::Word) -> impl 'a + Stream {
12 let stream = parsers::LEXER.parse_stream(source);
13 let stream = word_parser.parse_stream(stream);
14 parsers::brace(stream)
15}
16
17fn skip(stream: &mut impl Stream) -> Option<Location> {
22 loop {
23 let token = stream.read();
24 if token.is_incomplete() || token.is::<EndOfFile>() { return None; }
25 if token == ';' { return Some(token.location()); }
26 if token.is::<bracket::Brace>() { return Some(token.location()); }
27 if token.is::<stmt::Stmt>() {
28 return Some(token.location());
30 }
31 }
32}
33
34#[derive(Debug)]
47pub struct Buffer {
48 word_parser: parsers::Word,
50
51 source: String,
53
54 is_complete: bool,
56}
57
58impl Default for Buffer {
59 fn default() -> Self {
60 Self {word_parser: parsers::word(), source: String::new(), is_complete: false}
61 }
62}
63
64impl Buffer {
65 pub fn remainder(&self) -> &str { &self.source }
67
68 pub fn clear(&mut self) { self.source.clear(); }
70
71 pub fn push_str(&mut self, source: &str) {
73 assert!(!self.is_complete());
74 self.source.push_str(source);
75 }
76
77 pub fn complete(&mut self) { self.is_complete = true; }
88
89 pub fn is_complete(&self) -> bool { self.is_complete }
91
92 pub fn try_parse(&mut self) -> Option<(Rc<str>, Token)> {
108 let (token, end) = {
109 let source = Characters::new(self.remainder(), self.is_complete);
110 let mut stream = make_parser(source, &self.word_parser);
111 let token = stream.read();
112 if token.is_incomplete() || token.is::<EndOfFile>() { return None; }
113 let mut end = token.location().end;
115 if token.result_ref().is_err() { if let Some(loc) = skip(&mut stream) { end = loc.end; } }
116 (token, end)
117 };
118 let s: String = self.source.drain(..std::cmp::min(end, self.source.len())).collect();
119 Some((s.into(), token))
120 }
121}
122
123#[cfg(test)]
126mod tests {
127 use super::*;
128
129 fn check(
130 source: &'static str,
131 is_complete: bool,
132 expected: impl Into<Vec<&'static str>>,
133 expected_remainder: &'static str,
134 ) {
135 let mut buffer = Buffer::default();
136 buffer.push_str(source);
137 if is_complete { buffer.complete(); }
138 let mut tokens: Vec<String> = Vec::new();
139 while let Some((s, token)) = buffer.try_parse() {
140 let loc = token.location();
141 let span = String::from(&s[loc.start..loc.end]);
142 tokens.push(span);
143 }
144 assert_eq!(tokens, expected.into());
145 assert_eq!(buffer.remainder(), expected_remainder);
146 }
147
148 #[test]
149 fn whitespace() {
150 check(" ", true, [], " ");
151 }
152
153 #[test]
154 fn semicolon() {
155 check(" ; ", true, [";"], " ");
156 }
157
158 #[test]
159 fn five() {
160 check(" 5; ", true, ["5;"], " ");
161 }
162
163 #[test]
164 fn if_() {
165 check("if b {}", true, ["if b {}"], "");
166 check("if b {}", false, [], "if b {}");
167 check("if b {};", false, ["if b {}", ";"], "");
168 }
169
170 #[test]
171 fn if_else() {
172 check("if b {} else {}", true, ["if b {} else {}"], "");
173 check("if b {} else {}", false, ["if b {} else {}"], "");
174 check("if b {} else {};", false, ["if b {} else {}", ";"], "");
175 }
176
177 #[test]
178 fn fn_() {
179 check("fn f() {}\nx; y", true, ["fn f() {}\nx;", "y"], "");
180 check("fn f() {}\nx; y", false, ["fn f() {}\nx;"], " y");
181 check("fn f() {};\nx; y", false, ["fn f() {};", "x;"], " y");
182 }
183}