From 31c3827e9649ef2d302204c09512b1bd1870ec61 Mon Sep 17 00:00:00 2001 From: Julius de Jeu Date: Mon, 4 Jul 2022 22:23:59 +0200 Subject: [PATCH] Add support for operators to custom type This is done by implementing the required functions for your custom type. Sadly I could not solve this by using the regular traits like `Add`, since I can't easily check if a different trait is implemented. --- src/main.rs | 14 +++++++++++++- src/value/custom.rs | 21 +++++++++++++++++++++ src/value/mod.rs | 3 +++ test.foo | 9 ++++++++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 09fe26c..e40ff50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ -use std::{any::Any, fs::read_to_string}; +use std::{ + any::Any, + fs::read_to_string, +}; use env::Env; use function::FunctionMap; @@ -55,6 +58,14 @@ impl CustomValue for Foo { 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() { @@ -67,6 +78,7 @@ fn main() { }); m.insert_native("waluigi", || "Waluigi"); m.insert_native("native_test", || Foo { x: 41 }); + m.insert_native("other_foo", || Foo { x: 1 }); run(&m, &res); } diff --git a/src/value/custom.rs b/src/value/custom.rs index 8a6029b..689d660 100644 --- a/src/value/custom.rs +++ b/src/value/custom.rs @@ -34,6 +34,27 @@ pub trait CustomValue: std::fmt::Debug + BoxClone { fn to_bool(&self) -> bool { true } + + fn add(&self, _: &Value) -> Value { + Value::default() + } + + fn sub(&self, _: &Value) -> Value { + Value::default() + } + + fn mul(&self, _: &Value) -> Value { + Value::default() + } + + fn div(&self, _: &Value) -> Value { + Value::default() + } + + fn rem(&self, _: &Value) -> Value { + Value::default() + } + } impl PartialEq for dyn CustomValue { diff --git a/src/value/mod.rs b/src/value/mod.rs index 19ec413..c61299e 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -125,6 +125,9 @@ macro_rules! math_trait { match (self, other) { (Value::Int(lhs), Value::Int(rhs)) => Value::Int(lhs.$function_name(rhs)), (Value::Float(lhs), Value::Float(rhs)) => Value::Float(lhs.$function_name(rhs)), + (Value::Custom(lhs), rhs) => { + lhs.$function_name(&rhs) + } _ => Value::Error, } } diff --git a/test.foo b/test.foo index 2379aca..e9016aa 100644 --- a/test.foo +++ b/test.foo @@ -32,4 +32,11 @@ if x == 0 { print(x); let x = 5; -print(if x < 10 { 20 } else { 30 }); \ No newline at end of file +print(if x < 10 { 20 } else { 30 }); + +let f1 = native_test(); +let f2 = other_foo(); + +let f3 = f1 + f2; + +print(f3);