1use anyhow::{Result, anyhow};
2use indexmap::IndexMap;
3use serde::{Deserialize, Serialize};
4use std::{cell::RefCell, collections::HashMap, fmt::Display, rc::Rc};
5
6use crate::{
7 ast::Expr,
8 functions::BuiltInFunction,
9 heap::{
10 Heap, HeapPointer, HeapValue, IterablePointer, LambdaPointer, ListPointer, RecordPointer,
11 StringPointer,
12 },
13};
14
15#[derive(Debug)]
16pub enum FunctionArity {
17 Exact(usize),
18 AtLeast(usize),
19 Between(usize, usize),
20}
21
22impl FunctionArity {
23 pub fn can_accept(&self, n: usize) -> bool {
24 match self {
25 FunctionArity::Exact(expected) => n == *expected,
26 FunctionArity::Between(min, max) => n >= *min && n <= *max,
27 FunctionArity::AtLeast(min) => n >= *min,
28 }
29 }
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, PartialOrd)]
33pub enum LambdaArg {
34 Required(String),
35 Optional(String),
36 Rest(String),
37}
38
39impl LambdaArg {
40 pub fn get_name(&self) -> &str {
41 match self {
42 LambdaArg::Required(name) => name,
43 LambdaArg::Optional(name) => name,
44 LambdaArg::Rest(name) => name,
45 }
46 }
47
48 pub fn is_required(&self) -> bool {
49 matches!(self, LambdaArg::Required(_))
50 }
51
52 pub fn is_optional(&self) -> bool {
53 matches!(self, LambdaArg::Optional(_))
54 }
55
56 pub fn is_rest(&self) -> bool {
57 matches!(self, LambdaArg::Rest(_))
58 }
59
60 pub fn as_required(&self) -> Result<&str> {
61 match self {
62 LambdaArg::Required(name) => Ok(name),
63 _ => Err(anyhow!(
64 "expected a required argument, but got a {} one",
65 self.get_name()
66 )),
67 }
68 }
69
70 pub fn as_optional(&self) -> Result<&str> {
71 match self {
72 LambdaArg::Optional(name) => Ok(name),
73 _ => Err(anyhow!(
74 "expected an optional argument, but got a {} one",
75 self.get_name()
76 )),
77 }
78 }
79
80 pub fn as_rest(&self) -> Result<&str> {
81 match self {
82 LambdaArg::Rest(name) => Ok(name),
83 _ => Err(anyhow!(
84 "expected a rest argument, but got a {} one",
85 self.get_name()
86 )),
87 }
88 }
89}
90
91impl Display for LambdaArg {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 match self {
94 LambdaArg::Required(name) => write!(f, "{}", name),
95 LambdaArg::Optional(name) => write!(f, "{}?", name),
96 LambdaArg::Rest(name) => write!(f, "...{}", name),
97 }
98 }
99}
100
101#[derive(Debug, Clone, PartialEq)]
102pub struct LambdaDef {
103 pub name: Option<String>,
104 pub args: Vec<LambdaArg>,
105 pub body: Expr,
106 pub scope: HashMap<String, Value>,
107}
108
109impl LambdaDef {
110 pub fn set_name(&mut self, name: String, _value: Value) {
111 self.name = Some(name.clone());
112 }
113
114 pub fn get_arity(&self) -> FunctionArity {
115 let has_rest = self.args.iter().any(|arg| arg.is_rest());
116 let min = self.args.iter().filter(|arg| arg.is_required()).count();
117 let max = self.args.len();
118
119 if has_rest {
120 FunctionArity::AtLeast(min)
121 } else if min == max {
122 FunctionArity::Exact(min)
123 } else {
124 FunctionArity::Between(min, max)
125 }
126 }
127}
128
129impl PartialOrd for LambdaDef {
130 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
131 if self.args > other.args {
132 Some(std::cmp::Ordering::Greater)
133 } else if self.args < other.args {
134 Some(std::cmp::Ordering::Less)
135 } else {
136 Some(std::cmp::Ordering::Equal)
137 }
138 }
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
142pub struct SerializableLambdaDef {
143 pub name: Option<String>,
144 pub args: Vec<LambdaArg>,
145 pub body: String,
146 pub scope: Option<IndexMap<String, SerializableValue>>,
147}
148
149pub struct WithHeap<'h, T> {
150 pub value: &'h T,
151 pub heap: Rc<RefCell<Heap>>,
152}
153
154#[derive(Debug, Copy, Clone, PartialEq)]
155pub enum ReifiedIterableValue<'h> {
156 List(&'h Vec<Value>),
157 String(&'h String),
158 Record(&'h IndexMap<String, Value>),
159}
160
161#[derive(Debug, Clone, PartialEq)]
162pub enum ReifiedIterableValueType {
163 List,
164 String,
165 Record,
166}
167
168impl<'h> ReifiedIterableValue<'h> {
169 pub fn with_heap(&'h self, heap: Rc<RefCell<Heap>>) -> WithHeap<'h, ReifiedIterableValue<'h>> {
170 WithHeap { value: self, heap }
171 }
172
173 pub fn get_type(&self) -> ReifiedIterableValueType {
174 match self {
175 ReifiedIterableValue::List(_) => ReifiedIterableValueType::List,
176 ReifiedIterableValue::String(_) => ReifiedIterableValueType::String,
177 ReifiedIterableValue::Record(_) => ReifiedIterableValueType::Record,
178 }
179 }
180}
181
182impl<'h> IntoIterator for WithHeap<'h, ReifiedIterableValue<'h>> {
183 type Item = Value;
184 type IntoIter = std::vec::IntoIter<Self::Item>;
185
186 fn into_iter(self) -> Self::IntoIter {
187 match self.value {
188 ReifiedIterableValue::List(l) => (*l).clone().into_iter(),
190 ReifiedIterableValue::String(s) => s
192 .chars()
193 .map(|c| self.heap.borrow_mut().insert_string(c.to_string()))
194 .collect::<Vec<Value>>()
195 .into_iter(),
196 ReifiedIterableValue::Record(r) => r
198 .into_iter()
199 .map(|(k, v)| {
200 let list = vec![self.heap.borrow_mut().insert_string(k.to_string()), *v];
201 self.heap.borrow_mut().insert_list(list)
202 })
203 .collect::<Vec<Value>>()
204 .into_iter(),
205 }
206 }
207}
208
209impl<'h> IntoIterator for WithHeap<'h, ReifiedValue<'h>> {
210 type Item = Value;
211 type IntoIter = std::vec::IntoIter<Self::Item>;
212
213 fn into_iter(self) -> Self::IntoIter {
214 match self.value {
215 ReifiedValue::Spread(iterable, _) => iterable.with_heap(self.heap).into_iter(),
216 _ => vec![(*self.value).into()].into_iter(),
217 }
218 }
219}
220
221#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
222pub enum ValueType {
223 Number,
224 List,
225 Spread,
226 Bool,
227 Lambda,
228 BuiltIn,
229 String,
230 Record,
231 Null,
232}
233
234impl Display for ValueType {
235 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
236 match self {
237 ValueType::Number => write!(f, "number"),
238 ValueType::List => write!(f, "list"),
239 ValueType::Spread => write!(f, "spread"),
240 ValueType::Bool => write!(f, "boolean"),
241 ValueType::Lambda => write!(f, "function"),
242 ValueType::BuiltIn => write!(f, "built-in function"),
243 ValueType::String => write!(f, "string"),
244 ValueType::Record => write!(f, "record"),
245 ValueType::Null => write!(f, "null"),
246 }
247 }
248}
249
250#[derive(Debug, Copy, Clone, PartialEq)]
252pub enum ReifiedValue<'h> {
253 Number(f64),
255 Bool(bool),
257 Null,
259 List(&'h Vec<Value>, ListPointer),
261 String(&'h str, StringPointer),
263 Record(&'h IndexMap<String, Value>, RecordPointer),
265 Lambda(&'h LambdaDef, LambdaPointer),
267 Spread(ReifiedIterableValue<'h>, IterablePointer),
269 BuiltIn(BuiltInFunction),
271}
272
273impl<'h> ReifiedValue<'h> {
274 pub fn with_heap(&'h self, heap: Rc<RefCell<Heap>>) -> WithHeap<'h, ReifiedValue<'h>> {
275 WithHeap { value: self, heap }
276 }
277}
278
279impl From<ReifiedValue<'_>> for Value {
280 fn from(value: ReifiedValue) -> Self {
281 match value {
282 ReifiedValue::Number(n) => Value::Number(n),
283 ReifiedValue::Bool(b) => Value::Bool(b),
284 ReifiedValue::Null => Value::Null,
285 ReifiedValue::List(_, p) => Value::List(p),
286 ReifiedValue::String(_, p) => Value::String(p),
287 ReifiedValue::Record(_, p) => Value::Record(p),
288 ReifiedValue::Lambda(_, p) => Value::Lambda(p),
289 ReifiedValue::Spread(_, p) => Value::Spread(p),
290 ReifiedValue::BuiltIn(id) => Value::BuiltIn(id),
291 }
292 }
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
296pub enum SerializableIterableValue {
297 List(Vec<SerializableValue>),
298 String(String),
299 Record(IndexMap<String, SerializableValue>),
300}
301
302#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
303pub enum SerializableValue {
304 Number(f64),
305 Bool(bool),
306 Null,
307 List(Vec<SerializableValue>),
308 String(String),
309 Record(IndexMap<String, SerializableValue>),
310 Lambda(SerializableLambdaDef),
311 BuiltIn(String),
312}
313
314impl SerializableValue {
315 pub fn from_json(value: &serde_json::Value) -> SerializableValue {
317 match value {
318 serde_json::Value::Number(n) => SerializableValue::Number(n.as_f64().unwrap_or(0.0)),
319 serde_json::Value::Bool(b) => SerializableValue::Bool(*b),
320 serde_json::Value::Null => SerializableValue::Null,
321 serde_json::Value::String(s) => SerializableValue::String(s.clone()),
322 serde_json::Value::Array(arr) => {
323 SerializableValue::List(arr.iter().map(Self::from_json).collect())
324 }
325 serde_json::Value::Object(obj) => {
326 if let Some(func_value) = obj.get("__blots_function")
328 && let Some(func_str) = func_value.as_str() {
329 if crate::functions::BuiltInFunction::from_ident(func_str).is_some() {
331 return SerializableValue::BuiltIn(func_str.to_string());
332 }
333
334 if let Ok(lambda_def) = Self::parse_function_source(func_str) {
337 return SerializableValue::Lambda(lambda_def);
338 }
339 }
340
341 let map: IndexMap<String, SerializableValue> = obj
343 .iter()
344 .map(|(k, v)| (k.clone(), Self::from_json(v)))
345 .collect();
346 SerializableValue::Record(map)
347 }
348 }
349 }
350
351 fn parse_function_source(source: &str) -> Result<SerializableLambdaDef> {
353 use crate::expressions::pairs_to_expr;
354 use crate::parser::get_pairs;
355
356 let pairs = get_pairs(source)?;
358
359 for pair in pairs {
361 if let crate::parser::Rule::statement = pair.as_rule()
362 && let Some(inner_pair) = pair.into_inner().next()
363 && let crate::parser::Rule::expression = inner_pair.as_rule() {
364 let expr = pairs_to_expr(inner_pair.into_inner())?;
366
367 if let crate::ast::Expr::Lambda { args, body } = expr {
369 return Ok(SerializableLambdaDef {
372 name: None,
373 args,
374 body: crate::ast_to_source::expr_to_source(&body),
375 scope: None, });
377 }
378 }
379 }
380
381 Err(anyhow!("Failed to parse function source: {}", source))
382 }
383
384 pub fn to_json(&self) -> serde_json::Value {
386 match self {
387 SerializableValue::Number(n) => serde_json::Value::Number(
388 serde_json::Number::from_f64(*n).unwrap_or_else(|| serde_json::Number::from(0)),
389 ),
390 SerializableValue::Bool(b) => serde_json::Value::Bool(*b),
391 SerializableValue::Null => serde_json::Value::Null,
392 SerializableValue::String(s) => serde_json::Value::String(s.clone()),
393 SerializableValue::List(items) => {
394 serde_json::Value::Array(items.iter().map(|v| v.to_json()).collect())
395 }
396 SerializableValue::Record(fields) => {
397 let map: serde_json::Map<String, serde_json::Value> = fields
398 .iter()
399 .map(|(k, v)| (k.clone(), v.to_json()))
400 .collect();
401 serde_json::Value::Object(map)
402 }
403 SerializableValue::Lambda(lambda_def) => {
404 let mut map = serde_json::Map::new();
407
408 let args_str: Vec<String> = lambda_def
410 .args
411 .iter()
412 .map(|arg| match arg {
413 LambdaArg::Required(name) => name.clone(),
414 LambdaArg::Optional(name) => format!("{}?", name),
415 LambdaArg::Rest(name) => format!("...{}", name),
416 })
417 .collect();
418
419 let function_source = format!("({}) => {}", args_str.join(", "), lambda_def.body);
420
421 map.insert(
422 "__blots_function".to_string(),
423 serde_json::Value::String(function_source),
424 );
425 serde_json::Value::Object(map)
426 }
427 SerializableValue::BuiltIn(name) => {
428 let mut map = serde_json::Map::new();
430 map.insert(
431 "__blots_function".to_string(),
432 serde_json::Value::String(name.clone()),
433 );
434 serde_json::Value::Object(map)
435 }
436 }
437 }
438
439 pub fn from_value(value: &Value, heap: &Heap) -> Result<SerializableValue> {
440 match value {
441 Value::Number(n) => Ok(SerializableValue::Number(*n)),
442 Value::Bool(b) => Ok(SerializableValue::Bool(*b)),
443 Value::Null => Ok(SerializableValue::Null),
444 Value::List(p) => {
445 let list = p.reify(heap).as_list()?;
446 let serialized_list = list
447 .iter()
448 .map(|v| SerializableValue::from_value(v, heap))
449 .collect::<Result<Vec<SerializableValue>>>()?;
450 Ok(SerializableValue::List(serialized_list))
451 }
452 Value::String(p) => {
453 let string = p.reify(heap).as_string()?;
454 Ok(SerializableValue::String(string.to_string()))
455 }
456 Value::Record(p) => {
457 let record = p.reify(heap).as_record()?;
458 let serialized_record = record
459 .iter()
460 .map(|(k, v)| Ok((k.to_string(), SerializableValue::from_value(v, heap)?)))
461 .collect::<Result<IndexMap<String, SerializableValue>>>()?;
462 Ok(SerializableValue::Record(serialized_record))
463 }
464 Value::Lambda(p) => {
465 let lambda = p.reify(heap).as_lambda()?;
466
467 let serializable_scope: IndexMap<String, SerializableValue> = lambda
469 .scope
470 .clone()
471 .into_iter()
472 .map(|(k, v)| SerializableValue::from_value(&v, heap).map(|sv| (k, sv)))
473 .collect::<Result<IndexMap<String, SerializableValue>>>()?;
474
475 let body_with_inlined_scope = crate::ast_to_source::expr_to_source_with_scope(
477 &lambda.body,
478 &serializable_scope,
479 );
480
481 Ok(SerializableValue::Lambda(SerializableLambdaDef {
482 name: lambda.name.clone(),
483 args: lambda.args.clone(),
484 body: body_with_inlined_scope,
485 scope: Some(serializable_scope),
486 }))
487 }
488 Value::BuiltIn(built_in) => Ok(SerializableValue::BuiltIn(built_in.name().to_string())),
489 Value::Spread(_) => Err(anyhow!("cannot serialize a spread value")),
490 }
491 }
492
493 pub fn to_value(&self, heap: &mut Heap) -> Result<Value> {
494 match self {
495 SerializableValue::Number(n) => Ok(Value::Number(*n)),
496 SerializableValue::Bool(b) => Ok(Value::Bool(*b)),
497 SerializableValue::Null => Ok(Value::Null),
498 SerializableValue::List(list) => {
499 let deserialized_list = list
500 .iter()
501 .map(|v| SerializableValue::to_value(v, heap))
502 .collect::<Result<Vec<Value>>>()?;
503
504 Ok(heap.insert_list(deserialized_list))
505 }
506 SerializableValue::String(s) => Ok(heap.insert_string(s.to_string())),
507 SerializableValue::Record(record) => {
508 let deserialized_record = record
509 .iter()
510 .map(|(k, v)| Ok((k.to_string(), SerializableValue::to_value(v, heap)?)))
511 .collect::<Result<IndexMap<String, Value>>>()?;
512 Ok(heap.insert_record(deserialized_record))
513 }
514 SerializableValue::Lambda(s_lambda) => {
515 let scope = if let Some(scope) = s_lambda.scope.clone() {
516 scope
517 .iter()
518 .map(|(k, v)| Ok((k.to_string(), SerializableValue::to_value(v, heap)?)))
519 .collect::<Result<HashMap<String, Value>>>()?
520 } else {
521 HashMap::new()
522 };
523
524 let body_ast = crate::expressions::pairs_to_expr(
527 crate::parser::get_pairs(&s_lambda.body)?
528 .next()
529 .unwrap()
530 .into_inner(),
531 )?;
532
533 let lambda = LambdaDef {
534 name: s_lambda.name.clone(),
535 args: s_lambda.args.clone(),
536 body: body_ast,
537 scope,
538 };
539
540 Ok(heap.insert_lambda(lambda))
541 }
542 SerializableValue::BuiltIn(ident) => BuiltInFunction::from_ident(ident)
543 .ok_or(anyhow!("built-in function with ident {} not found", ident))
544 .map(Value::BuiltIn),
545 }
546 }
547}
548
549#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
550pub enum PrimitiveValue {
551 Number(f64),
552 Bool(bool),
553 Null,
554}
555
556impl From<PrimitiveValue> for Value {
557 fn from(val: PrimitiveValue) -> Self {
558 match val {
559 PrimitiveValue::Number(n) => Value::Number(n),
560 PrimitiveValue::Bool(b) => Value::Bool(b),
561 PrimitiveValue::Null => Value::Null,
562 }
563 }
564}
565
566impl From<PrimitiveValue> for SerializableValue {
567 fn from(val: PrimitiveValue) -> Self {
568 match val {
569 PrimitiveValue::Number(n) => SerializableValue::Number(n),
570 PrimitiveValue::Bool(b) => SerializableValue::Bool(b),
571 PrimitiveValue::Null => SerializableValue::Null,
572 }
573 }
574}
575
576#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
577pub enum Value {
578 Number(f64),
580 Bool(bool),
582 Null,
584 List(ListPointer),
586 String(StringPointer),
588 Record(RecordPointer),
590 Lambda(LambdaPointer),
592 Spread(IterablePointer),
594 BuiltIn(BuiltInFunction),
596}
597
598impl Value {
599 pub fn equals(&self, other: &Value, heap: &Heap) -> Result<bool> {
601 match (self, other) {
602 (Value::Number(a), Value::Number(b)) => Ok(a == b),
604 (Value::Bool(a), Value::Bool(b)) => Ok(a == b),
605 (Value::Null, Value::Null) => Ok(true),
606
607 (Value::String(a_ptr), Value::String(b_ptr)) => {
609 let a_str = a_ptr.reify(heap).as_string()?;
610 let b_str = b_ptr.reify(heap).as_string()?;
611 Ok(a_str == b_str)
612 }
613
614 (Value::List(a_ptr), Value::List(b_ptr)) => {
616 let a_list = a_ptr.reify(heap).as_list()?;
617 let b_list = b_ptr.reify(heap).as_list()?;
618
619 if a_list.len() != b_list.len() {
620 return Ok(false);
621 }
622
623 for (a_elem, b_elem) in a_list.iter().zip(b_list.iter()) {
624 if !a_elem.equals(b_elem, heap)? {
625 return Ok(false);
626 }
627 }
628 Ok(true)
629 }
630
631 (Value::Record(a_ptr), Value::Record(b_ptr)) => {
633 let a_record = a_ptr.reify(heap).as_record()?;
634 let b_record = b_ptr.reify(heap).as_record()?;
635
636 if a_record.len() != b_record.len() {
637 return Ok(false);
638 }
639
640 for (key, a_value) in a_record.iter() {
641 match b_record.get(key) {
642 Some(b_value) => {
643 if !a_value.equals(b_value, heap)? {
644 return Ok(false);
645 }
646 }
647 None => return Ok(false),
648 }
649 }
650 Ok(true)
651 }
652
653 (Value::Lambda(a_ptr), Value::Lambda(b_ptr)) => {
655 let a_lambda = a_ptr.reify(heap).as_lambda()?;
656 let b_lambda = b_ptr.reify(heap).as_lambda()?;
657
658 if a_lambda.args != b_lambda.args {
660 return Ok(false);
661 }
662
663 if a_lambda.body != b_lambda.body {
665 return Ok(false);
666 }
667
668 Ok(true)
672 }
673
674 (Value::BuiltIn(a), Value::BuiltIn(b)) => Ok(a == b),
676
677 (Value::Spread(a_ptr), Value::Spread(b_ptr)) => match (a_ptr, b_ptr) {
679 (IterablePointer::List(a), IterablePointer::List(b)) => {
680 Value::List(*a).equals(&Value::List(*b), heap)
681 }
682 (IterablePointer::String(a), IterablePointer::String(b)) => {
683 Value::String(*a).equals(&Value::String(*b), heap)
684 }
685 (IterablePointer::Record(a), IterablePointer::Record(b)) => {
686 Value::Record(*a).equals(&Value::Record(*b), heap)
687 }
688 _ => Ok(false),
689 },
690
691 _ => Ok(false),
693 }
694 }
695
696 pub fn compare(&self, other: &Value, heap: &Heap) -> Result<Option<std::cmp::Ordering>> {
698 match (self, other) {
699 (Value::Number(a), Value::Number(b)) => Ok(a.partial_cmp(b)),
701
702 (Value::Bool(a), Value::Bool(b)) => Ok(a.partial_cmp(b)),
704
705 (Value::String(a_ptr), Value::String(b_ptr)) => {
707 let a_str = a_ptr.reify(heap).as_string()?;
708 let b_str = b_ptr.reify(heap).as_string()?;
709 Ok(a_str.partial_cmp(b_str))
710 }
711
712 (Value::List(a_ptr), Value::List(b_ptr)) => {
714 let a_list = a_ptr.reify(heap).as_list()?;
715 let b_list = b_ptr.reify(heap).as_list()?;
716
717 for (a_elem, b_elem) in a_list.iter().zip(b_list.iter()) {
718 match a_elem.compare(b_elem, heap)? {
719 Some(std::cmp::Ordering::Equal) => continue,
720 other => return Ok(other),
721 }
722 }
723
724 Ok(a_list.len().partial_cmp(&b_list.len()))
726 }
727
728 _ => Ok(None),
730 }
731 }
732
733 pub fn get_type(&self) -> ValueType {
734 match self {
735 Value::Number(_) => ValueType::Number,
736 Value::List(_) => ValueType::List,
737 Value::Spread(_) => ValueType::Spread,
738 Value::Bool(_) => ValueType::Bool,
739 Value::Lambda(_) => ValueType::Lambda,
740 Value::String(_) => ValueType::String,
741 Value::Null => ValueType::Null,
742 Value::BuiltIn(_) => ValueType::BuiltIn,
743 Value::Record(_) => ValueType::Record,
744 }
745 }
746
747 pub fn is_number(&self) -> bool {
748 matches!(self, Value::Number(_))
749 }
750
751 pub fn is_list(&self) -> bool {
752 matches!(self, Value::List(_))
753 }
754
755 pub fn is_spread(&self) -> bool {
756 matches!(self, Value::Spread(_))
757 }
758
759 pub fn is_bool(&self) -> bool {
760 matches!(self, Value::Bool(_))
761 }
762
763 pub fn is_lambda(&self) -> bool {
764 matches!(self, Value::Lambda(_))
765 }
766
767 pub fn is_string(&self) -> bool {
768 matches!(self, Value::String(_))
769 }
770
771 pub fn is_null(&self) -> bool {
772 matches!(self, Value::Null)
773 }
774
775 pub fn is_built_in(&self) -> bool {
776 matches!(self, Value::BuiltIn(_))
777 }
778
779 pub fn is_callable(&self) -> bool {
780 matches!(self, Value::BuiltIn(_) | Value::Lambda(_))
781 }
782
783 pub fn as_number(&self) -> Result<f64> {
784 match self {
785 Value::Number(n) => Ok(*n),
786 _ => Err(anyhow!("expected a number, but got a {}", self.get_type())),
787 }
788 }
789
790 pub fn as_list<'h>(&self, heap: &'h Heap) -> Result<&'h Vec<Value>> {
791 match self {
792 Value::List(l) => l.reify(heap).as_list(),
793 _ => Err(anyhow!("expected a list, but got a {}", self.get_type())),
794 }
795 }
796
797 pub fn as_spread<'h>(&self, heap: &'h Heap) -> Result<&'h HeapValue> {
798 match self {
799 Value::Spread(v) => Ok(v.reify(heap)),
800 _ => Err(anyhow!("expected a spread, but got a {}", self.get_type())),
801 }
802 }
803
804 pub fn as_bool(&self) -> Result<bool> {
805 match self {
806 Value::Bool(b) => Ok(*b),
807 _ => Err(anyhow!("expected a boolean, but got a {}", self.get_type())),
808 }
809 }
810
811 pub fn as_lambda<'h>(&self, heap: &'h Heap) -> Result<&'h LambdaDef> {
812 match self {
813 Value::Lambda(l) => l.reify(heap).as_lambda(),
814 _ => Err(anyhow!("expected a lambda, but got a {}", self.get_type())),
815 }
816 }
817
818 pub fn as_string<'h>(&self, heap: &'h Heap) -> Result<&'h str> {
819 match self {
820 Value::String(p) => p.reify(heap).as_string(),
821 _ => Err(anyhow!("expected a string, but got a {}", self.get_type())),
822 }
823 }
824
825 pub fn as_null(&self) -> Result<()> {
826 match self {
827 Value::Null => Ok(()),
828 _ => Err(anyhow!("expected a null, but got a {}", self.get_type())),
829 }
830 }
831
832 pub fn as_built_in(&self) -> Result<&str> {
833 match self {
834 Value::BuiltIn(built_in) => Ok(built_in.name()),
835 _ => Err(anyhow!(
836 "expected a built-in function, but got a {}",
837 self.get_type()
838 )),
839 }
840 }
841
842 pub fn as_record<'h>(&self, heap: &'h Heap) -> Result<&'h IndexMap<String, Value>> {
843 match self {
844 Value::Record(r) => r.reify(heap).as_record(),
845 _ => Err(anyhow!("expected a record, but got a {}", self.get_type())),
846 }
847 }
848
849 pub fn as_list_pointer(&self) -> Result<ListPointer> {
850 match self {
851 Value::List(p) => Ok(*p),
852 _ => Err(anyhow!("expected a list, but got a {}", self.get_type())),
853 }
854 }
855
856 pub fn as_string_pointer(&self) -> Result<StringPointer> {
857 match self {
858 Value::String(p) => Ok(*p),
859 _ => Err(anyhow!("expected a string, but got a {}", self.get_type())),
860 }
861 }
862
863 pub fn as_record_pointer(&self) -> Result<RecordPointer> {
864 match self {
865 Value::Record(p) => Ok(*p),
866 _ => Err(anyhow!("expected a record, but got a {}", self.get_type())),
867 }
868 }
869
870 pub fn as_lambda_pointer(&self) -> Result<LambdaPointer> {
871 match self {
872 Value::Lambda(p) => Ok(*p),
873 _ => Err(anyhow!("expected a lambda, but got a {}", self.get_type())),
874 }
875 }
876
877 pub fn as_iterable_pointer(&self) -> Result<IterablePointer> {
878 match self {
879 Value::Spread(p) => Ok(*p),
880 _ => Err(anyhow!("expected a spread, but got a {}", self.get_type())),
881 }
882 }
883
884 pub fn to_serializable_value(&self, heap: &Heap) -> Result<SerializableValue> {
885 SerializableValue::from_value(self, heap)
886 }
887
888 pub fn reify<'h>(&self, heap: &'h Heap) -> Result<ReifiedValue<'h>> {
889 match self {
890 Value::Number(n) => Ok(ReifiedValue::Number(*n)),
891 Value::List(p) => Ok(ReifiedValue::List(p.reify(heap).as_list()?, *p)),
892 Value::Spread(p) => Ok(ReifiedValue::Spread(p.reify(heap).as_iterable()?, *p)),
893 Value::Bool(b) => Ok(ReifiedValue::Bool(*b)),
894 Value::Lambda(p) => Ok(ReifiedValue::Lambda(p.reify(heap).as_lambda()?, *p)),
895 Value::String(p) => Ok(ReifiedValue::String(p.reify(heap).as_string()?, *p)),
896 Value::Null => Ok(ReifiedValue::Null),
897 Value::BuiltIn(id) => Ok(ReifiedValue::BuiltIn(*id)),
898 Value::Record(p) => Ok(ReifiedValue::Record(p.reify(heap).as_record()?, *p)),
899 }
900 }
901
902 pub fn stringify_internal(&self, heap: &Heap) -> String {
906 self.stringify(heap, false)
907 }
908
909 pub fn stringify_external(&self, heap: &Heap) -> String {
910 self.stringify(heap, true)
911 }
912
913 fn stringify(&self, heap: &Heap, wrap_strings: bool) -> String {
914 match self {
915 Value::String(p) => p
916 .reify(heap)
917 .as_string()
918 .map(|s| {
919 if wrap_strings {
920 format!("\"{}\"", s)
921 } else {
922 s.to_string()
923 }
924 })
925 .unwrap(),
926 Value::List(p) => {
927 let mut result = String::from("[");
928 let list = p.reify(heap).as_list().unwrap();
929
930 for (i, value) in list.iter().enumerate() {
931 result.push_str(&value.stringify(heap, wrap_strings));
932 if i < list.len() - 1 {
933 result.push_str(", ");
934 }
935 }
936 result.push(']');
937 result
938 }
939 Value::Record(p) => {
940 let mut result = String::from("{");
941 let record = p.reify(heap).as_record().unwrap();
942
943 for (i, (key, value)) in record.iter().enumerate() {
944 result.push_str(&format!("{}: {}", key, value.stringify(heap, wrap_strings)));
945 if i < record.len() - 1 {
946 result.push_str(", ");
947 }
948 }
949 result.push('}');
950 result
951 }
952 Value::Lambda(p) => {
953 let lambda = p.reify(heap).as_lambda().unwrap();
954 let mut result = String::from("(");
955 for (i, arg) in lambda.args.iter().enumerate() {
956 result.push_str(&arg.to_string());
957 if i < lambda.args.len() - 1 {
958 result.push_str(", ");
959 }
960 }
961 result.push_str(") => ");
962 result.push_str(&crate::ast_to_source::expr_to_source(&lambda.body));
963 result
964 }
965 Value::BuiltIn(built_in) => {
966 format!("{} (built-in)", built_in.name())
967 }
968 Value::Spread(p) => match p {
969 IterablePointer::List(l) => {
970 let list = l.reify(heap).as_list().unwrap();
971 let mut result = String::from("...");
972 result.push_str(
973 &list
974 .iter()
975 .map(|v| v.stringify(heap, wrap_strings))
976 .collect::<String>(),
977 );
978 result
979 }
980 IterablePointer::String(s) => {
981 let string = s.reify(heap).as_string().unwrap();
982 format!("...{}", string)
983 }
984 IterablePointer::Record(r) => {
985 let record = r.reify(heap).as_record().unwrap();
986 let mut result = String::from("...");
987 result.push('{');
988 for (i, (key, value)) in record.iter().enumerate() {
989 result.push_str(&format!(
990 "{}: {}",
991 key,
992 value.stringify(heap, wrap_strings)
993 ));
994 if i < record.len() - 1 {
995 result.push_str(", ");
996 }
997 }
998 result.push('}');
999 result
1000 }
1001 },
1002 Value::Bool(_) | Value::Number(_) | Value::Null => format!("{}", self),
1003 }
1004 }
1005}
1006
1007impl Display for Value {
1008 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1009 match self {
1010 Value::Number(n) => write!(f, "{}", n),
1011 Value::List(p) => write!(f, "{}", p),
1012 Value::Spread(p) => write!(f, "...{}", p),
1013 Value::Bool(b) => write!(f, "{}", b),
1014 Value::Lambda(p) => write!(f, "{}", p),
1015 Value::String(p) => write!(f, "{}", p),
1016 Value::Null => write!(f, "null"),
1017 Value::BuiltIn(built_in) => write!(f, "{} (built-in)", built_in.name()),
1018 Value::Record(p) => write!(f, "{}", p),
1019 }
1020 }
1021}