Rewrote value storage and implemented class instantiation

* Probably not the last time.
  * Object-like things (functions, classes, etc...) are stored as
    ref-counted cells.
  * Separate data structure for native functions.
  * with_callable() method on value to run specific code on objects
    that are callable
  * Instance type added.
  * Instance construction implemented
This commit is contained in:
Emmanuel BENOîT 2023-01-08 10:40:36 +01:00
parent 85e9c7db38
commit d8dba3ac5f
8 changed files with 274 additions and 100 deletions
src/interpreter

View file

@ -1,9 +1,28 @@
use std::{cell::RefCell, fmt::Display, rc::Rc};
use crate::errors::SloxResult;
use super::{Callable, InterpreterState, Value};
/// A Lox class.
#[derive(Debug, Clone)]
pub struct Class {
name: String,
}
/// Classes are mostly used through references.
pub type ClassRef = Rc<RefCell<Class>>;
/// An instance of a Lox class
#[derive(Debug, Clone)]
pub struct Instance {
class: Rc<RefCell<Class>>,
}
/* -------------------- *
* Class implementation *
* -------------------- */
impl Class {
/// Create a new class, specifying its name.
pub fn new(name: String) -> Self {
@ -11,8 +30,40 @@ impl Class {
}
}
impl ToString for Class {
fn to_string(&self) -> String {
self.name.clone()
impl Display for Class {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("<class ")?;
f.write_str(&self.name)?;
f.write_str(">")
}
}
impl Callable for ClassRef {
fn arity(&self) -> usize {
return 0;
}
fn call(&self, _itpr_state: &mut InterpreterState, _arguments: Vec<Value>) -> SloxResult<Value> {
let instance = Instance::new(self.clone());
Ok(Value::from(instance))
}
}
/* ----------------------- *
* Instance implementation *
* ----------------------- */
impl Instance {
fn new(class: ClassRef) -> Self {
Self { class }
}
}
impl Display for Instance {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!(
"<Instance of {}>",
self.class.borrow().to_string()
))
}
}