Skip to content

Instantly share code, notes, and snippets.

@mbillingr
Created March 6, 2019 07:09
Show Gist options
  • Select an option

  • Save mbillingr/9b174e03eb685adb79fa42adb4693f48 to your computer and use it in GitHub Desktop.

Select an option

Save mbillingr/9b174e03eb685adb79fa42adb4693f48 to your computer and use it in GitHub Desktop.
Experimental Object Protocol
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