use alloc::fmt::Debug;
use alloc::format;
use alloc::string::String;
use alloc::string::ToString;
use alloc::vec::Vec;
use core::fmt::{Display, Formatter};
use simple_detailed_error::{SimpleErrorDetail, SimpleErrorExplanation};
use ast::Statement;
use crate::function::MoonFunction;
use crate::value::FullValue;
pub mod optimized_ast;
pub mod ast;
#[derive(Debug)]
pub enum RuntimeError {
FunctionError { function_error_message: String },
CannotTurnPredicateToBool { type_of_statement: &'static str, function_error_message: String },
CannotParseArgument,
AnArgumentIsMissing,
}
impl RuntimeError {
pub(crate) fn explain(&self) -> String {
match self {
RuntimeError::CannotTurnPredicateToBool { type_of_statement, function_error_message } =>
format!("Could not parse predicate of a {type_of_statement} block due to: {function_error_message}"),
RuntimeError::FunctionError { function_error_message } =>
format!("Could not execute a function due to: {function_error_message}"),
RuntimeError::CannotParseArgument => "A function argument type is wrong".to_string(),
RuntimeError::AnArgumentIsMissing => "A function is missing an argument".to_string(),
}
}
}
impl SimpleErrorDetail for RuntimeError {
fn explain_error(&self) -> SimpleErrorExplanation {
SimpleErrorExplanation::new().explanation(self.explain())
}
}
impl Display for RuntimeError{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.write_str(&self.explain_error().to_display_struct(true).to_string())
}
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct ASTFunction {
pub(crate) function: MoonFunction,
pub(crate) args: Vec<FullValue>,
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct ConditionalStatements {
pub(crate) condition: FullValue,
pub(crate) statements: Vec<Statement>,
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct RuntimeVariable {
pub(crate) value: FullValue,
}
impl From<FullValue> for RuntimeVariable {
fn from(value: FullValue) -> Self {
RuntimeVariable::new(value)
}
}
impl RuntimeVariable {
pub(crate) fn new<Value: Into<FullValue>>(value: Value) -> Self {
Self { value: value.into() }
}
}