use crate::{
error::EggResult,
expression::{Expression, Value},
scope::{self, Scope},
};
use alloc::{boxed::Box, collections::BTreeMap};
mod arithmetic;
mod boolean;
mod comparison;
mod control_flow;
mod convert;
#[cfg(feature = "std")]
mod console;
mod stringtools;
mod variables;
pub trait Operator {
fn evaluate(&self, args: &[Expression], scope: &mut Scope, operators: &BTreeMap<&str, Box<dyn Operator>>) -> EggResult<Value>;
}
pub fn empty() -> BTreeMap<&'static str, Box<dyn Operator>> {
BTreeMap::new()
}
pub fn minimal<'a>(map: &'a mut BTreeMap<&'static str, Box<dyn Operator>>) -> &'a mut BTreeMap<&'static str, Box<dyn Operator>> {
map.insert("define", Box::new(variables::Define));
map.insert("set", Box::new(variables::Set));
map.insert("delete", Box::new(variables::Delete));
map.insert("exists", Box::new(variables::Exists));
map.insert("typeof", Box::new(variables::TypeOf));
map.insert("if", Box::new(control_flow::If));
map.insert("do", Box::new(control_flow::Do));
map.insert("while", Box::new(control_flow::While));
map.insert("repeat", Box::new(control_flow::Repeat));
map.insert("panic", Box::new(control_flow::Panic));
map.insert("assert", Box::new(control_flow::Assert));
map.insert("equals", Box::new(comparison::Equals));
map.insert("not_equals", Box::new(comparison::NotEquals));
map.insert("greater_than", Box::new(comparison::GreaterThan));
map.insert("less_than", Box::new(comparison::LessThan));
map.insert("is_nil", Box::new(comparison::IsNil));
map.insert("sum", Box::new(arithmetic::Sum));
map.insert("subtract", Box::new(arithmetic::Subtract));
map.insert("divide", Box::new(arithmetic::Divide));
map.insert("multiply", Box::new(arithmetic::Multiply));
map.insert("modulus", Box::new(arithmetic::Modulus));
map.insert("and", Box::new(boolean::AND));
map.insert("or", Box::new(boolean::OR));
map.insert("not", Box::new(boolean::NOT));
map.insert("str", Box::new(convert::ToString));
map.insert("num", Box::new(convert::ToNumber));
map.insert("fn", Box::new(scope::functions::CreateFunction));
map
}
pub fn objects(map: &mut BTreeMap<&'static str, Box<dyn Operator>>) {
map.insert("object.new", Box::new(scope::object::CreateObject));
map.insert("object.get", Box::new(scope::object::Get));
map.insert("object.insert", Box::new(scope::object::Insert));
map.insert("object.has", Box::new(scope::object::Has));
map.insert("object.remove", Box::new(scope::object::Remove));
map.insert("object.size", Box::new(scope::object::Size));
map.insert("object.clear", Box::new(scope::object::Clear));
}
pub fn strings<'a>(map: &'a mut BTreeMap<&'static str, Box<dyn Operator>>) {
map.insert("string.length", Box::new(stringtools::Length));
map.insert("string.slice", Box::new(stringtools::Slice));
map.insert("string.concat", Box::new(stringtools::Concat));
map.insert("string.to_upper", Box::new(stringtools::ToUpper));
map.insert("string.to_lower", Box::new(stringtools::ToLower));
map.insert("string.trim", Box::new(stringtools::Trim));
}
#[cfg(feature = "std")]
pub fn console<'a>(map: &'a mut BTreeMap<&'static str, Box<dyn Operator>>) {
map.insert("print", Box::new(console::Print));
map.insert("println", Box::new(console::PrintLine));
map.insert("readline", Box::new(console::ReadLine));
}
pub fn full<'a>(map: &'a mut BTreeMap<&'static str, Box<dyn Operator>>) {
minimal(map);
objects(map);
strings(map);
#[cfg(feature = "std")]
{
map.insert("sleep", Box::new(control_flow::Sleep));
console(map);
}
}