1
//! Whitespace skipping and the `; @annotation` reader-comment
2
//! collector. The annotation handler is the only place that pulls
3
//! `parse_expr` back in from the surrounding module — annotations
4
//! evaluate their RHS as an expression so the sample harness can
5
//! attach metadata like `; @test (= (count 'defun) 5)`.
6

            
7
use winnow::ascii::{line_ending, space0, till_line_ending};
8
use winnow::combinator::opt;
9
use winnow::error::ModalResult;
10
use winnow::prelude::*;
11
use winnow::token::take_while;
12

            
13
use crate::ast::{Annotation, Expr};
14

            
15
8478304
pub(super) fn skip_ws_and_comments(
16
8478304
    input: &mut &str,
17
8478304
    annotations: &mut Vec<Annotation>,
18
8478304
) -> ModalResult<()> {
19
    loop {
20
10904443
        let _ = space0.parse_next(input)?;
21
10904443
        if input.starts_with("; @") {
22
11088
            let _ = "; @".parse_next(input)?;
23
55443
            let name: &str = take_while(1.., |c: char| c.is_alphanumeric() || c == '-' || c == '_')
24
11088
                .parse_next(input)?;
25
11088
            let _ = space0.parse_next(input)?;
26

            
27
11088
            let value = super::parse_expr(input).unwrap_or(Expr::Nil);
28
11088
            annotations.push(Annotation {
29
11088
                name: name.to_string(),
30
11088
                value,
31
11088
            });
32
11088
            let _ = till_line_ending.parse_next(input)?;
33
11088
            let _ = opt(line_ending).parse_next(input)?;
34
10893355
        } else if input.starts_with(';') {
35
1158372
            let _ = till_line_ending.parse_next(input)?;
36
1158372
            let _ = opt(line_ending).parse_next(input)?;
37
9734983
        } else if input.starts_with('\n') || input.starts_with('\r') {
38
1256679
            let _ = line_ending.parse_next(input)?;
39
        } else {
40
8478304
            break;
41
        }
42
    }
43
8478304
    Ok(())
44
8478304
}
45

            
46
7594026
pub(super) fn skip_ws_and_comments_no_annotations(input: &mut &str) -> ModalResult<()> {
47
7594026
    let mut dummy = Vec::new();
48
7594026
    skip_ws_and_comments(input, &mut dummy)
49
7594026
}