Interpreter - Working bound methods
This commit is contained in:
parent
542bc56aad
commit
3e4aea0d78
3 changed files with 39 additions and 6 deletions
|
@ -1,4 +1,9 @@
|
|||
use std::{cell::RefCell, collections::HashMap, fmt::Display, rc::Rc};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
fmt::Display,
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
errors::{ErrorKind, SloxError, SloxResult},
|
||||
|
@ -77,12 +82,16 @@ impl Instance {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn get(&self, name: &Token) -> SloxResult<Value> {
|
||||
pub(super) fn get(&self, this_value: &Value, name: &Token) -> SloxResult<Value> {
|
||||
if let Some(value) = self.fields.get(&name.lexeme) {
|
||||
return Ok(value.clone());
|
||||
}
|
||||
if let Some(method) = self.class.borrow().methods.get(&name.lexeme) {
|
||||
return Ok(Value::from(method.clone()));
|
||||
if self.class.borrow().methods.get(&name.lexeme).is_some() {
|
||||
let bound_method = BoundMethod {
|
||||
instance: this_value.clone(),
|
||||
method: name.lexeme.clone(),
|
||||
};
|
||||
return Ok(Value::from(bound_method));
|
||||
}
|
||||
|
||||
Err(SloxError::with_token(
|
||||
|
@ -150,6 +159,21 @@ impl Callable for BoundMethod {
|
|||
.environment
|
||||
.borrow_mut()
|
||||
.define(&self.this_token(), Some(self.instance.clone()))?;
|
||||
println!("{:?}", this_env.locals);
|
||||
self.with_method(|m| m.call(&mut this_env, arguments))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for BoundMethod {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.instance.with_instance(
|
||||
|instance| {
|
||||
f.write_fmt(format_args!(
|
||||
"<Bound method {} of {}>",
|
||||
self.method, instance
|
||||
))
|
||||
},
|
||||
|| panic!("Instance value does not contain an instance"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -539,7 +539,7 @@ impl ExprNode {
|
|||
) -> InterpreterResult {
|
||||
let instance = get_expr.instance.interpret(itpr_state)?.result();
|
||||
instance.with_instance(
|
||||
|instance| instance.get(&get_expr.name).map(|v| v.into()),
|
||||
|inst| inst.get(&instance, &get_expr.name).map(|v| v.into()),
|
||||
|| error(&get_expr.name, "only instances have properties"),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{cell::RefCell, fmt::Display, rc::Rc};
|
||||
|
||||
use super::{
|
||||
classes::{Class, ClassRef, Instance},
|
||||
classes::{Class, ClassRef, Instance, BoundMethod},
|
||||
functions::Function,
|
||||
native_fn::NativeFunction,
|
||||
Callable,
|
||||
|
@ -23,6 +23,7 @@ pub enum Object {
|
|||
LoxFunction(Function),
|
||||
Class(ClassRef),
|
||||
Instance(Instance),
|
||||
BoundMethod(BoundMethod),
|
||||
}
|
||||
|
||||
/* -------------------- *
|
||||
|
@ -56,6 +57,7 @@ impl Value {
|
|||
Object::LoxFunction(func) => fok(func),
|
||||
Object::Class(class) => fok(class),
|
||||
Object::Instance(_) => ferr(),
|
||||
Object::BoundMethod(bm) => fok(bm),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,6 +150,12 @@ impl From<Instance> for Value {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<BoundMethod> for Value {
|
||||
fn from(value: BoundMethod) -> Self {
|
||||
Value::Object(Rc::new(RefCell::new(Object::BoundMethod(value))))
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------- *
|
||||
* Object implementation *
|
||||
* --------------------- */
|
||||
|
@ -159,6 +167,7 @@ impl Display for Object {
|
|||
Object::LoxFunction(func) => func.fmt(f),
|
||||
Object::Class(cls) => cls.borrow().fmt(f),
|
||||
Object::Instance(inst) => inst.fmt(f),
|
||||
Object::BoundMethod(bm) => bm.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue