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::{
|
use crate::{
|
||||||
errors::{ErrorKind, SloxError, SloxResult},
|
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) {
|
if let Some(value) = self.fields.get(&name.lexeme) {
|
||||||
return Ok(value.clone());
|
return Ok(value.clone());
|
||||||
}
|
}
|
||||||
if let Some(method) = self.class.borrow().methods.get(&name.lexeme) {
|
if self.class.borrow().methods.get(&name.lexeme).is_some() {
|
||||||
return Ok(Value::from(method.clone()));
|
let bound_method = BoundMethod {
|
||||||
|
instance: this_value.clone(),
|
||||||
|
method: name.lexeme.clone(),
|
||||||
|
};
|
||||||
|
return Ok(Value::from(bound_method));
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(SloxError::with_token(
|
Err(SloxError::with_token(
|
||||||
|
@ -150,6 +159,21 @@ impl Callable for BoundMethod {
|
||||||
.environment
|
.environment
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.define(&self.this_token(), Some(self.instance.clone()))?;
|
.define(&self.this_token(), Some(self.instance.clone()))?;
|
||||||
|
println!("{:?}", this_env.locals);
|
||||||
self.with_method(|m| m.call(&mut this_env, arguments))
|
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 {
|
) -> InterpreterResult {
|
||||||
let instance = get_expr.instance.interpret(itpr_state)?.result();
|
let instance = get_expr.instance.interpret(itpr_state)?.result();
|
||||||
instance.with_instance(
|
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"),
|
|| error(&get_expr.name, "only instances have properties"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{cell::RefCell, fmt::Display, rc::Rc};
|
use std::{cell::RefCell, fmt::Display, rc::Rc};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
classes::{Class, ClassRef, Instance},
|
classes::{Class, ClassRef, Instance, BoundMethod},
|
||||||
functions::Function,
|
functions::Function,
|
||||||
native_fn::NativeFunction,
|
native_fn::NativeFunction,
|
||||||
Callable,
|
Callable,
|
||||||
|
@ -23,6 +23,7 @@ pub enum Object {
|
||||||
LoxFunction(Function),
|
LoxFunction(Function),
|
||||||
Class(ClassRef),
|
Class(ClassRef),
|
||||||
Instance(Instance),
|
Instance(Instance),
|
||||||
|
BoundMethod(BoundMethod),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------- *
|
/* -------------------- *
|
||||||
|
@ -56,6 +57,7 @@ impl Value {
|
||||||
Object::LoxFunction(func) => fok(func),
|
Object::LoxFunction(func) => fok(func),
|
||||||
Object::Class(class) => fok(class),
|
Object::Class(class) => fok(class),
|
||||||
Object::Instance(_) => ferr(),
|
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 *
|
* Object implementation *
|
||||||
* --------------------- */
|
* --------------------- */
|
||||||
|
@ -159,6 +167,7 @@ impl Display for Object {
|
||||||
Object::LoxFunction(func) => func.fmt(f),
|
Object::LoxFunction(func) => func.fmt(f),
|
||||||
Object::Class(cls) => cls.borrow().fmt(f),
|
Object::Class(cls) => cls.borrow().fmt(f),
|
||||||
Object::Instance(inst) => inst.fmt(f),
|
Object::Instance(inst) => inst.fmt(f),
|
||||||
|
Object::BoundMethod(bm) => bm.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue