diff options
Diffstat (limited to 'src/parse/mod.rs')
| -rw-r--r-- | src/parse/mod.rs | 148 |
1 files changed, 79 insertions, 69 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index bd217c1c..7c0a0932 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -28,103 +28,124 @@ pub fn parse(src: &str) -> Arc<GreenNode> { } } -/// Parse some markup. Returns `Some` if all of the input was consumed. -pub fn parse_markup( - prefix: &str, - src: &str, - _: bool, - min_column: usize, -) -> Option<(Vec<Green>, bool)> { - let mut p = Parser::with_prefix(prefix, src, TokenMode::Markup); - if min_column == 0 { - markup(&mut p, true); - } else { - markup_indented(&mut p, min_column); - } - p.consume() -} - /// Parse some markup without the topmost node. Returns `Some` if all of the /// input was consumed. pub fn parse_markup_elements( prefix: &str, src: &str, + end_pos: usize, + differential: isize, + reference: &[Green], mut at_start: bool, - _: usize, -) -> Option<(Vec<Green>, bool)> { +) -> Option<(Vec<Green>, bool, usize)> { let mut p = Parser::with_prefix(prefix, src, TokenMode::Markup); + + let mut node: Option<&Green> = None; + let mut iter = reference.iter(); + let mut offset = 0; + let mut replaced = 0; + let mut stopped = false; + while !p.eof() { markup_node(&mut p, &mut at_start); + + if p.prev_end() >= end_pos { + let recent = p.children.last().unwrap(); + let recent_start = p.prev_end() - recent.len(); + + while offset <= recent_start { + if let Some(node) = node { + // The nodes are equal, at the same position and have the + // same content. The parsing trees have converged again, so + // the reparse may stop here. + if (offset as isize + differential) as usize == recent_start + && node == recent + { + replaced -= 1; + stopped = true; + break; + } + } + + let result = iter.next(); + if let Some(node) = node { + offset += node.len(); + } + node = result; + if node.is_none() { + break; + } else { + replaced += 1; + } + } + + if stopped { + break; + } + } } - p.consume() -} -/// Parse an atomic primary. Returns `Some` if all of the input was consumed. -pub fn parse_atomic( - prefix: &str, - src: &str, - _: bool, - _: usize, -) -> Option<(Vec<Green>, bool)> { - let mut p = Parser::with_prefix(prefix, src, TokenMode::Code); - primary(&mut p, true).ok()?; - p.consume_open_ended() -} + if p.eof() && !stopped { + replaced = reference.len(); + } -/// Parse an atomic primary. Returns `Some` if all of the input was consumed. -pub fn parse_atomic_markup( - prefix: &str, - src: &str, - _: bool, - _: usize, -) -> Option<(Vec<Green>, bool)> { - let mut p = Parser::with_prefix(prefix, src, TokenMode::Markup); - markup_expr(&mut p); - p.consume_open_ended() + let (mut res, terminated) = p.consume_open_ended()?; + if stopped { + res.pop().unwrap(); + } + + Some((res, terminated, replaced)) } /// Parse a template literal. Returns `Some` if all of the input was consumed. pub fn parse_template( prefix: &str, src: &str, + end_pos: usize, + _: isize, + reference: &[Green], _: bool, - _: usize, -) -> Option<(Vec<Green>, bool)> { +) -> Option<(Vec<Green>, bool, usize)> { let mut p = Parser::with_prefix(prefix, src, TokenMode::Code); if !p.at(&NodeKind::LeftBracket) { return None; } template(&mut p); - p.consume() + + let (mut green, terminated) = p.consume_open_ended()?; + let first = green.remove(0); + if first.len() != end_pos { + return None; + } + + Some((vec![first], terminated, 1)) } /// Parse a code block. Returns `Some` if all of the input was consumed. pub fn parse_block( prefix: &str, src: &str, + end_pos: usize, + _: isize, + reference: &[Green], _: bool, - _: usize, -) -> Option<(Vec<Green>, bool)> { +) -> Option<(Vec<Green>, bool, usize)> { let mut p = Parser::with_prefix(prefix, src, TokenMode::Code); if !p.at(&NodeKind::LeftBrace) { return None; } block(&mut p); - p.consume() -} -/// Parse a comment. Returns `Some` if all of the input was consumed. -pub fn parse_comment( - prefix: &str, - src: &str, - _: bool, - _: usize, -) -> Option<(Vec<Green>, bool)> { - let mut p = Parser::with_prefix(prefix, src, TokenMode::Code); - comment(&mut p).ok()?; - p.consume() + let (mut green, terminated) = p.consume_open_ended()?; + let first = green.remove(0); + + if first.len() != end_pos { + return None; + } + + Some((vec![first], terminated, 1)) } /// Parse markup. @@ -916,17 +937,6 @@ fn body(p: &mut Parser) -> ParseResult { Ok(()) } -/// Parse a comment. -fn comment(p: &mut Parser) -> ParseResult { - match p.peek() { - Some(NodeKind::LineComment | NodeKind::BlockComment) => { - p.eat(); - Ok(()) - } - _ => Err(ParseError), - } -} - #[cfg(test)] mod tests { use std::fmt::Debug; |
