Interpreter - Working bound methods

This commit is contained in:
Emmanuel BENOîT 2023-01-09 11:19:42 +01:00
parent 542bc56aad
commit 3e4aea0d78
3 changed files with 39 additions and 6 deletions

View file

@ -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"),
)
}
}

View file

@ -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"),
)
}

View file

@ -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),
}
}
}