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