WIP Progress on parsing labels

- Add parsing for motion at start of line
- Start parsing if statements
- Add first file-based parsing test
- Implement Rule for `Box<dyn Rule>`
This commit is contained in:
2025-05-17 16:44:02 -07:00
parent cd8cc1dd57
commit 773ee19158
4 changed files with 71 additions and 4 deletions
+51 -4
View File
@@ -24,11 +24,34 @@ fn program() -> impl Rule {
} }
fn line() -> impl Rule { fn line() -> impl Rule {
Alt((send, label_line, any_line)) (motion_prefix, Alt((command_line, label_line, any_line)))
} }
fn send() -> impl Rule { fn motion_prefix() -> impl Rule {
("#", w, NoCase("send"), ww, Tag("ref", label_name), w, eol) star!(Alt(("/", "?")), w, direction)
}
fn command_line() -> impl Rule {
("#", w, bare_command)
}
fn bare_command() -> impl Rule {
Alt((bare_if, bare_send))
}
fn bare_if() -> impl Rule {
(
"if",
w,
condition,
w,
Opt(("then", w)),
Box::new(line) as Box<dyn Rule>,
)
}
fn bare_send() -> impl Rule {
(NoCase("send"), ww, Tag("ref", label_name), w, eol)
} }
fn any_line() -> impl Rule { fn any_line() -> impl Rule {
@@ -160,7 +183,9 @@ fn ww() -> impl Rule {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use insta::assert_debug_snapshot; use std::fs;
use insta::{assert_debug_snapshot, assert_snapshot};
use crate::preprocess::peg::Ref; use crate::preprocess::peg::Ref;
@@ -225,4 +250,26 @@ mod test {
] ]
"#); "#);
} }
#[test]
fn test_label_detection() {
let input = fs::read_to_string("tests/labels/find-all.txt").unwrap();
let mut parser = Parser::new(&input);
assert!(program.parse(&mut parser));
let mut result = String::new();
let mut last_index = 0;
for group in parser.iter() {
let before = &input[last_index..group.span().start];
let inner = match group.kind() {
"label" => format!("({})", group.text()),
_ => group.text().into(),
};
result.push_str(before);
result.push_str(&inner);
last_index = group.span().end;
}
result.push_str(&input[last_index..]);
assert_snapshot!(result);
}
} }
@@ -0,0 +1,9 @@
---
source: src/labels/labels.rs
expression: result
---
'Find all the labels and their references
:(foo)
#send foo
#if blocked n #send foo
#if bar foo
+6
View File
@@ -106,6 +106,12 @@ pub trait Rule {
fn parse(&self, p: &mut Parser) -> bool; fn parse(&self, p: &mut Parser) -> bool;
} }
impl Rule for Box<dyn Rule> {
fn parse(&self, p: &mut Parser) -> bool {
self.as_ref().parse(p)
}
}
pub struct Ref<T>(pub T); pub struct Ref<T>(pub T);
impl<T> Rule for Ref<&T> impl<T> Rule for Ref<&T>
+5
View File
@@ -0,0 +1,5 @@
'Find all the labels and their references
:foo
#send foo
#if blocked n #send foo
#if bar foo