fexplib 0.3.1

A simple lower-house syntax for programming language experimentation
Documentation
use bumpalo::Bump;
use tattle::Reporter;

use crate::{grammar::parse, lexer::lex, parser::Prec, FExp};

pub struct ParseConfig<'a> {
    precedences: &'a [(&'a str, Prec)],
    keywords: &'a [&'a str],
}

impl<'a> ParseConfig<'a> {
    pub const fn new(precedences: &'a [(&'a str, Prec)], keywords: &'a [&'a str]) -> Self {
        Self {
            precedences,
            keywords,
        }
    }

    pub fn with_parsed<A, F: FnOnce(&FExp) -> Option<A>>(
        &self,
        input: &str,
        reporter: Reporter,
        f: F,
    ) -> Option<A> {
        let precedences = self
            .precedences
            .iter()
            .map(|(s, p)| (s.to_string(), *p))
            .collect();
        let keywords = self.keywords.iter().map(|s| s.to_string()).collect();
        let tokens = lex(input, keywords, reporter.clone());
        let arena = Bump::new();
        let ast = parse(input, reporter.clone(), &precedences, &tokens, &arena);
        if reporter.errored() {
            None
        } else {
            f(ast)
        }
    }
}