use core::fmt;
use pest::Span;
mod interpreter;
use interpreter::expr::eval_visitor::EvalVisitor;
use interpreter::{ast::create_ast, parser::parse_dala};
#[derive(Debug, Clone)]
pub enum DalaValue {
Str(String),
Num(f64),
Boolean(bool),
}
impl fmt::Display for DalaValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DalaValue::Str(value) => write!(f, "{}", value),
DalaValue::Num(value) => write!(f, "{}", value),
DalaValue::Boolean(value) => write!(f, "{}", value),
}
}
}
#[derive(Debug, Clone)]
pub struct Position {
pub start: usize,
pub end: usize,
}
impl Position {
pub fn new(pair: Span) -> Self {
Self {
start: pair.start(),
end: pair.end(),
}
}
}
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}, {}", self.start, self.end)
}
}
#[derive(Debug, Clone)]
pub enum DalaError {
BuildError(BuildError),
RuntimeError(RuntimeError),
ParseError(ParseError),
}
impl fmt::Display for DalaError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DalaError::BuildError(err) => write!(f, "{}", err),
DalaError::RuntimeError(err) => write!(f, "{}", err),
DalaError::ParseError(err) => write!(f, "{}", err),
}
}
}
#[derive(Debug, Clone)]
pub struct RuntimeError {
pub pos: Position,
pub message: String,
}
impl RuntimeError {
pub fn new(pos: Position, message: String) -> Self {
Self { pos, message }
}
}
impl fmt::Display for RuntimeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Runtime error: {}, at: {}", self.message, self.pos)
}
}
#[derive(Debug, Clone)]
pub struct BuildError {
pub pos: Position,
pub message: String,
}
impl BuildError {
pub fn new(pos: Position, message: String) -> Self {
Self { pos, message }
}
}
impl fmt::Display for BuildError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Build error: {}, at: {}", self.message, self.pos)
}
}
#[derive(Debug, Clone)]
pub struct ParseError {
pub message: String,
}
impl ParseError {
pub fn new(message: String) -> Self {
Self { message }
}
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Parse error: {}", self.message)
}
}
pub fn eval(str: &str) -> Vec<Result<DalaValue, DalaError>> {
let parsed = parse_dala(str);
if parsed.is_err() {
return vec![Err(parsed.unwrap_err())];
}
create_ast(parsed.unwrap())
.into_iter()
.map(|expr| expr.and_then(|expr| expr.eval()))
.collect()
}