neutron_engine/iris/
value.rs1use std::collections::HashMap;
2use std::fmt;
3use std::rc::Rc;
4use std::cell::RefCell;
5
6#[derive(Debug, Clone)]
8pub enum Value {
9 Null,
10 Bool(bool),
11 Number(f64),
12 String(String),
13 Array(Rc<RefCell<Vec<Value>>>),
14 Object(Rc<RefCell<HashMap<String, Value>>>),
15 Function {
16 params: Vec<String>,
17 body: Vec<crate::iris::parser::Stmt>,
18 closure: Rc<RefCell<HashMap<String, Value>>>,
19 },
20 Builtin(fn(&[Value]) -> Result<Value, String>),
21 Return(Box<Value>),
22}
23
24impl PartialEq for Value {
25 fn eq(&self, other: &Self) -> bool {
26 match (self, other) {
27 (Value::Null, Value::Null) => true,
28 (Value::Bool(a), Value::Bool(b)) => a == b,
29 (Value::Number(a), Value::Number(b)) => a == b,
30 (Value::String(a), Value::String(b)) => a == b,
31 (Value::Array(a), Value::Array(b)) => a == b,
32 (Value::Object(a), Value::Object(b)) => a == b,
33 (
34 Value::Function { params: ap, body: ab, closure: ac },
35 Value::Function { params: bp, body: bb, closure: bc },
36 ) => ap == bp && ab == bb && ac == bc,
37 (Value::Builtin(a), Value::Builtin(b)) => std::ptr::fn_addr_eq(*a, *b),
38 (Value::Return(a), Value::Return(b)) => a == b,
39 _ => false,
40 }
41 }
42}
43
44impl fmt::Display for Value {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 Value::Null => write!(f, "null"),
48 Value::Bool(b) => write!(f, "{}", b),
49 Value::Number(n) => {
50 if n.fract() == 0.0 {
51 write!(f, "{:.0}", n)
52 } else {
53 write!(f, "{}", n)
54 }
55 }
56 Value::String(s) => write!(f, "{}", s),
57 Value::Array(arr) => {
58 let arr = arr.borrow();
59 let items: Vec<String> = arr.iter().map(|v| v.to_string()).collect();
60 write!(f, "[{}]", items.join(", "))
61 }
62 Value::Object(obj) => {
63 let obj = obj.borrow();
64 let items: Vec<String> = obj
65 .iter()
66 .map(|(k, v)| format!("{}: {}", k, v))
67 .collect();
68 write!(f, "{{{}}}", items.join(", "))
69 }
70 Value::Function { .. } => write!(f, "<function>"),
71 Value::Builtin(_) => write!(f, "<builtin function>"),
72 Value::Return(v) => write!(f, "{}", v),
73 }
74 }
75}
76
77impl Value {
78 pub fn is_truthy(&self) -> bool {
79 match self {
80 Value::Null => false,
81 Value::Bool(b) => *b,
82 Value::Number(n) => *n != 0.0,
83 Value::String(s) => !s.is_empty(),
84 _ => true,
85 }
86 }
87
88 pub fn type_name(&self) -> &'static str {
89 match self {
90 Value::Null => "null",
91 Value::Bool(_) => "bool",
92 Value::Number(_) => "number",
93 Value::String(_) => "string",
94 Value::Array(_) => "array",
95 Value::Object(_) => "object",
96 Value::Function { .. } | Value::Builtin(_) => "function",
97 Value::Return(_) => "return",
98 }
99 }
100}
101