use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
use super::Object;
use crate::code::definitions::Instructions;
#[derive(Debug, Default)]
pub struct CompiledFunction {
pub instructions: Rc<Instructions>,
pub num_locals: usize,
pub num_params: usize,
pub line: usize,
}
impl CompiledFunction {
pub fn new(
instructions: Instructions,
num_locals: usize,
num_params: usize,
line: usize,
) -> Self {
Self {
instructions: Rc::new(instructions),
num_locals,
num_params,
line,
}
}
}
impl fmt::Display for CompiledFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<compiled function>")
}
}
impl PartialEq for CompiledFunction {
fn eq(&self, other: &Self) -> bool {
self.instructions == other.instructions
}
}
impl Eq for CompiledFunction {}
#[derive(Debug, Default)]
pub struct Closure {
pub func: Rc<CompiledFunction>,
pub free: RefCell<Vec<Rc<Object>>>,
}
impl Closure {
pub fn new(func: Rc<CompiledFunction>, free: Vec<Rc<Object>>) -> Self {
Self {
func,
free: RefCell::new(free),
}
}
}
impl fmt::Display for Closure {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<closure>")
}
}
impl PartialEq for Closure {
fn eq(&self, other: &Self) -> bool {
self.func == other.func
}
}
pub type BuiltinFunctionProto = fn(Vec<Rc<Object>>) -> Result<Rc<Object>, String>;
#[derive(Debug, Clone)]
pub struct BuiltinFunction {
pub name: &'static str,
pub func: BuiltinFunctionProto,
}
impl fmt::Display for BuiltinFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<built-in function {}>", self.name)
}
}
impl BuiltinFunction {
pub const fn new(name: &'static str, func: BuiltinFunctionProto) -> BuiltinFunction {
BuiltinFunction { name, func }
}
}
impl PartialEq for BuiltinFunction {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}