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}