virtual_rust/interpreter/
value.rs1use std::collections::HashMap;
7use std::fmt;
8
9use crate::ast::{Expr, Type};
10use crate::interpreter::environment::Environment;
11
12#[derive(Debug, Clone)]
19pub enum Value {
20 Int(i64),
22 Float(f64),
23 Bool(bool),
24 Char(char),
25 String(String),
26
27 Array(Vec<Value>),
29 Tuple(Vec<Value>),
30 Struct {
31 name: String,
32 fields: HashMap<String, Value>,
33 },
34
35 Function {
37 name: String,
38 params: Vec<(String, Type)>,
39 body: Box<Expr>,
40 closure_env: Option<Environment>,
41 },
42 Closure {
43 params: Vec<(String, Option<Type>)>,
44 body: Box<Expr>,
45 env: Environment,
46 },
47
48 Option(Option<Box<Value>>),
50 Unit,
51
52 Break(Option<Box<Value>>),
55 Continue,
57 Return(Option<Box<Value>>),
59}
60
61impl fmt::Display for Value {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 match self {
66 Value::Int(n) => write!(f, "{n}"),
67 Value::Float(n) => {
68 if *n == n.floor() && !n.is_infinite() && !n.is_nan() {
69 write!(f, "{n:.1}")
70 } else {
71 write!(f, "{n}")
72 }
73 }
74 Value::Bool(b) => write!(f, "{b}"),
75 Value::Char(c) => write!(f, "{c}"),
76 Value::String(s) => write!(f, "{s}"),
77 Value::Array(arr) => write_array(f, arr),
78 Value::Tuple(elems) => write_tuple(f, elems),
79 Value::Struct { name, fields } => write_struct(f, name, fields),
80 Value::Function { name, .. } => write!(f, "<fn {name}>"),
81 Value::Closure { .. } => write!(f, "<closure>"),
82 Value::Option(Some(v)) => write!(f, "Some({v})"),
83 Value::Option(None) => write!(f, "None"),
84 Value::Unit => write!(f, "()"),
85 Value::Break(_) => write!(f, "<break>"),
86 Value::Continue => write!(f, "<continue>"),
87 Value::Return(_) => write!(f, "<return>"),
88 }
89 }
90}
91
92fn write_array(f: &mut fmt::Formatter<'_>, arr: &[Value]) -> fmt::Result {
93 write!(f, "[")?;
94 for (i, v) in arr.iter().enumerate() {
95 if i > 0 {
96 write!(f, ", ")?;
97 }
98 match v {
99 Value::String(s) => write!(f, "\"{s}\"")?,
100 Value::Char(c) => write!(f, "'{c}'")?,
101 _ => write!(f, "{v}")?,
102 }
103 }
104 write!(f, "]")
105}
106
107fn write_tuple(f: &mut fmt::Formatter<'_>, elements: &[Value]) -> fmt::Result {
108 write!(f, "(")?;
109 for (i, v) in elements.iter().enumerate() {
110 if i > 0 {
111 write!(f, ", ")?;
112 }
113 write!(f, "{v}")?;
114 }
115 if elements.len() == 1 {
116 write!(f, ",")?;
117 }
118 write!(f, ")")
119}
120
121fn write_struct(
122 f: &mut fmt::Formatter<'_>,
123 name: &str,
124 fields: &HashMap<String, Value>,
125) -> fmt::Result {
126 write!(f, "{name} {{ ")?;
127 for (i, (k, v)) in fields.iter().enumerate() {
128 if i > 0 {
129 write!(f, ", ")?;
130 }
131 write!(f, "{k}: {v}")?;
132 }
133 write!(f, " }}")
134}
135
136impl Value {
139 pub fn is_truthy(&self) -> bool {
141 match self {
142 Value::Bool(b) => *b,
143 Value::Int(n) => *n != 0,
144 Value::Float(n) => *n != 0.0,
145 Value::String(s) => !s.is_empty(),
146 Value::Option(v) => v.is_some(),
147 Value::Unit => false,
148 _ => true,
149 }
150 }
151
152 pub fn type_name(&self) -> &str {
154 match self {
155 Value::Int(_) => "i64",
156 Value::Float(_) => "f64",
157 Value::Bool(_) => "bool",
158 Value::Char(_) => "char",
159 Value::String(_) => "String",
160 Value::Array(_) => "array",
161 Value::Tuple(_) => "tuple",
162 Value::Struct { name, .. } => name,
163 Value::Function { .. } => "function",
164 Value::Closure { .. } => "closure",
165 Value::Option(_) => "Option",
166 Value::Unit => "()",
167 Value::Break(_) => "break",
168 Value::Continue => "continue",
169 Value::Return(_) => "return",
170 }
171 }
172
173 pub fn debug_fmt(&self) -> String {
175 match self {
176 Value::String(s) => format!("\"{s}\""),
177 Value::Char(c) => format!("'{c}'"),
178 other => format!("{other}"),
179 }
180 }
181}