1use bumpalo::Bump;
2use tattle::Reporter;
3
4use crate::{grammar::parse, lexer::lex, parser::Prec, FNtn};
5
6pub struct ParseConfig<'a> {
7 precedences: &'a [(&'a str, Prec)],
8 keywords: &'a [&'a str],
9}
10
11impl<'a> ParseConfig<'a> {
12 pub const fn new(precedences: &'a [(&'a str, Prec)], keywords: &'a [&'a str]) -> Self {
13 Self {
14 precedences,
15 keywords,
16 }
17 }
18
19 pub fn with_parsed<A, F: FnOnce(&FNtn) -> Option<A>>(
20 &self,
21 input: &str,
22 reporter: Reporter,
23 f: F,
24 ) -> Option<A> {
25 let precedences = self
26 .precedences
27 .iter()
28 .map(|(s, p)| (s.to_string(), *p))
29 .collect();
30 let keywords = self.keywords.iter().map(|s| s.to_string()).collect();
31 let tokens = lex(input, keywords, reporter.clone());
32 let arena = Bump::new();
33 let ast = parse(input, reporter.clone(), &precedences, &tokens, &arena);
34 if reporter.errored() {
35 None
36 } else {
37 f(ast)
38 }
39 }
40}