use std::{ any::Any, fs::read_to_string, }; use env::Env; use function::FunctionMap; use statement::Statement; use value::{custom::CustomValue, Value}; mod env; mod expression; mod function; mod macros; mod statement; mod value; // mod lexer; // mod parser; mod pest_parser; fn run(functions: &FunctionMap, statement: &Statement) { let env = Env::new(); statement.eval(&env, functions); } #[derive(Clone, Debug, PartialEq, Eq)] struct Foo { x: i32, } impl Foo { fn edit(&self) -> Self { let mut f = self.clone(); f.x += 1; f } } impl CustomValue for Foo { fn as_any(&self) -> &dyn Any { self } fn format(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Foo({})", self.x) } fn eq(&self, other: &Value) -> bool { if let Some(v) = other.as_t() { self == v } else { false } } fn functions(&self) -> Option { let mut map = FunctionMap::new(); map.insert_native("edit_foo", Foo::edit); Some(map) } fn add(&self, other: &Value) -> Value { if let Some(v) = other.as_t::() { Foo { x: self.x + v.x }.into() } else { Value::default() } } } fn main() { let f = read_to_string("./test.foo").unwrap(); let (res, funcs) = pest_parser::parse(&f); let mut m = FunctionMap::new(); m.insert_holder(funcs); m.insert_native("print", |a: &Value| { println!("{}", a); }); m.insert_native("waluigi", || "Waluigi"); m.insert_native("native_test", || Foo { x: 41 }); m.insert_native("other_foo", || Foo { x: 1 }); run(&m, &res); }