use crate::ast::node::Node;
use crate::ast::program::Program;
use crate::eval::Environment;
use crate::functions::ExprCall;
use crate::{ExprPest, Rule};
use crate::{Context, Error, Result, Value};
use pest::Parser as PestParser;
use std::fmt;
use std::fmt::{Debug, Formatter};
pub fn compile(code: &str) -> Result<Program> {
#[cfg(debug_assertions)]
pest::set_error_detail(true);
let pairs = ExprPest::parse(Rule::full, code).map_err(|e| Error::PestError(Box::new(e)))?;
Ok(pairs.into())
}
#[deprecated(note = "Use `compile()` and `Environment` instead")]
#[derive(Default)]
pub struct Parser<'a> {
env: Environment<'a>,
}
#[allow(deprecated)]
impl Debug for Parser<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_struct("ExprParser").finish()
}
}
#[allow(deprecated)]
impl<'a> Parser<'a> {
pub fn new() -> Self {
Parser {
env: Environment::new(),
}
}
pub fn add_function<F>(&mut self, name: &str, f: F)
where
F: Fn(ExprCall) -> Result<Value> + 'a + Sync + Send,
{
self.env.add_function(name, Box::new(f));
}
pub fn compile(&self, code: &str) -> Result<Program> {
compile(code)
}
pub fn run(&self, program: Program, ctx: &Context) -> Result<Value> {
self.env.run(program, ctx)
}
pub fn eval(&self, code: &str, ctx: &Context) -> Result<Value> {
self.env.eval(code, ctx)
}
pub fn eval_expr(&self, ctx: &Context, node: Node) -> Result<Value> {
self.env.eval_expr(ctx, node)
}
}