roost_lang/interpreter/
value.rs

1pub mod bitwise_operations;
2pub mod indexing;
3pub mod iterator;
4pub mod mathematical_operations;
5pub mod members;
6pub mod relational_operations;
7pub mod truth;
8pub mod types;
9
10use crate::{
11    error::{Result, Span},
12    nodes::{Block, MemberKind},
13};
14use rust_decimal::Decimal;
15use std::{
16    cell::RefCell,
17    collections::HashMap,
18    fmt::{Debug, Display},
19    rc::Rc,
20};
21
22pub type WrappedValue<'tree> = Rc<RefCell<Value<'tree>>>;
23
24#[derive(PartialEq, Clone)]
25pub enum Value<'tree> {
26    Number(Decimal),
27    Bool(bool),
28    String(String),
29    Range {
30        start: Option<i128>,
31        end: Option<i128>,
32    },
33    List(Vec<WrappedValue<'tree>>),
34    Function {
35        args: &'tree [String],
36        block: &'tree Block,
37    },
38    BuiltIn(BuiltIn),
39    Class {
40        statics: HashMap<&'tree str, WrappedValue<'tree>>,
41        non_statics: Vec<&'tree MemberKind>,
42    },
43    Object(HashMap<&'tree str, WrappedValue<'tree>>),
44    Null,
45}
46
47impl<'tree> Value<'tree> {
48    pub fn wrapped(self) -> WrappedValue<'tree> {
49        Rc::new(RefCell::new(self))
50    }
51}
52
53#[derive(Clone)]
54pub enum BuiltIn {
55    Function(
56        for<'tree> fn(args: Vec<WrappedValue<'tree>>, span: &Span) -> Result<WrappedValue<'tree>>,
57    ),
58    Method(
59        for<'tree> fn(
60            this: &WrappedValue<'tree>,
61            args: Vec<WrappedValue<'tree>>,
62            span: &Span,
63        ) -> Result<WrappedValue<'tree>>,
64    ),
65    Print {
66        newline: bool,
67        stderr: bool,
68    },
69    Exit,
70    Debug,
71}
72
73impl PartialEq for BuiltIn {
74    fn eq(&self, _other: &Self) -> bool {
75        false
76    }
77}
78
79macro_rules! dbg_map {
80    ($map:ident) => {
81        dbg_map!(@inner $map, "", "", "")
82    };
83    (:? $map:ident) => {
84        dbg_map!(@inner $map, "\x1b[31m", "\x1b[0m", ":?")
85    };
86    (@inner $map:ident, $col:literal, $reset:literal, $dbg:literal) => {
87        $map.iter()
88            .map(|(k, v)| {
89                format!(
90                    concat!("    ", $col, "{k}", $reset, " = {v},\n"),
91                    k = k,
92                    v = format!(concat!("{", $dbg, "}"), v.borrow())
93                        .split('\n')
94                        .collect::<Vec<_>>()
95                        .join("\n    "),
96                )
97            })
98            .collect::<Vec<_>>()
99            .join("")
100    };
101}
102
103impl Display for Value<'_> {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        match self {
106            Value::Number(value) => Display::fmt(&value, f),
107            Value::Bool(value) => Display::fmt(&value, f),
108            Value::String(value) => Display::fmt(&value, f),
109            Value::Range { start, end } => match (start, end) {
110                (Some(start), Some(end)) => write!(f, "{start}..={end}"),
111                (Some(start), None) => write!(f, "{start}.."),
112                (None, Some(end)) => write!(f, "..={end}"),
113                (None, None) => write!(f, ".."),
114            },
115            Value::List(list) => write!(
116                f,
117                "[{}]",
118                list.iter()
119                    .map(|val| val.borrow().to_string())
120                    .collect::<Vec<_>>()
121                    .join(", ")
122            ),
123            Value::Function { .. } | Value::BuiltIn(..) => {
124                write!(f, "<function>")
125            }
126            Value::Class { statics, .. } => write!(f, "<class> {{\n{}}}", dbg_map!(statics)),
127            Value::Object(fields) => write!(f, "<object> {{\n{}}}", dbg_map!(fields)),
128            Value::Null => write!(f, "null"),
129        }
130    }
131}
132
133impl Debug for Value<'_> {
134    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135        match self {
136            Value::Number(value) => write!(f, "\x1b[33m{value}\x1b[0m"),
137            Value::Bool(value) => write!(f, "\x1b[34m{value}\x1b[0m"),
138            Value::String(value) => write!(f, "\x1b[32m'{value}'\x1b[0m"),
139            Value::Range { start, end } => match (start, end) {
140                (Some(start), Some(end)) => {
141                    write!(f, "\x1b[33m{start}\x1b[0m..=\x1b[33m{end}\x1b[0m")
142                }
143                (Some(start), None) => write!(f, "\x1b[33m{start}\x1b[0m.."),
144                (None, Some(end)) => write!(f, "..=\x1b[33m{end}\x1b[0m"),
145                (None, None) => write!(f, ".."),
146            },
147            Value::List(list) => write!(
148                f,
149                "[{}]",
150                list.iter()
151                    .map(|val| format!("{:?}", val.borrow()))
152                    .collect::<Vec<_>>()
153                    .join(", ")
154            ),
155            Value::Function { .. } | Value::BuiltIn(..) => {
156                write!(f, "\x1b[1m<function>\x1b[0m")
157            }
158            Value::Class { statics, .. } => {
159                write!(f, "\x1b[1m<class>\x1b[0m {{\n{}}}", dbg_map!(:? statics))
160            }
161            Value::Object(fields) => {
162                write!(f, "\x1b[1m<object>\x1b[0m {{\n{}}}", dbg_map!(:? fields))
163            }
164            Value::Null => write!(f, "\x1b[90mnull\x1b[0m"),
165        }
166    }
167}
168
169pub trait ToValue {
170    fn to_value<'tree>(&self) -> Value<'tree>;
171}