1
use crate::errors::RecoverableParseError;
2

            
3
const KEYWORDS: [&str; 21] = [
4
    "forall", "exists", "such", "that", "letting", "find", "minimise", "maximise", "subject", "to",
5
    "where", "and", "or", "not", "if", "then", "else", "in", "sum", "product", "bool",
6
];
7

            
8
738
pub fn keyword_as_identifier(
9
738
    root: tree_sitter::Node,
10
738
    source: &str,
11
738
    errors: &mut Vec<RecoverableParseError>,
12
738
) {
13
738
    let mut stack = vec![root];
14
38076
    while let Some(node) = stack.pop() {
15
37338
        if (node.kind() == "variable" || node.kind() == "identifier" || node.kind() == "parameter")
16
2806
            && let Ok(text) = node.utf8_text(source.as_bytes())
17
        {
18
2806
            let ident = text.trim();
19
2806
            if KEYWORDS.contains(&ident) {
20
77
                let start_point = node.start_position();
21
77
                let end_point = node.end_position();
22
77
                errors.push(RecoverableParseError::new(
23
77
                    format!("Keyword '{ident}' used as identifier"),
24
77
                    Some(tree_sitter::Range {
25
77
                        start_byte: node.start_byte(),
26
77
                        end_byte: node.end_byte(),
27
77
                        start_point,
28
77
                        end_point,
29
77
                    }),
30
77
                ));
31
2729
            }
32
34532
        }
33

            
34
37338
        for i in 0..node.child_count() {
35
36600
            if let Some(child) = u32::try_from(i).ok().and_then(|i| node.child(i)) {
36
36600
                stack.push(child);
37
36600
            }
38
        }
39
    }
40
738
}