object/
object.rs

1use std::collections::HashMap;
2use std::fmt;
3use std::fmt::{Formatter, write};
4use std::hash::{Hash, Hasher};
5use std::rc::Rc;
6
7use parser::ast::{BlockStatement, IDENTIFIER};
8
9#[macro_use]
10extern crate lazy_static;
11
12use crate::environment::Env;
13
14pub mod builtins;
15pub mod environment;
16
17pub type EvalError = String;
18pub type BuiltinFunc = fn(Vec<Rc<Object>>) -> Rc<Object>;
19
20#[derive(Debug, Clone, Eq, PartialEq)]
21pub enum Object {
22    Integer(i64),
23    Boolean(bool),
24    String(String),
25    Array(Vec<Rc<Object>>),
26    Hash(HashMap<Rc<Object>, Rc<Object>>),
27    Null,
28    ReturnValue(Rc<Object>),
29    Function(Vec<IDENTIFIER>, BlockStatement, Env),
30    Builtin(BuiltinFunc),
31    Error(String),
32    CompiledFunction(Rc<CompiledFunction>),
33    ClosureObj(Closure)
34}
35
36impl fmt::Display for Object {
37    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
38        match self {
39            Object::Integer(i) => write!(f, "{}", i),
40            Object::Boolean(b) => write!(f, "{}", b),
41            Object::String(s) => write!(f, "{}", s),
42            Object::Null => write!(f, "null"),
43            Object::ReturnValue(expr) => write!(f, "{}", expr),
44            Object::Function(params, body, _env) => {
45                let func_params = params
46                    .iter()
47                    .map(|stmt| stmt.to_string())
48                    .collect::<Vec<String>>()
49                    .join(", ");
50                write!(f, "fn({}) {{ {} }}", func_params, body)
51            }
52            Object::Builtin(_) => write!(f, "[builtin function]"),
53            Object::Error(e) => write!(f, "{}", e),
54            Object::Array(e) => write!(
55                f,
56                "[{}]",
57                e.iter()
58                    .map(|o| o.to_string())
59                    .collect::<Vec<String>>()
60                    .join(", ")
61            ),
62            Object::Hash(map) => write!(
63                f,
64                "[{}]",
65                map.iter()
66                    .map(|(k, v)| format!("{}: {}", k, v))
67                    .collect::<Vec<String>>()
68                    .join(", ")
69            ),
70            Object::CompiledFunction(_) => {
71                write!(f, "[compiled function]")
72            }
73            Object::ClosureObj(_) => {
74                write!(f, "[closure function]")
75            }
76        }
77    }
78}
79
80impl Object {
81    pub fn is_hashable(&self) -> bool {
82        match self {
83            Object::Integer(_) | Object::Boolean(_) | Object::String(_) => return true,
84            _ => return false,
85        }
86    }
87}
88
89impl Hash for Object {
90    fn hash<H: Hasher>(&self, state: &mut H) {
91        match self {
92            Object::Integer(i) => i.hash(state),
93            Object::Boolean(b) => b.hash(state),
94            Object::String(s) => s.hash(state),
95            t => panic!("can't hashable for {}", t),
96        }
97    }
98}
99
100#[derive(Debug, Clone, Eq, PartialEq)]
101pub struct CompiledFunction {
102    pub instructions: Vec<u8>,
103    pub num_locals: usize,
104    pub num_parameters: usize,
105}
106
107#[derive(Debug, Clone, Eq, PartialEq)]
108pub struct Closure {
109    pub func: Rc<CompiledFunction>,
110    pub free: Vec<Rc<Object>>,
111}