85 lines
1.7 KiB
Rust
85 lines
1.7 KiB
Rust
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<FunctionMap> {
|
|
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>() {
|
|
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);
|
|
}
|