Files
simple-rust-tests/__lang/monkey-rs/src/object.rs
2022-06-02 00:32:03 +08:00

63 lines
2.1 KiB
Rust

use std;
use crate::ast::BlockStatement;
use crate::environment::Environment;
use std::cell::RefCell;
use std::rc::Rc;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
#[derive(Debug, PartialEq, Clone)]
pub enum Object {
Error(String),
Nil,
Integer(i64),
Boolean(bool),
String(String),
Identifier(String),
FunctionInBuilt(String),
Array(Vec<Object>),
Dict(HashMap<Object, Object>),
FunctionLiteral(Vec<String>, BlockStatement, Rc<RefCell<Environment>>),
}
impl Eq for Object {}
impl Hash for Object {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
Object::String(s) => s.hash(state),
Object::Integer(i) => i.hash(state),
_ => panic!("Invalid dict key {}, supported types are string and integer", self)
}
}
}
impl std::fmt::Display for Object {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
Object::Error(e) => write!(fmt, "{}", e),
Object::Nil => write!(fmt, "nil"),
Object::Integer(i) => write!(fmt, "{}", i),
Object::Boolean(b) => write!(fmt, "{}", b),
Object::Identifier(s) => write!(fmt, "{}", s),
Object::String(s) => write!(fmt, "\"{}\"", s),
Object::Array(arr) => write!(fmt, "[{}]", arr.iter().map(|a| a.to_string()).collect::<Vec<String>>().join(",")),
Object::Dict(dict) => {
let mut str = String::new();
str.push_str("{");
for (k, v) in dict {
str.push_str(format!("{}:{},", k, v).as_str());
}
if str.ends_with(',') {
str.pop();
}
str.push_str("}");
write!(fmt, "{}", str)
},
Object::FunctionLiteral(parameters, block, _) => write!(fmt, "fn({}){{ {} }}",
parameters.join(","), block.to_string()),
_ => panic!("Invalid object {}", self),
}
}
}