1use super::Code;
2use super::GenObj;
3use super::RcStr;
4use std::cell::Ref;
5use std::cell::RefCell;
6use std::cell::RefMut;
7use std::cmp;
8use std::fmt;
9use std::rc::Rc;
10
11#[derive(Clone, PartialEq)]
12pub enum Val {
13 Invalid,
15
16 Nil,
17 Bool(bool),
18 Number(f64),
19
20 String(RcStr),
24
25 List(Rc<List>),
26
27 Func(Func),
28
29 GenObj(GenObjPtr),
30}
31
32impl Val {
33 pub fn truthy(&self) -> bool {
34 match self {
35 Self::Invalid => panic!("Val::Invalid.truthy()"),
36 Self::Nil => false,
37 Self::Bool(x) => *x,
38 Self::Number(x) => *x != 0.0,
39 Self::String(x) => x.len() > 0,
40 Self::List(x) => x.borrow().len() > 0,
41 Self::Func(_) | Self::GenObj(_) => true,
42 }
43 }
44 pub fn number(&self) -> Option<f64> {
45 if let Self::Number(x) = self {
46 Some(*x)
47 } else {
48 None
49 }
50 }
51 pub fn expect_number(&self) -> Result<f64, Val> {
52 if let Some(x) = self.number() {
53 Ok(x)
54 } else {
55 Err(Val::String("Expected number".to_owned().into()))
56 }
57 }
58 pub fn list(&self) -> Option<&List> {
59 if let Self::List(x) = self {
60 Some(x)
61 } else {
62 None
63 }
64 }
65 pub fn expect_list(&self) -> Result<&List, Val> {
66 if let Some(x) = self.list() {
67 Ok(x)
68 } else {
69 Err(Val::String("Expected list".to_owned().into()))
70 }
71 }
72 pub fn func(&self) -> Option<&Rc<Code>> {
73 if let Self::Func(x) = self {
74 Some(&x.0)
75 } else {
76 None
77 }
78 }
79 pub fn expect_func(&self) -> Result<&Rc<Code>, Val> {
80 if let Some(x) = self.func() {
81 Ok(x)
82 } else {
83 Err(Val::String("Expected func".to_owned().into()))
84 }
85 }
86 pub fn genobj(&self) -> Option<&GenObjPtr> {
87 if let Self::GenObj(x) = self {
88 Some(x)
89 } else {
90 None
91 }
92 }
93 pub fn expect_genobj(&self) -> Result<&GenObjPtr, Val> {
94 if let Some(x) = self.genobj() {
95 Ok(x)
96 } else {
97 Err(Val::String("Expected generator object".to_owned().into()))
98 }
99 }
100 pub fn lt(&self, other: &Self) -> Result<bool, Val> {
101 match (self, other) {
102 (Self::Number(a), Self::Number(b)) => Ok(a < b),
103 (Self::String(a), Self::String(b)) => Ok(a < b),
104 (Self::List(a), Self::List(b)) => Ok({
105 let a = a.borrow();
106 let b = b.borrow();
107 for (x, y) in a.iter().zip(b.iter()) {
108 if x.lt(y)? {
109 return Ok(true);
110 } else if y.lt(x)? {
111 return Ok(false);
112 }
113 }
114 a.len() < b.len()
115 }),
116 _ => Err(Val::String(
117 format!("{} and {} are not comparable", self, other).into(),
118 )),
119 }
120 }
121}
122
123impl From<bool> for Val {
124 fn from(x: bool) -> Self {
125 Self::Bool(x)
126 }
127}
128
129impl From<&str> for Val {
130 fn from(s: &str) -> Self {
131 Self::String(s.into())
132 }
133}
134
135impl From<String> for Val {
136 fn from(s: String) -> Self {
137 Self::String(s.into())
138 }
139}
140
141impl From<&RcStr> for Val {
142 fn from(s: &RcStr) -> Self {
143 Self::String(s.clone())
144 }
145}
146
147impl From<RcStr> for Val {
148 fn from(s: RcStr) -> Self {
149 Self::String(s.into())
150 }
151}
152
153impl From<Vec<Val>> for Val {
154 fn from(vec: Vec<Val>) -> Self {
155 Self::List(
156 List {
157 vec: RefCell::new(vec),
158 }
159 .into(),
160 )
161 }
162}
163
164impl fmt::Debug for Val {
165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166 match self {
167 Val::Invalid => write!(f, "<invalid>"),
168 Val::Nil => write!(f, "nil"),
169 Val::Bool(x) => write!(f, "{}", if *x { "true" } else { "false" }),
170 Val::Number(x) => write!(f, "{}", x),
171 Val::String(x) => {
172 write!(f, "\"")?;
173 for c in x.chars() {
174 match c {
175 '\\' => write!(f, "\\\\")?,
176 '\"' => write!(f, "\\\"")?,
177 '\'' => write!(f, "\\\'")?,
178 '\n' => write!(f, "\\\n")?,
179 '\r' => write!(f, "\\\r")?,
180 '\t' => write!(f, "\\\t")?,
181 _ => write!(f, "{}", c)?,
182 }
183 }
184 write!(f, "\"")
185 }
186 Val::List(xs) => {
187 write!(f, "[")?;
188 for (i, x) in xs.borrow().iter().enumerate() {
189 if i > 0 {
190 write!(f, ", ")?;
191 }
192 write!(f, "{:?}", x)?;
193 }
194 write!(f, "]")
195 }
196 Val::Func(func) => write!(f, "<func {}>", func.0.name()),
197 Val::GenObj(_) => write!(f, "<genobj>"),
198 }
199 }
200}
201
202impl fmt::Display for Val {
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204 match self {
205 Val::String(x) => write!(f, "{}", x),
206 _ => write!(f, "{:?}", self),
207 }
208 }
209}
210
211pub struct List {
215 vec: RefCell<Vec<Val>>,
216}
217
218impl List {
219 pub fn borrow(&self) -> Ref<Vec<Val>> {
220 self.vec.borrow()
221 }
222 pub fn borrow_mut(&self) -> RefMut<Vec<Val>> {
223 self.vec.borrow_mut()
224 }
225}
226
227impl cmp::PartialEq for List {
228 fn eq(&self, other: &Self) -> bool {
229 self.vec.eq(&other.vec)
230 }
231}
232
233impl cmp::Eq for List {}
234
235#[derive(Clone)]
236pub struct Func(pub Rc<Code>);
237
238impl cmp::PartialEq for Func {
239 fn eq(&self, other: &Self) -> bool {
240 Rc::as_ptr(&self.0) == Rc::as_ptr(&other.0)
241 }
242}
243
244impl cmp::Eq for Func {}
245
246#[derive(Clone)]
247pub struct GenObjPtr(pub Rc<RefCell<GenObj>>);
248
249impl cmp::PartialEq for GenObjPtr {
250 fn eq(&self, other: &Self) -> bool {
251 Rc::as_ptr(&self.0) == Rc::as_ptr(&other.0)
252 }
253}
254
255impl cmp::Eq for GenObjPtr {}
256
257#[cfg(test)]
258mod tests {
259 use super::*;
260
261 #[test]
262 fn val_size() {
263 assert_eq!(std::mem::size_of::<Val>(), 2 * std::mem::size_of::<usize>());
264 }
265}