Skip to main content

virtual_rust/interpreter/
value.rs

1//! Runtime value representation for the Virtual Rust interpreter.
2//!
3//! This module defines [`Value`], the core enum that represents all possible
4//! values that can exist at runtime during interpretation.
5
6use std::collections::HashMap;
7use std::fmt;
8
9use crate::ast::{Expr, Type};
10use crate::interpreter::environment::Environment;
11
12/// A runtime value produced by evaluating an expression.
13///
14/// Every result of evaluation is represented as a `Value`. This includes
15/// primitive types (int, float, bool, char, string), compound types
16/// (array, tuple, struct), callable types (function, closure), and
17/// control-flow sentinels (break, continue, return).
18#[derive(Debug, Clone)]
19pub enum Value {
20    // ── Primitive types ──────────────────────────────────────────────
21    Int(i64),
22    Float(f64),
23    Bool(bool),
24    Char(char),
25    String(String),
26
27    // ── Compound types ───────────────────────────────────────────────
28    Array(Vec<Value>),
29    Tuple(Vec<Value>),
30    Struct {
31        name: String,
32        fields: HashMap<String, Value>,
33    },
34
35    // ── Callable types ───────────────────────────────────────────────
36    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    // ── Special types ────────────────────────────────────────────────
49    Option(Option<Box<Value>>),
50    Unit,
51
52    // ── Control-flow sentinels ───────────────────────────────────────
53    /// Signals a `break` with an optional value.
54    Break(Option<Box<Value>>),
55    /// Signals a `continue`.
56    Continue,
57    /// Signals a `return` with an optional value.
58    Return(Option<Box<Value>>),
59}
60
61// ── Display ──────────────────────────────────────────────────────────────
62
63impl 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
136// ── Value helpers ────────────────────────────────────────────────────────
137
138impl Value {
139    /// Returns `true` if the value is considered "truthy" in boolean context.
140    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    /// Returns the human-readable name of this value's type.
153    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    /// Debug-style format that shows quotes around strings and chars.
174    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}