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