qalam 0.3.1

Interpreter for the Qalam programming language. Qalam is a dead-simple, Urdu inspired, interpreted programming langauge.
Documentation
use crate::callable::class::QalamClass;
use crate::callable::function::QalamFunction;
use crate::error::RuntimeError;
use crate::hashable::{HashableMap, HashableRcRefCell};
use crate::literal::Literal;
use crate::token::Token;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct QalamInstance {
    pub class: QalamClass,
    pub fields: HashableMap<String, Option<Literal>>,
}

impl QalamInstance {
    pub fn init(class: QalamClass) -> Self {
        return Self {
            class,
            fields: HashableMap::new(),
        };
    }

    pub fn to_string(&self) -> String {
        return format!("<instanceof {}>", self.class.name);
    }

    pub fn get(
        instance: HashableRcRefCell<QalamInstance>,
        name: &Token,
    ) -> Result<Option<Literal>, RuntimeError> {
        if instance.0.borrow().fields.contains_key(&name.lexeme) {
            return Ok(instance
                .0
                .borrow()
                .fields
                .get(&name.lexeme)
                .unwrap()
                .clone());
        }

        let method = instance.0.borrow().class.find_method(&name.lexeme);
        if let Some(method) = method {
            if let Some(method) = method.as_any().downcast_ref::<QalamFunction>() {
                return Ok(Some(Literal::Callable(Box::new(
                    method.bind(instance.clone()),
                ))));
            }
            // return Ok(Some(Literal::Callable(method)));
        }

        return Err(RuntimeError::init(
            name,
            format!("Undefined property '{}'.", name.lexeme),
        ));
    }

    pub fn set(&mut self, name: &Token, value: Option<Literal>) {
        self.fields.insert(name.lexeme.to_owned(), value);
    }
}