Skip to main content

neutron_engine/iris/
value.rs

1use std::collections::HashMap;
2use std::fmt;
3use std::rc::Rc;
4use std::cell::RefCell;
5
6/// Iris Value Types
7#[derive(Debug, Clone, PartialEq)]
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 fmt::Display for Value {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        match self {
27            Value::Null => write!(f, "null"),
28            Value::Bool(b) => write!(f, "{}", b),
29            Value::Number(n) => {
30                if n.fract() == 0.0 {
31                    write!(f, "{:.0}", n)
32                } else {
33                    write!(f, "{}", n)
34                }
35            }
36            Value::String(s) => write!(f, "{}", s),
37            Value::Array(arr) => {
38                let arr = arr.borrow();
39                let items: Vec<String> = arr.iter().map(|v| v.to_string()).collect();
40                write!(f, "[{}]", items.join(", "))
41            }
42            Value::Object(obj) => {
43                let obj = obj.borrow();
44                let items: Vec<String> = obj
45                    .iter()
46                    .map(|(k, v)| format!("{}: {}", k, v))
47                    .collect();
48                write!(f, "{{{}}}", items.join(", "))
49            }
50            Value::Function { .. } => write!(f, "<function>"),
51            Value::Builtin(_) => write!(f, "<builtin function>"),
52            Value::Return(v) => write!(f, "{}", v),
53        }
54    }
55}
56
57impl Value {
58    pub fn is_truthy(&self) -> bool {
59        match self {
60            Value::Null => false,
61            Value::Bool(b) => *b,
62            Value::Number(n) => *n != 0.0,
63            Value::String(s) => !s.is_empty(),
64            _ => true,
65        }
66    }
67
68    pub fn type_name(&self) -> &'static str {
69        match self {
70            Value::Null => "null",
71            Value::Bool(_) => "bool",
72            Value::Number(_) => "number",
73            Value::String(_) => "string",
74            Value::Array(_) => "array",
75            Value::Object(_) => "object",
76            Value::Function { .. } | Value::Builtin(_) => "function",
77            Value::Return(_) => "return",
78        }
79    }
80}
81