1use crate::{
4 ast::statements::{Param, Statement, TypeAnnotation},
5 interpreter::evaluator::EnvironmentItem,
6};
7use std::{cell::RefCell, collections::HashMap, fmt, rc::Rc};
8
9#[derive(Debug, Clone, PartialEq)]
11pub enum Value {
12 Integer(i64),
14 Float(f64),
16 String(String),
18 Bool(bool),
20 Byte(u8),
22 Char(char),
24 Values {
26 items_type: TypeAnnotation,
28 items: Vec<Value>,
29 },
30 Null,
32
33 Function(Rc<FunctionData>),
35
36 Tuple(Vec<Value>),
38 Error(Box<Value>),
40 Ok(Box<Value>),
41 Err(Box<Value>),
42
43 Struct {
44 name: String,
45 fields: Rc<RefCell<Vec<(String, Value)>>>,
46 },
47 Enum {
48 name: String,
49 variant: String,
50 },
51
52 Map {
53 key_type: TypeAnnotation,
54 value_type: TypeAnnotation,
55 entries: Rc<RefCell<HashMap<MapKey, Value>>>,
56 },
57 Set {
58 items_type: TypeAnnotation,
60 items: Vec<Value>,
61 },
62}
63
64#[derive(Debug, Clone, PartialEq)]
66pub struct FunctionData {
67 pub params: Rc<Vec<Param>>,
68 pub body: Rc<Vec<Statement>>,
69 pub return_type: Option<TypeAnnotation>,
71 pub captured_env: Vec<Vec<EnvironmentItem>>,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Hash)]
76pub enum MapKey {
77 Integer(i64),
78 String(String),
79 Bool(bool),
80 Byte(u8),
81 Char(char),
82}
83
84impl MapKey {
85 pub fn from_value(value: &Value) -> Option<MapKey> {
86 match value {
87 Value::Integer(i) => Some(MapKey::Integer(*i)),
88 Value::String(s) => Some(MapKey::String(s.clone())),
89 Value::Bool(b) => Some(MapKey::Bool(*b)),
90 Value::Byte(b) => Some(MapKey::Byte(*b)),
91 Value::Char(c) => Some(MapKey::Char(*c)),
92 _ => None,
93 }
94 }
95
96 pub fn into_value(self) -> Value {
97 match self {
98 MapKey::Integer(i) => Value::Integer(i),
99 MapKey::String(s) => Value::String(s),
100 MapKey::Bool(b) => Value::Bool(b),
101 MapKey::Byte(b) => Value::Byte(b),
102 MapKey::Char(c) => Value::Char(c),
103 }
104 }
105}
106
107impl Value {
108 pub fn type_name(&self) -> &'static str {
110 match self {
111 Value::Integer(_) => "int",
112 Value::Float(_) => "float",
113 Value::String(_) => "string",
114 Value::Bool(_) => "bool",
115 Value::Byte(_) => "byte",
116 Value::Char(_) => "char",
117 Value::Values { .. } => "array",
118 Value::Map { .. } => "map",
119 Value::Null => "null",
120 Value::Function { .. } => "function",
121 Value::Tuple(_) => "tuple",
122 Value::Error(_) => "error",
123 Value::Ok(_) => "ok",
124 Value::Err(_) => "err",
125 Value::Struct { .. } => "record",
126 Value::Enum { .. } => "tag",
127 Value::Set { .. } => "set",
128 }
129 }
130
131 pub fn is_ok(&self) -> bool {
132 matches!(self, Value::Ok(_))
133 }
134 pub fn is_err(&self) -> bool {
135 matches!(self, Value::Err(_))
136 }
137}
138
139impl fmt::Display for Value {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 match self {
142 Value::Integer(i) => write!(f, "{}", i),
143 Value::Float(fl) => write!(f, "{}", fl),
144 Value::String(s) => write!(f, "{}", s),
145 Value::Bool(b) => write!(f, "{}", b),
146 Value::Byte(b) => write!(f, "{}", b),
147 Value::Char(c) => write!(f, "'{}'", c),
148 Value::Values { items, .. } => {
149 let formatted: Vec<String> = items.iter().map(|v| v.to_string()).collect();
150 write!(f, "[{}]", formatted.join(", "))
151 }
152 Value::Null => write!(f, "null"),
153 Value::Function(data) => {
154 let mut params_name = vec![];
155 for param in data.params.iter() {
156 params_name.push(param.param_name.clone());
157 }
158 write!(f, "<fn({})>", params_name.join(", "))
159 }
160 Value::Tuple(items) => {
161 let formatted: Vec<String> = items.iter().map(|v| v.to_string()).collect();
162 write!(f, "({})", formatted.join(", "))
163 }
164 Value::Error(inner) => write!(f, "error({})", inner),
165 Value::Ok(inner) => write!(f, "ok({})", inner),
166 Value::Err(inner) => write!(f, "err({})", inner),
167 Value::Struct { name, fields } => {
168 let fields = fields.borrow();
169 let formatted: Vec<String> = fields
170 .iter()
171 .map(|(field_name, value)| format!("{}: {}", field_name, value))
172 .collect();
173 write!(f, "{} {{ {} }}", name, formatted.join(", "))
174 }
175 Value::Enum { name, variant } => write!(f, "{}.{}", name, variant),
176 Value::Map { entries, .. } => {
177 let entries = entries.borrow();
178 let formatted: Vec<String> = entries
179 .iter()
180 .map(|(k, v)| format!("{}: {}", k.clone().into_value(), v))
181 .collect();
182 write!(f, "{{{}}}", formatted.join(", "))
183 }
184 Value::Set { items, .. } => {
185 let formatted: Vec<String> = items.iter().map(|v| v.to_string()).collect();
186 write!(f, "{{{}}}", formatted.join(", "))
187 }
188 }
189 }
190}