Created
March 6, 2019 07:09
-
-
Save mbillingr/9b174e03eb685adb79fa42adb4693f48 to your computer and use it in GitHub Desktop.
Experimental Object Protocol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::any::Any; | |
| type State = Vec<Object>; | |
| trait ObjectProtocol: std::fmt::Debug { | |
| fn as_any(&self) -> &dyn Any; | |
| fn as_number(&self) -> Option<&dyn NumberProtocol>; | |
| fn repr(&self, _state: &mut State); | |
| fn is_number(&self) -> bool { self.as_number().is_some() } | |
| } | |
| trait NumberProtocol { | |
| fn add(&self, _state: &mut State); | |
| } | |
| #[derive(Debug)] | |
| enum Object { | |
| Nil, | |
| Int(i32), | |
| Dynamic(Box<dyn ObjectProtocol>), | |
| } | |
| impl ObjectProtocol for Object { | |
| fn as_any(&self) -> &dyn Any { | |
| match self { | |
| Object::Dynamic(obj) => obj.as_any(), | |
| _ => self, | |
| } | |
| } | |
| fn as_number(&self) -> Option<&dyn NumberProtocol> { | |
| match self { | |
| Object::Nil => None, | |
| Object::Int(_) => Some(self), | |
| Object::Dynamic(obj) => obj.as_number(), | |
| } | |
| } | |
| fn repr(&self, _state: &mut State) { | |
| unimplemented!() | |
| } | |
| } | |
| impl NumberProtocol for Object { | |
| fn add(&self, state: &mut State) { | |
| match self { | |
| Object::Nil => panic!("add nil"), | |
| Object::Int(_) => {} | |
| Object::Dynamic(obj) => obj.as_number().unwrap().add(state), | |
| } | |
| } | |
| } | |
| #[derive(Debug)] | |
| struct Complex(f64, f64); | |
| impl ObjectProtocol for Complex { | |
| fn as_any(&self) -> &dyn Any { | |
| self | |
| } | |
| fn as_number(&self) -> Option<&dyn NumberProtocol> { | |
| Some(self) | |
| } | |
| fn repr(&self, _state: &mut State) { | |
| unimplemented!() | |
| } | |
| } | |
| impl NumberProtocol for Complex { | |
| fn add(&self, _state: &mut State) {} | |
| } | |
| impl Complex { | |
| fn try_cast(obj: &Object) -> Option<&Complex> { | |
| obj.as_any().downcast_ref() | |
| } | |
| } | |
| fn is_complex(obj: &dyn Any) -> bool { | |
| obj.is::<Complex>() | |
| } | |
| fn main() { | |
| let mut stack: State = vec![ | |
| Object::Nil, | |
| Object::Dynamic(Box::new(Complex(4.0, 2.0))), | |
| Object::Int(42), | |
| ]; | |
| println!("{:?}", stack); | |
| //stack.pop().unwrap().as_number().unwrap().add(&mut stack); | |
| //stack.pop().unwrap().as_number().unwrap().add(&mut stack); | |
| println!("{:?}", Complex::try_cast(&stack.pop().unwrap())); | |
| println!("{:?}", Complex::try_cast(&stack.pop().unwrap())); | |
| println!("{:?}", Complex::try_cast(&stack.pop().unwrap())); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment