lambda_throw_cat/
value.rs1use std::collections::BTreeMap;
9
10use crate::env::Env;
11use crate::heap::Address;
12use crate::syntax::{Expr, VarName};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum Value {
17 Closure {
19 param: VarName,
21 body: Expr,
23 env: Env,
25 },
26 Ref(Address),
28 Object {
30 properties: BTreeMap<VarName, Value>,
32 prototype: Option<Address>,
34 },
35}
36
37impl Value {
38 #[must_use]
40 pub fn closure(param: VarName, body: Expr, env: Env) -> Self {
41 Self::Closure { param, body, env }
42 }
43
44 #[must_use]
46 pub fn reference(address: Address) -> Self {
47 Self::Ref(address)
48 }
49
50 #[must_use]
52 pub fn object(properties: BTreeMap<VarName, Value>, prototype: Option<Address>) -> Self {
53 Self::Object {
54 properties,
55 prototype,
56 }
57 }
58}
59
60impl std::fmt::Display for Value {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 match self {
63 Self::Closure { param, body, .. } => write!(f, "\\{param}. {body}"),
64 Self::Ref(address) => write!(f, "ref({address})"),
65 Self::Object {
66 properties,
67 prototype,
68 } => write_object(f, properties, *prototype),
69 }
70 }
71}
72
73fn write_object(
74 f: &mut std::fmt::Formatter<'_>,
75 properties: &BTreeMap<VarName, Value>,
76 prototype: Option<Address>,
77) -> std::fmt::Result {
78 let entries = properties
79 .iter()
80 .map(|(k, v)| format!("{k} = {v}"))
81 .collect::<Vec<_>>()
82 .join(", ");
83 let prefix = prototype.map_or(String::new(), |a| format!("proto={a} "));
84 write!(f, "{{{prefix}{entries}}}")
85}