#![feature(assert_matches)]
#![feature(get_mut_unchecked)]
use std::rc::Rc;
mod ast;
mod binop;
mod builtins;
mod scope;
mod thunk;
mod value;
use ast::{AstNode, Rule};
use binop::BinOp;
pub use builtins::BuiltinFn;
use scope::ScopePtr;
use thunk::Thunk;
pub use value::Value;
#[macro_use]
extern crate pest_derive;
#[derive(Debug, Clone)]
pub enum Error {
ParseError(Box<pest::error::Error<Rule>>),
ImportReadError(Rc<std::io::Error>),
NameResolutionError(ScopePtr, String),
AttributeAccessOnBadType(Rc<Value>, String),
NoSuchAttribute(ScopePtr, String),
BadFunctionCall(String, Thunk),
InvalidArguments(Thunk, Vec<Thunk>),
BuiltinInvalidArguments(&'static str, Vec<Thunk>),
UnsupportedOperation(BinOp, Rc<Value>, Rc<Value>),
BadEvaluationAccess,
TypeError(String, Thunk),
IndexError(usize, Thunk),
Custom(String),
}
type Result<T> = std::result::Result<T, Error>;
impl From<pest::error::Error<Rule>> for Error {
fn from(parse_error: pest::error::Error<Rule>) -> Self {
Error::ParseError(Box::new(parse_error))
}
}
impl From<&Error> for Error {
fn from(value: &Error) -> Self {
value.clone()
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::ParseError(e) => write!(f, "Parse error: {e}"),
_ => write!(f, "{:?}", self),
}
}
}
pub fn parse(contents: &str) -> Result<Rc<Value>> {
let ast = AstNode::parse(contents)?;
Thunk::from(ast.value(&builtins::builtins())).evaluate()
}
#[cfg(feature = "serde")]
extern crate serde as extern_serde;
#[cfg(feature = "serde")]
pub mod serde;
#[cfg(feature = "serde")]
impl extern_serde::de::Error for Error {
fn custom<T>(msg: T) -> Self
where
T: std::fmt::Display,
{
Error::Custom(format!("{}", msg))
}
}
#[cfg(feature = "serde")]
impl extern_serde::ser::StdError for Error {}
#[cfg(feature = "python")]
pub mod py;
#[cfg(feature = "python")]
impl From<Error> for pyo3::PyErr {
fn from(value: Error) -> Self {
crate::py::ConflagError::new_err(format!("{value}"))
}
}