seraphine_core/
eval.rs

1use std::{
2    cell::RefCell,
3    collections::{BTreeMap, BTreeSet},
4    fmt::{Debug, Display},
5    io::{stderr, stdin, stdout, BufRead, BufReader, Read, Write},
6    rc::Rc,
7};
8
9use crate::{
10    error::{EvalError, SeraphineError},
11    parser::{parse, Ast},
12    tokenizer::tokenize,
13};
14
15// TODO: Find out how to increase this limit, since the stack of the main thread can overflow if
16// this is too large.
17const CALL_STACK_SIZE_LIMIT: usize = 100;
18
19#[derive(Debug, Clone)]
20pub enum ControlFlow {
21    Return(Value),
22    Continue,
23    Break,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum Type {
28    Null,
29    Number,
30    Bool,
31    String,
32    Function,
33    List,
34    Object,
35}
36
37impl Display for Type {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        use Type::*;
40        match self {
41            Null => write!(f, "null"),
42            Number => write!(f, "number"),
43            Bool => write!(f, "bool"),
44            String => write!(f, "string"),
45            Function => write!(f, "function"),
46            List => write!(f, "list"),
47            Object => write!(f, "object"),
48        }
49    }
50}
51
52#[derive(Debug, Clone)]
53pub enum Value {
54    Null,
55    Number(f64),
56    Bool(bool),
57    String(String),
58    Function(Function),
59    List(Rc<RefCell<Vec<Value>>>),
60    Object(Rc<RefCell<BTreeMap<String, Value>>>),
61}
62
63impl Display for Value {
64    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65        use Value::*;
66        match self {
67            Null => write!(f, "null"),
68            Number(n) => {
69                if n.is_nan() {
70                    write!(f, "nan")
71                } else {
72                    write!(f, "{}", n)
73                }
74            }
75            Bool(b) => write!(f, "{}", b),
76            String(s) => write!(f, r#""{}""#, s),
77            Function(func) => write!(f, "{:?}", func),
78            List(_) | Object(_) => print_potentially_self_referential(self, f),
79        }
80    }
81}
82
83fn print_potentially_self_referential(
84    value: &Value,
85    f: &mut std::fmt::Formatter<'_>,
86) -> std::fmt::Result {
87    print_potentially_self_referential_recursive(value, f, &mut Vec::new())
88}
89
90fn print_potentially_self_referential_recursive(
91    value: &Value,
92    f: &mut std::fmt::Formatter<'_>,
93    refs: &mut Vec<usize>,
94) -> std::fmt::Result {
95    match value {
96        Value::List(lst) => {
97            write!(f, "[")?;
98
99            let pointer = lst.as_ptr() as usize;
100            if refs.contains(&pointer) {
101                write!(f, "...")?;
102            } else {
103                refs.push(pointer);
104                let mut first = true;
105                for item in lst.borrow().iter() {
106                    if !first {
107                        write!(f, ", ")?;
108                    }
109                    first = false;
110                    print_potentially_self_referential_recursive(item, f, refs)?;
111                }
112                refs.pop();
113            }
114
115            write!(f, "]")
116        }
117        Value::Object(obj) => {
118            write!(f, "{{ ")?;
119
120            let pointer = obj.as_ptr() as usize;
121            if refs.contains(&pointer) {
122                write!(f, "...")?;
123            } else {
124                refs.push(pointer);
125                let mut first = true;
126                for (key, value) in obj.borrow().iter() {
127                    if !first {
128                        write!(f, ", ")?;
129                    }
130                    first = false;
131                    write!(f, "{}: ", key)?;
132                    print_potentially_self_referential_recursive(value, f, refs)?;
133                }
134                refs.pop();
135            }
136
137            write!(f, " }}")
138        }
139        non_referential => write!(f, "{}", non_referential),
140    }
141}
142
143impl Value {
144    fn get_type(&self) -> Type {
145        use Value::*;
146        match self {
147            Null => Type::Null,
148            Number(..) => Type::Number,
149            Bool(..) => Type::Bool,
150            String(..) => Type::String,
151            Function(..) => Type::Function,
152            List(..) => Type::List,
153            Object(..) => Type::Object,
154        }
155    }
156
157    fn assert_type(&self, expected: Type) -> Result<(), EvalError> {
158        let got = self.get_type();
159        if got != expected {
160            return Err(EvalError::WrongType { expected, got });
161        }
162        Ok(())
163    }
164
165    fn convert_to_string(&self) -> String {
166        match self {
167            Value::String(s) => s.clone(),
168            other => other.to_string(),
169        }
170    }
171
172    fn as_bool(&self) -> bool {
173        match self {
174            Value::Null => false,
175            Value::Number(n) => *n != 0.0,
176            Value::Bool(b) => *b,
177            Value::String(s) => !s.is_empty(),
178            Value::Function(..) => true,
179            Value::List(lst) => !lst.borrow().is_empty(),
180            Value::Object(obj) => !obj.borrow().is_empty(),
181        }
182    }
183
184    fn call(&self, ctx: &mut Context, args: Vec<Value>) -> Result<Value, EvalError> {
185        match self {
186            Value::Function(func) => {
187                let maybe_expected_args = func.get_arg_count();
188                let got_args = args.len();
189                if let Some(expected_args) = maybe_expected_args {
190                    if got_args != expected_args {
191                        return Err(EvalError::FunctionWrongArgAmount {
192                            name: func.get_name(),
193                            expected: expected_args,
194                            got: got_args,
195                        });
196                    }
197                }
198                func.call(ctx, &args)
199            }
200            other => {
201                let error = format!("Cannot call value of type {}", other.get_type());
202                Err(EvalError::TypeError(error))
203            }
204        }
205    }
206
207    fn get_member(&self, member: &str) -> Result<Value, EvalError> {
208        match self {
209            Value::String(s) => match member {
210                "length" => Ok(Value::Number(s.len() as f64)),
211                "trim" => {
212                    let func = Function::new_builtin(
213                        "trim",
214                        Some(self.clone()),
215                        Some(0),
216                        |_ctx, this, _args| {
217                            let Some(Value::String(s)) = this else {
218                                unreachable!()
219                            };
220                            let trimmed = s.trim().to_string();
221                            Ok(Value::String(trimmed))
222                        },
223                    );
224                    Ok(Value::Function(func))
225                }
226                "concat" => {
227                    let func = Function::new_builtin(
228                        "concat",
229                        Some(self.clone()),
230                        Some(1),
231                        |_ctx, this, args| {
232                            let Some(Value::String(mut s)) = this else {
233                                unreachable!()
234                            };
235                            args[0].assert_type(Type::String)?;
236                            let Value::String(other) = &args[0] else {
237                                unreachable!()
238                            };
239                            s.push_str(other);
240                            Ok(Value::String(s))
241                        },
242                    );
243                    Ok(Value::Function(func))
244                }
245                "slice" => {
246                    let func = Function::new_builtin(
247                        "slice",
248                        Some(self.clone()),
249                        Some(2),
250                        |_ctx, this, args| {
251                            let Some(Value::String(s)) = this else {
252                                unreachable!()
253                            };
254                            args[0].assert_type(Type::Number)?;
255                            args[1].assert_type(Type::Number)?;
256                            let Value::Number(start) = &args[0] else {
257                                unreachable!()
258                            };
259                            let Value::Number(end) = &args[1] else {
260                                unreachable!()
261                            };
262                            // TODO: Add overflow checks
263                            let start = *start as usize;
264                            let end = *end as usize;
265                            let sliced = if end > start { &s[start..end] } else { "" };
266                            Ok(Value::String(sliced.to_string()))
267                        },
268                    );
269                    Ok(Value::Function(func))
270                }
271                _ => Err(EvalError::NoSuchMember {
272                    r#type: Type::String,
273                    member_name: member.to_string(),
274                }),
275            },
276            Value::List(l) => match member {
277                "length" => Ok(Value::Number(l.borrow().len() as f64)),
278                "get" => {
279                    let func = Function::new_builtin(
280                        "get",
281                        Some(self.clone()),
282                        Some(1),
283                        |_ctx, this, args| {
284                            let Some(Value::List(l)) = this else {
285                                unreachable!()
286                            };
287                            args[0].assert_type(Type::Number)?;
288                            let Value::Number(index) = &args[0] else {
289                                unreachable!()
290                            };
291                            // TODO: Add overflow checks
292                            let index = *index as usize;
293                            let item = l.borrow().get(index).cloned().unwrap_or(NULL_VALUE);
294                            Ok(item)
295                        },
296                    );
297                    Ok(Value::Function(func))
298                }
299                "set" => {
300                    let func = Function::new_builtin(
301                        "set",
302                        Some(self.clone()),
303                        Some(2),
304                        |_ctx, this, args| {
305                            let Some(Value::List(l)) = this else {
306                                unreachable!()
307                            };
308                            args[0].assert_type(Type::Number)?;
309                            let Value::Number(index) = &args[0] else {
310                                unreachable!()
311                            };
312
313                            // TODO: Add overflow checks
314                            let index = *index as usize;
315                            let mut list = l.borrow_mut();
316                            if index >= list.len() {
317                                return Err(EvalError::IndexOutOfBounds {
318                                    index,
319                                    length: list.len(),
320                                });
321                            }
322                            list[index] = args[1].clone();
323
324                            Ok(NULL_VALUE)
325                        },
326                    );
327                    Ok(Value::Function(func))
328                }
329                "push" => {
330                    let func = Function::new_builtin(
331                        "push",
332                        Some(self.clone()),
333                        Some(1),
334                        |_ctx, this, args| {
335                            let Some(Value::List(l)) = this else {
336                                unreachable!()
337                            };
338                            l.borrow_mut().push(args[0].clone());
339                            Ok(Value::List(l))
340                        },
341                    );
342                    Ok(Value::Function(func))
343                }
344                _ => Err(EvalError::NoSuchMember {
345                    r#type: Type::List,
346                    member_name: member.to_string(),
347                }),
348            },
349            Value::Object(o) => {
350                let obj = o.borrow();
351                // TODO: Put this functionality in a method of a new Object type
352                if let Some(value) = obj.get(member) {
353                    match value.clone() {
354                        Value::Function(f) => Ok(Value::Function(f.with_this(Some(self.clone())))),
355                        v => Ok(v),
356                    }
357                } else {
358                    Err(EvalError::NoSuchMember {
359                        r#type: Type::Object,
360                        member_name: member.to_string(),
361                    })
362                }
363            }
364            _ => Err(EvalError::NoSuchMember {
365                r#type: self.get_type(),
366                member_name: member.to_string(),
367            }),
368        }
369    }
370
371    fn set_member(self, member: &str, value: Value) -> Result<(), EvalError> {
372        match self {
373            Value::Object(o) => {
374                let mut obj = o.borrow_mut();
375                obj.insert(member.to_string(), value);
376                Ok(())
377            }
378            _ => {
379                let error = format!("Cannot set member of type {}", self.get_type());
380                Err(EvalError::TypeError(error))
381            }
382        }
383    }
384
385    fn get_index(self, idx: Value) -> Result<Value, EvalError> {
386        match self {
387            Value::List(l) => {
388                idx.assert_type(Type::Number)?;
389                let Value::Number(index) = idx else {
390                    unreachable!()
391                };
392
393                // TODO: Add overflow checks
394                let index = index as usize;
395                let list = l.borrow();
396                if index >= list.len() {
397                    return Err(EvalError::IndexOutOfBounds {
398                        index,
399                        length: list.len(),
400                    });
401                }
402                Ok(list[index].clone())
403            }
404            Value::Object(ref o) => {
405                idx.assert_type(Type::String)?;
406                let Value::String(index) = idx else {
407                    unreachable!()
408                };
409
410                // TODO: Put this functionality in a method of a new Object type
411                if let Some(value) = o.borrow().get(&index) {
412                    match value.clone() {
413                        Value::Function(f) => Ok(Value::Function(f.with_this(Some(self.clone())))),
414                        v => Ok(v),
415                    }
416                } else {
417                    Err(EvalError::NoSuchMember {
418                        r#type: Type::Object,
419                        member_name: index,
420                    })
421                }
422            }
423            _ => {
424                let error = format!("Cannot index value of type {}", self.get_type());
425                Err(EvalError::TypeError(error))
426            }
427        }
428    }
429
430    fn set_index(self, idx: Value, value: Value) -> Result<(), EvalError> {
431        match self {
432            Value::List(l) => {
433                idx.assert_type(Type::Number)?;
434                let Value::Number(index) = idx else {
435                    unreachable!()
436                };
437
438                // TODO: Add overflow checks
439                let index = index as usize;
440                let mut list = l.borrow_mut();
441                if index >= list.len() {
442                    return Err(EvalError::IndexOutOfBounds {
443                        index,
444                        length: list.len(),
445                    });
446                }
447                list[index] = value;
448                Ok(())
449            }
450            Value::Object(o) => {
451                idx.assert_type(Type::String)?;
452                let Value::String(index) = idx else {
453                    unreachable!()
454                };
455
456                o.borrow_mut().insert(index, value);
457                Ok(())
458            }
459            _ => {
460                let error = format!("Cannot index value of type {}", self.get_type());
461                Err(EvalError::TypeError(error))
462            }
463        }
464    }
465
466    fn get_iterable(self) -> Result<Vec<Value>, EvalError> {
467        match self {
468            Value::List(l) => Ok(l.borrow().clone()),
469            _ => {
470                let error = format!("Cannot iterate over value of type {}", self.get_type());
471                Err(EvalError::TypeError(error))
472            }
473        }
474    }
475
476    fn add(self, rhs: Self) -> Result<Value, EvalError> {
477        use Value::*;
478        match (self, rhs) {
479            (Number(l), Number(r)) => Ok(Number(l + r)),
480            (String(l), String(r)) => Ok(String(l + &r)),
481            (l, r) => {
482                let error = format!(
483                    "Cannot add value of type {} and value of type {}",
484                    l.get_type(),
485                    r.get_type()
486                );
487                Err(EvalError::TypeError(error))
488            }
489        }
490    }
491
492    fn subtract(self, rhs: Self) -> Result<Value, EvalError> {
493        use Value::*;
494        match (self, rhs) {
495            (Number(l), Number(r)) => Ok(Number(l - r)),
496            (l, r) => {
497                let error = format!(
498                    "Cannot subtract value of type {} and value of type {}",
499                    l.get_type(),
500                    r.get_type()
501                );
502                Err(EvalError::TypeError(error))
503            }
504        }
505    }
506
507    fn multiply(self, rhs: Self) -> Result<Value, EvalError> {
508        use Value::*;
509        match (self, rhs) {
510            (Number(l), Number(r)) => Ok(Number(l * r)),
511            (l, r) => {
512                let error = format!(
513                    "Cannot multiply value of type {} and value of type {}",
514                    l.get_type(),
515                    r.get_type()
516                );
517                Err(EvalError::TypeError(error))
518            }
519        }
520    }
521
522    fn divide(self, rhs: Self) -> Result<Value, EvalError> {
523        use Value::*;
524        match (self, rhs) {
525            (Number(l), Number(r)) => Ok(Number(l / r)),
526            (l, r) => {
527                let error = format!(
528                    "Cannot divide value of type {} and value of type {}",
529                    l.get_type(),
530                    r.get_type()
531                );
532                Err(EvalError::TypeError(error))
533            }
534        }
535    }
536
537    fn modulo(self, rhs: Self) -> Result<Value, EvalError> {
538        use Value::*;
539        match (self, rhs) {
540            (Number(l), Number(r)) => Ok(Number(l % r)),
541            (l, r) => {
542                let error = format!(
543                    "Cannot modulo value of type {} and value of type {}",
544                    l.get_type(),
545                    r.get_type()
546                );
547                Err(EvalError::TypeError(error))
548            }
549        }
550    }
551
552    fn power(self, rhs: Self) -> Result<Value, EvalError> {
553        use Value::*;
554        match (self, rhs) {
555            (Number(l), Number(r)) => Ok(Number(l.powf(r))),
556            (l, r) => {
557                let error = format!(
558                    "Cannot raise power of value of type {} and value of type {}",
559                    l.get_type(),
560                    r.get_type()
561                );
562                Err(EvalError::TypeError(error))
563            }
564        }
565    }
566
567    fn negate(self) -> Result<Value, EvalError> {
568        use Value::*;
569        match self {
570            Number(l) => Ok(Number(-l)),
571            _ => {
572                let error = format!("Cannot negate value of type {}", self.get_type());
573                Err(EvalError::TypeError(error))
574            }
575        }
576    }
577
578    fn bool_negate(self) -> Result<Value, EvalError> {
579        Ok(Value::Bool(!self.as_bool()))
580    }
581
582    fn inner_equal(&self, rhs: &Self) -> bool {
583        use Value::*;
584
585        match (self, rhs) {
586            (Number(l), Number(r)) => l == r,
587            (Bool(l), Bool(r)) => l == r,
588            (String(l), String(r)) => l == r,
589            (Function(l), Function(r)) => l.is_equal(r),
590            (List(l), List(r)) => Rc::ptr_eq(l, r),
591            (Object(l), Object(r)) => Rc::ptr_eq(l, r),
592            (Null, Null) => true,
593            _ => false,
594        }
595    }
596
597    fn equal(self, rhs: Self) -> Result<Value, EvalError> {
598        Ok(Value::Bool(self.inner_equal(&rhs)))
599    }
600
601    fn unequal(self, rhs: Self) -> Result<Value, EvalError> {
602        Ok(Value::Bool(!self.inner_equal(&rhs)))
603    }
604
605    fn less_than(self, rhs: Self) -> Result<Value, EvalError> {
606        use Value::*;
607        let lt = match (self, rhs) {
608            (Number(l), Number(r)) => l < r,
609            (String(l), String(r)) => l < r,
610            (l, r) => {
611                let error = format!(
612                    "Cannot compare value of type {} and value of type {}",
613                    l.get_type(),
614                    r.get_type()
615                );
616                return Err(EvalError::TypeError(error));
617            }
618        };
619        Ok(Bool(lt))
620    }
621
622    fn greater_than(self, rhs: Self) -> Result<Value, EvalError> {
623        use Value::*;
624        let gt = match (self, rhs) {
625            (Number(l), Number(r)) => l > r,
626            (String(l), String(r)) => l > r,
627            (l, r) => {
628                let error = format!(
629                    "Cannot compare value of type {} and value of type {}",
630                    l.get_type(),
631                    r.get_type()
632                );
633                return Err(EvalError::TypeError(error));
634            }
635        };
636        Ok(Bool(gt))
637    }
638
639    fn less_than_or_equal(self, rhs: Self) -> Result<Value, EvalError> {
640        use Value::*;
641        let le = match (self, rhs) {
642            (Number(l), Number(r)) => l <= r,
643            (String(l), String(r)) => l <= r,
644            (l, r) => {
645                let error = format!(
646                    "Cannot compare value of type {} and value of type {}",
647                    l.get_type(),
648                    r.get_type()
649                );
650                return Err(EvalError::TypeError(error));
651            }
652        };
653        Ok(Bool(le))
654    }
655
656    fn greater_than_or_equal(self, rhs: Self) -> Result<Value, EvalError> {
657        use Value::*;
658        let ge = match (self, rhs) {
659            (Number(l), Number(r)) => l >= r,
660            (String(l), String(r)) => l >= r,
661            (l, r) => {
662                let error = format!(
663                    "Cannot compare value of type {} and value of type {}",
664                    l.get_type(),
665                    r.get_type()
666                );
667                return Err(EvalError::TypeError(error));
668            }
669        };
670        Ok(Bool(ge))
671    }
672
673    fn and(
674        self,
675        rhs_evaluator: impl FnOnce() -> Result<Self, EvalError>,
676    ) -> Result<Value, EvalError> {
677        let result = self.as_bool() && rhs_evaluator()?.as_bool();
678        Ok(Value::Bool(result))
679    }
680
681    fn or(
682        self,
683        rhs_evaluator: impl FnOnce() -> Result<Self, EvalError>,
684    ) -> Result<Value, EvalError> {
685        let result = self.as_bool() || rhs_evaluator()?.as_bool();
686        Ok(Value::Bool(result))
687    }
688}
689
690const NULL_VALUE: Value = Value::Null;
691
692#[derive(Clone)]
693pub struct Function {
694    kind: Rc<FunctionKind>,
695    receiver: Option<Box<Value>>,
696}
697
698impl Debug for Function {
699    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
700        write!(f, "{:?}", self.kind)?;
701        if let Some(receiver) = &self.receiver {
702            write!(f, " on {}", receiver)?;
703        }
704        Ok(())
705    }
706}
707
708impl Function {
709    pub fn new_builtin<F>(
710        name: impl Into<String>,
711        receiver: Option<Value>,
712        n_args: Option<usize>,
713        func: F,
714    ) -> Self
715    where
716        F: Fn(&mut Context, Option<Value>, &[Value]) -> Result<Value, EvalError> + 'static,
717    {
718        Function {
719            kind: Rc::new(FunctionKind::Builtin {
720                name: name.into(),
721                n_args,
722                func: Box::new(func),
723            }),
724            receiver: receiver.map(Box::new),
725        }
726    }
727
728    pub fn new_user_defined(
729        func_name: Option<&str>,
730        arg_names: Vec<String>,
731        body: Ast,
732    ) -> Result<Self, EvalError> {
733        let func_name = func_name.map(|name| name.to_string());
734
735        let mut arg_set = BTreeSet::new();
736        for name in &arg_names {
737            if !arg_set.insert(name) {
738                return Err(EvalError::DuplicateArgName {
739                    func_name,
740                    arg_name: name.clone(),
741                });
742            }
743        }
744
745        Ok(Function {
746            kind: Rc::new(FunctionKind::UserDefined {
747                name: func_name,
748                arg_names,
749                body,
750            }),
751            receiver: None,
752        })
753    }
754
755    pub fn get_name(&self) -> Option<String> {
756        match self.kind.as_ref() {
757            FunctionKind::Builtin { name, .. } => Some(name.clone()),
758            FunctionKind::UserDefined { name, .. } => name.clone(),
759        }
760    }
761
762    pub fn call(&self, ctx: &mut Context, args: &[Value]) -> Result<Value, EvalError> {
763        let receiver = self.receiver.as_ref().map(|r| r.as_ref().to_owned());
764
765        match self.kind.as_ref() {
766            FunctionKind::Builtin { func, .. } => func(ctx, receiver, args),
767            FunctionKind::UserDefined {
768                arg_names, body, ..
769            } => {
770                if ctx.call_stack.len() >= CALL_STACK_SIZE_LIMIT - 1 {
771                    return Err(EvalError::CallStackOverflow);
772                }
773
774                let mut scope = Scope::new();
775                if let Some(recv) = receiver {
776                    scope.set_var("this", recv);
777                }
778                for (name, value) in arg_names.iter().zip(args.iter()) {
779                    scope.set_var(name, value.clone());
780                }
781
782                if let Some(function_scope) = ctx.function_scope.take() {
783                    ctx.call_stack.push(function_scope);
784                }
785                ctx.function_scope = Some(scope);
786
787                let call_result = match evaluate(body, ctx) {
788                    Err(EvalError::InternalControlFlow(ControlFlow::Return(val))) => Ok(val),
789                    Err(EvalError::InternalControlFlow(ControlFlow::Continue)) => {
790                        Err(EvalError::ContinueOutsideOfLoop)
791                    }
792                    Err(EvalError::InternalControlFlow(ControlFlow::Break)) => {
793                        Err(EvalError::BreakOutsideOfLoop)
794                    }
795                    other => other,
796                };
797                ctx.function_scope = ctx.call_stack.pop();
798                call_result
799            }
800        }
801    }
802
803    fn get_arg_count(&self) -> Option<usize> {
804        match self.kind.as_ref() {
805            FunctionKind::Builtin { n_args, .. } => *n_args,
806            FunctionKind::UserDefined { arg_names, .. } => Some(arg_names.len()),
807        }
808    }
809
810    fn is_equal(&self, other: &Function) -> bool {
811        Rc::ptr_eq(&self.kind, &other.kind)
812            && match (&self.receiver, &other.receiver) {
813                (Some(l), Some(r)) => l.inner_equal(r),
814                (None, None) => true,
815                _ => false,
816            }
817    }
818
819    fn with_this(self, this: Option<Value>) -> Self {
820        Function {
821            kind: self.kind,
822            receiver: this.map(Box::new),
823        }
824    }
825}
826
827type BuiltinFunctionClosure =
828    Box<dyn Fn(&mut Context, Option<Value>, &[Value]) -> Result<Value, EvalError>>;
829
830pub enum FunctionKind {
831    Builtin {
832        name: String,
833        n_args: Option<usize>,
834        func: BuiltinFunctionClosure,
835    },
836    UserDefined {
837        name: Option<String>,
838        arg_names: Vec<String>,
839        body: Ast,
840    },
841}
842
843impl Debug for FunctionKind {
844    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
845        match self {
846            FunctionKind::Builtin { name, .. } => {
847                write!(f, "built-in function '{}'", name)
848            }
849            FunctionKind::UserDefined { name, .. } => {
850                if let Some(name) = name {
851                    write!(f, "function '{}'", name)
852                } else {
853                    write!(f, "unnamed function")
854                }
855            }
856        }
857    }
858}
859
860struct Scope {
861    variables: BTreeMap<String, Value>,
862}
863
864impl Scope {
865    pub fn new() -> Self {
866        Self {
867            variables: BTreeMap::new(),
868        }
869    }
870
871    pub fn get_var(&self, name: &str) -> Option<Value> {
872        self.variables.get(name).cloned()
873    }
874
875    pub fn set_var(&mut self, name: impl Into<String>, val: Value) {
876        self.variables.insert(name.into(), val);
877    }
878}
879
880pub struct ContextBuilder {
881    stdin: Box<dyn Read>,
882    stdout: Box<dyn Write>,
883    stderr: Box<dyn Write>,
884    debug_writer: Option<Box<dyn Write>>,
885    standard_variables: bool,
886    standard_functions: bool,
887}
888
889impl Default for ContextBuilder {
890    fn default() -> Self {
891        Self {
892            stdin: Box::new(stdin()),
893            stdout: Box::new(stdout()),
894            stderr: Box::new(stderr()),
895            debug_writer: Some(Box::new(stdout())),
896            standard_variables: true,
897            standard_functions: true,
898        }
899    }
900}
901
902impl ContextBuilder {
903    pub fn build(self) -> Context {
904        let mut ctx = Context {
905            global_scope: Scope::new(),
906            function_scope: None,
907            call_stack: Vec::new(),
908            stdin: BufReader::new(self.stdin),
909            stdout: self.stdout,
910            stderr: self.stderr,
911            debug_writer: self.debug_writer,
912            _internal_side_effect_flag: false,
913        };
914
915        if self.standard_variables {
916            ctx.add_standard_variables();
917        }
918        if self.standard_functions {
919            ctx.add_standard_functions()
920                .expect("Failed to add standard functions to context");
921        }
922
923        ctx
924    }
925
926    // TODO: Remove `#[allow(unused)]` once this is used outside of tests
927    #[allow(unused)]
928    pub fn stdin(mut self, stdin: impl Read + 'static) -> Self {
929        self.stdin = Box::new(stdin);
930        self
931    }
932
933    // TODO: Remove `#[allow(unused)]` once this is used outside of tests
934    #[allow(unused)]
935    pub fn stdout(mut self, stdout: impl Write + 'static) -> Self {
936        self.stdout = Box::new(stdout);
937        self
938    }
939
940    // TODO: Remove `#[allow(unused)]` once this is used outside of tests
941    #[allow(unused)]
942    pub fn stderr(mut self, stderr: impl Write + 'static) -> Self {
943        self.stderr = Box::new(stderr);
944        self
945    }
946
947    pub fn debug_writer(mut self, debug_writer: Option<impl Write + 'static>) -> Self {
948        if let Some(debug_writer) = debug_writer {
949            self.debug_writer = Some(Box::new(debug_writer));
950        } else {
951            self.debug_writer = None;
952        }
953        self
954    }
955
956    // TODO: Remove `#[allow(unused)]` once this is used outside of tests
957    #[allow(unused)]
958    pub fn standard_variables(mut self, b: bool) -> Self {
959        self.standard_variables = b;
960        self
961    }
962
963    // TODO: Remove `#[allow(unused)]` once this is used outside of tests
964    #[allow(unused)]
965    pub fn standard_functions(mut self, b: bool) -> Self {
966        self.standard_functions = b;
967        self
968    }
969}
970
971pub struct Context {
972    global_scope: Scope,
973    function_scope: Option<Scope>,
974    call_stack: Vec<Scope>,
975    stdin: BufReader<Box<dyn Read>>,
976    stdout: Box<dyn Write>,
977    stderr: Box<dyn Write>,
978    #[allow(dead_code)]
979    debug_writer: Option<Box<dyn Write>>,
980    /// This flag is used during tests until observable side effects apart from writing to stdout
981    /// are introduced.
982    // TODO: Remove this when some form of obvservable side effects is implemented
983    pub _internal_side_effect_flag: bool,
984}
985
986impl Default for Context {
987    fn default() -> Self {
988        Self::builder().build()
989    }
990}
991
992impl Context {
993    pub fn new() -> Self {
994        Self::default()
995    }
996
997    pub fn builder() -> ContextBuilder {
998        ContextBuilder::default()
999    }
1000
1001    pub fn eval_str(&mut self, s: &str) -> Result<Value, SeraphineError> {
1002        let tokens = tokenize(s)?;
1003
1004        #[cfg(debug_assertions)]
1005        if !cfg!(test) {
1006            if let Some(debug_writer) = &mut self.debug_writer {
1007                writeln!(debug_writer, "Tokens: {:?}", tokens)?;
1008            }
1009        } else {
1010            println!("Tokens: {:?}", tokens);
1011        }
1012
1013        let ast = parse(&tokens)?;
1014
1015        #[cfg(debug_assertions)]
1016        if !cfg!(test) {
1017            if let Some(debug_writer) = &mut self.debug_writer {
1018                writeln!(debug_writer, "AST: {:#?}", ast)?;
1019            }
1020        } else {
1021            println!("AST: {:#?}", ast);
1022        }
1023
1024        let result = evaluate(&ast, self)?;
1025        Ok(result)
1026    }
1027
1028    fn add_standard_variables(&mut self) {
1029        use std::f64::consts::{E, PI};
1030
1031        // TODO: Scope constants to a separate namespace like `math`, so they can be used via `math.pi`
1032        self.set_var("pi", Value::Number(PI));
1033        self.set_var("e", Value::Number(E));
1034        self.set_var("nan", Value::Number(f64::NAN));
1035        self.set_var("inf", Value::Number(f64::INFINITY));
1036    }
1037
1038    fn add_standard_functions(&mut self) -> Result<(), EvalError> {
1039        self.add_builtin_function(
1040            "_set_internal_side_effect_flag",
1041            Some(0),
1042            |ctx, _this, _args| {
1043                ctx._internal_side_effect_flag = true;
1044                Ok(NULL_VALUE)
1045            },
1046        );
1047
1048        self.add_builtin_function("print", None, |ctx, _this, args| {
1049            print_values(&mut ctx.stdout, args)?;
1050            ctx.stdout.flush()?;
1051            Ok(NULL_VALUE)
1052        });
1053
1054        self.add_builtin_function("println", None, |ctx, _this, args| {
1055            print_values(&mut ctx.stdout, args)?;
1056            writeln!(ctx.stdout, "")?;
1057            Ok(NULL_VALUE)
1058        });
1059
1060        self.add_builtin_function("eprint", None, |ctx, _this, args| {
1061            print_values(&mut ctx.stderr, args)?;
1062            ctx.stderr.flush()?;
1063            Ok(NULL_VALUE)
1064        });
1065
1066        self.add_builtin_function("eprintln", None, |ctx, _this, args| {
1067            print_values(&mut ctx.stderr, args)?;
1068            writeln!(ctx.stderr, "")?;
1069            Ok(NULL_VALUE)
1070        });
1071
1072        self.add_builtin_function("read_line", Some(0), |ctx, _this, _args| {
1073            let mut str = String::new();
1074            ctx.stdin.read_line(&mut str)?;
1075            str.pop();
1076            Ok(Value::String(str))
1077        });
1078
1079        self.add_builtin_function("to_string", Some(1), |_ctx, _this, args| {
1080            Ok(Value::String(args[0].convert_to_string()))
1081        });
1082
1083        self.add_builtin_function("parse_number", Some(1), |_ctx, _this, args| {
1084            args[0].assert_type(Type::String)?;
1085            let Value::String(ref arg) = args[0] else {
1086                unreachable!()
1087            };
1088            let num = arg.parse().unwrap_or(f64::NAN);
1089            Ok(Value::Number(num))
1090        });
1091
1092        self.add_builtin_function("range", None, |_ctx, _this, args| {
1093            // TODO: Implement backwards stepping
1094            fn make_range(start: i64, end: i64, step: i64) -> Result<Vec<Value>, EvalError> {
1095                if step == 0 {
1096                    return Err(EvalError::GenericError(
1097                        "range: step cannot be 0".to_string(),
1098                    ));
1099                }
1100
1101                if step > 0 {
1102                    Ok((start..end)
1103                        .into_iter()
1104                        .step_by(step as usize)
1105                        .map(|n| Value::Number(n as f64))
1106                        .collect())
1107                } else {
1108                    // TODO: This could panic for i64::MIN
1109                    let step = -step;
1110
1111                    // `end` is not inclusive but `start` is; `+ 1` since end is the smaller number
1112                    // in this case
1113                    Ok(((end + 1)..=start)
1114                        .into_iter()
1115                        .rev()
1116                        .step_by(step as usize)
1117                        .map(|n| Value::Number(n as f64))
1118                        .collect())
1119                }
1120            }
1121
1122            // TODO: Limit arguments to range 1..=3 in a better way
1123            if args.is_empty() {
1124                return Err(EvalError::FunctionWrongArgAmount {
1125                    name: Some("range".to_string()),
1126                    expected: 1,
1127                    got: args.len(),
1128                });
1129            } else if args.len() > 3 {
1130                return Err(EvalError::FunctionWrongArgAmount {
1131                    name: Some("range".to_string()),
1132                    expected: 3,
1133                    got: args.len(),
1134                });
1135            }
1136
1137            let range = if args.len() == 1 {
1138                args[0].assert_type(Type::Number)?;
1139                let Value::Number(end) = args[0] else {
1140                    unreachable!()
1141                };
1142
1143                // TODO: Fix this
1144                let end = end as i64;
1145
1146                make_range(0, end, 1)?
1147            } else {
1148                args[0].assert_type(Type::Number)?;
1149                args[1].assert_type(Type::Number)?;
1150                if args.len() == 3 {
1151                    args[2].assert_type(Type::Number)?;
1152                }
1153
1154                let Value::Number(start) = args[0] else {
1155                    unreachable!()
1156                };
1157                let Value::Number(end) = args[1] else {
1158                    unreachable!()
1159                };
1160
1161                let step = if args.len() == 3 {
1162                    let Value::Number(step) = args[2] else {
1163                        unreachable!()
1164                    };
1165                    step
1166                } else {
1167                    1.0
1168                };
1169
1170                // TODO: Fix this
1171                let start = start as i64;
1172                let end = end as i64;
1173                let step = step as i64;
1174
1175                make_range(start, end, step)?
1176            };
1177
1178            Ok(Value::List(Rc::new(RefCell::new(range))))
1179        });
1180
1181        // TODO: Scope functions to a separate namespace like `math`, so they can be used via
1182        // `math.is_nan(42)`
1183        self.add_builtin_function("is_nan", Some(1), |_ctx, _this, args| {
1184            args[0].assert_type(Type::Number)?;
1185            let Value::Number(arg) = args[0] else {
1186                unreachable!()
1187            };
1188            Ok(Value::Bool(arg.is_nan()))
1189        });
1190
1191        self.add_builtin_function("is_infinite", Some(1), |_ctx, _this, args| {
1192            args[0].assert_type(Type::Number)?;
1193            let Value::Number(arg) = args[0] else {
1194                unreachable!()
1195            };
1196            Ok(Value::Bool(arg.is_infinite()))
1197        });
1198
1199        self.add_builtin_function("is_finite", Some(1), |_ctx, _this, args| {
1200            args[0].assert_type(Type::Number)?;
1201            let Value::Number(arg) = args[0] else {
1202                unreachable!()
1203            };
1204            Ok(Value::Bool(arg.is_finite()))
1205        });
1206
1207        self.add_builtin_function("sin", Some(1), |_ctx, _this, args| {
1208            args[0].assert_type(Type::Number)?;
1209            let Value::Number(arg) = args[0] else {
1210                unreachable!()
1211            };
1212            Ok(Value::Number(arg.sin()))
1213        });
1214        self.add_builtin_function("cos", Some(1), |_ctx, _this, args| {
1215            args[0].assert_type(Type::Number)?;
1216            let Value::Number(arg) = args[0] else {
1217                unreachable!()
1218            };
1219            Ok(Value::Number(arg.cos()))
1220        });
1221        self.add_builtin_function("tan", Some(1), |_ctx, _this, args| {
1222            args[0].assert_type(Type::Number)?;
1223            let Value::Number(arg) = args[0] else {
1224                unreachable!()
1225            };
1226            Ok(Value::Number(arg.tan()))
1227        });
1228        self.add_builtin_function("asin", Some(1), |_ctx, _this, args| {
1229            args[0].assert_type(Type::Number)?;
1230            let Value::Number(arg) = args[0] else {
1231                unreachable!()
1232            };
1233            Ok(Value::Number(arg.asin()))
1234        });
1235        self.add_builtin_function("acos", Some(1), |_ctx, _this, args| {
1236            args[0].assert_type(Type::Number)?;
1237            let Value::Number(arg) = args[0] else {
1238                unreachable!()
1239            };
1240            Ok(Value::Number(arg.acos()))
1241        });
1242        self.add_builtin_function("atan", Some(1), |_ctx, _this, args| {
1243            args[0].assert_type(Type::Number)?;
1244            let Value::Number(arg) = args[0] else {
1245                unreachable!()
1246            };
1247            Ok(Value::Number(arg.atan()))
1248        });
1249        self.add_builtin_function("atan2", Some(1), |_ctx, _this, args| {
1250            args[0].assert_type(Type::Number)?;
1251            args[1].assert_type(Type::Number)?;
1252            let Value::Number(arg1) = args[0] else {
1253                unreachable!()
1254            };
1255            let Value::Number(arg2) = args[1] else {
1256                unreachable!()
1257            };
1258            Ok(Value::Number(arg1.atan2(arg2)))
1259        });
1260        self.add_builtin_function("tanh", Some(1), |_ctx, _this, args| {
1261            args[0].assert_type(Type::Number)?;
1262            let Value::Number(arg) = args[0] else {
1263                unreachable!()
1264            };
1265            Ok(Value::Number(arg.tanh()))
1266        });
1267        self.add_builtin_function("sinh", Some(1), |_ctx, _this, args| {
1268            args[0].assert_type(Type::Number)?;
1269            let Value::Number(arg) = args[0] else {
1270                unreachable!()
1271            };
1272            Ok(Value::Number(arg.sinh()))
1273        });
1274        self.add_builtin_function("cosh", Some(1), |_ctx, _this, args| {
1275            args[0].assert_type(Type::Number)?;
1276            let Value::Number(arg) = args[0] else {
1277                unreachable!()
1278            };
1279            Ok(Value::Number(arg.cosh()))
1280        });
1281
1282        self.add_builtin_function("ln", Some(1), |_ctx, _this, args| {
1283            args[0].assert_type(Type::Number)?;
1284            let Value::Number(arg) = args[0] else {
1285                unreachable!()
1286            };
1287            Ok(Value::Number(arg.ln()))
1288        });
1289        self.add_builtin_function("log2", Some(1), |_ctx, _this, args| {
1290            args[0].assert_type(Type::Number)?;
1291            let Value::Number(arg) = args[0] else {
1292                unreachable!()
1293            };
1294            Ok(Value::Number(arg.log2()))
1295        });
1296        self.add_builtin_function("log10", Some(1), |_ctx, _this, args| {
1297            args[0].assert_type(Type::Number)?;
1298            let Value::Number(arg) = args[0] else {
1299                unreachable!()
1300            };
1301            Ok(Value::Number(arg.log10()))
1302        });
1303        self.add_builtin_function("log", Some(2), |_ctx, _this, args| {
1304            args[0].assert_type(Type::Number)?;
1305            args[1].assert_type(Type::Number)?;
1306            let Value::Number(arg1) = args[0] else {
1307                unreachable!()
1308            };
1309            let Value::Number(arg2) = args[1] else {
1310                unreachable!()
1311            };
1312            Ok(Value::Number(arg1.log(arg2)))
1313        });
1314
1315        self.add_builtin_function("abs", Some(1), |_ctx, _this, args| {
1316            args[0].assert_type(Type::Number)?;
1317            let Value::Number(arg) = args[0] else {
1318                unreachable!()
1319            };
1320            Ok(Value::Number(arg.abs()))
1321        });
1322        self.add_builtin_function("min", Some(2), |_ctx, _this, args| {
1323            args[0].assert_type(Type::Number)?;
1324            args[1].assert_type(Type::Number)?;
1325            let Value::Number(arg1) = args[0] else {
1326                unreachable!()
1327            };
1328            let Value::Number(arg2) = args[1] else {
1329                unreachable!()
1330            };
1331            Ok(Value::Number(arg1.min(arg2)))
1332        });
1333        self.add_builtin_function("max", Some(2), |_ctx, _this, args| {
1334            args[0].assert_type(Type::Number)?;
1335            args[1].assert_type(Type::Number)?;
1336            let Value::Number(arg1) = args[0] else {
1337                unreachable!()
1338            };
1339            let Value::Number(arg2) = args[1] else {
1340                unreachable!()
1341            };
1342            Ok(Value::Number(arg1.max(arg2)))
1343        });
1344        self.add_builtin_function("floor", Some(1), |_ctx, _this, args| {
1345            args[0].assert_type(Type::Number)?;
1346            let Value::Number(arg) = args[0] else {
1347                unreachable!()
1348            };
1349            Ok(Value::Number(arg.floor()))
1350        });
1351        self.add_builtin_function("ceil", Some(1), |_ctx, _this, args| {
1352            args[0].assert_type(Type::Number)?;
1353            let Value::Number(arg) = args[0] else {
1354                unreachable!()
1355            };
1356            Ok(Value::Number(arg.ceil()))
1357        });
1358        self.add_builtin_function("round", Some(1), |_ctx, _this, args| {
1359            args[0].assert_type(Type::Number)?;
1360            let Value::Number(arg) = args[0] else {
1361                unreachable!()
1362            };
1363            Ok(Value::Number(arg.round()))
1364        });
1365
1366        self.add_builtin_function("sqrt", Some(1), |_ctx, _this, args| {
1367            args[0].assert_type(Type::Number)?;
1368            let Value::Number(arg) = args[0] else {
1369                unreachable!()
1370            };
1371            Ok(Value::Number(arg.sqrt()))
1372        });
1373        self.add_builtin_function("exp", Some(1), |_ctx, _this, args| {
1374            args[0].assert_type(Type::Number)?;
1375            let Value::Number(arg) = args[0] else {
1376                unreachable!()
1377            };
1378            Ok(Value::Number(arg.exp()))
1379        });
1380
1381        self.add_builtin_function("inspect", Some(1), |_ctx, _this, args| {
1382            println!("{}", args[0]);
1383            Ok(args[0].clone())
1384        });
1385
1386        Ok(())
1387    }
1388
1389    pub fn add_builtin_function<F>(
1390        &mut self,
1391        name: impl Into<String> + Clone,
1392        n_args: Option<usize>,
1393        func: F,
1394    ) where
1395        F: Fn(&mut Context, Option<Value>, &[Value]) -> Result<Value, EvalError> + 'static,
1396    {
1397        self.set_var(
1398            name.clone(),
1399            Value::Function(Function::new_builtin(name, None, n_args, func)),
1400        )
1401    }
1402
1403    pub fn get_var(&self, name: &str) -> Option<Value> {
1404        self.function_scope
1405            .as_ref()
1406            .and_then(|s| s.get_var(name))
1407            .or_else(|| self.global_scope.get_var(name))
1408    }
1409
1410    pub fn set_var(&mut self, name: impl Into<String>, val: Value) {
1411        let scope = self
1412            .function_scope
1413            .as_mut()
1414            .unwrap_or(&mut self.global_scope);
1415        scope.set_var(name, val);
1416    }
1417}
1418
1419pub fn evaluate(ast: &Ast, ctx: &mut Context) -> Result<Value, EvalError> {
1420    let result = match ast {
1421        Ast::FunctionDefinition {
1422            name,
1423            arg_names,
1424            body,
1425        } => {
1426            let func =
1427                Function::new_user_defined(Some(name.as_str()), arg_names.clone(), *body.clone())?;
1428            ctx.set_var(name, Value::Function(func));
1429            NULL_VALUE
1430        }
1431        Ast::UnnamedFunction { arg_names, body } => {
1432            let func = Function::new_user_defined(None, arg_names.clone(), *body.clone())?;
1433            Value::Function(func)
1434        }
1435        Ast::MemberAccess {
1436            value: value_ast,
1437            member,
1438        } => {
1439            let value = evaluate(value_ast, ctx)?;
1440            value.get_member(member)?
1441        }
1442        Ast::Indexing {
1443            value: value_ast,
1444            index: index_ast,
1445        } => {
1446            let value = evaluate(value_ast, ctx)?;
1447            let index = evaluate(index_ast, ctx)?;
1448            value.get_index(index)?
1449        }
1450        Ast::Lines(lines) => {
1451            let mut result = NULL_VALUE;
1452            for line in lines {
1453                result = evaluate(line, ctx)?;
1454            }
1455            result
1456        }
1457        Ast::Null => NULL_VALUE,
1458        Ast::NumberLiteral(n) => Value::Number(*n),
1459        Ast::BooleanLiteral(b) => Value::Bool(*b),
1460        Ast::StringLiteral(s) => Value::String(s.clone()),
1461        Ast::ListLiteral(values) => {
1462            let values: Vec<_> = values
1463                .iter()
1464                .map(|ast| evaluate(ast, ctx))
1465                .collect::<Result<_, _>>()?;
1466            Value::List(Rc::new(RefCell::new(values)))
1467        }
1468        Ast::ObjectLiteral(key_value_pairs) => {
1469            let mut object = BTreeMap::new();
1470            for (key, value) in key_value_pairs {
1471                let value = evaluate(value, ctx)?;
1472                object.insert(key.clone(), value);
1473            }
1474            Value::Object(Rc::new(RefCell::new(object)))
1475        }
1476        Ast::Variable(name) => ctx
1477            .get_var(name)
1478            .ok_or_else(|| EvalError::VariableNotDefined(name.clone()))?,
1479        Ast::Add(lhs, rhs) => evaluate(lhs, ctx)?.add(evaluate(rhs, ctx)?)?,
1480        Ast::Subtract(lhs, rhs) => evaluate(lhs, ctx)?.subtract(evaluate(rhs, ctx)?)?,
1481        Ast::Multiply(lhs, rhs) => evaluate(lhs, ctx)?.multiply(evaluate(rhs, ctx)?)?,
1482        Ast::Divide(lhs, rhs) => evaluate(lhs, ctx)?.divide(evaluate(rhs, ctx)?)?,
1483        Ast::Modulo(lhs, rhs) => evaluate(lhs, ctx)?.modulo(evaluate(rhs, ctx)?)?,
1484        Ast::Power(lhs, rhs) => evaluate(lhs, ctx)?.power(evaluate(rhs, ctx)?)?,
1485        Ast::UnaryMinus(rhs) => evaluate(rhs, ctx)?.negate()?,
1486        Ast::BooleanNegate(rhs) => evaluate(rhs, ctx)?.bool_negate()?,
1487        Ast::Equality(lhs, rhs) => evaluate(lhs, ctx)?.equal(evaluate(rhs, ctx)?)?,
1488        Ast::Inequality(lhs, rhs) => evaluate(lhs, ctx)?.unequal(evaluate(rhs, ctx)?)?,
1489        Ast::LessThan(lhs, rhs) => evaluate(lhs, ctx)?.less_than(evaluate(rhs, ctx)?)?,
1490        Ast::GreaterThan(lhs, rhs) => evaluate(lhs, ctx)?.greater_than(evaluate(rhs, ctx)?)?,
1491        Ast::LessThanOrEqual(lhs, rhs) => {
1492            evaluate(lhs, ctx)?.less_than_or_equal(evaluate(rhs, ctx)?)?
1493        }
1494        Ast::GreaterThanOrEqual(lhs, rhs) => {
1495            evaluate(lhs, ctx)?.greater_than_or_equal(evaluate(rhs, ctx)?)?
1496        }
1497        Ast::And(lhs, rhs) => evaluate(lhs, ctx)?.and(|| evaluate(rhs, ctx))?,
1498        Ast::Or(lhs, rhs) => evaluate(lhs, ctx)?.or(|| evaluate(rhs, ctx))?,
1499        Ast::Brackets(inner) => evaluate(inner, ctx)?,
1500        Ast::Assign(name, rhs) => {
1501            let rval = evaluate(rhs, ctx)?;
1502            ctx.set_var(name, rval.clone());
1503            NULL_VALUE
1504        }
1505        Ast::IndexingAssign { value, index, rhs } => {
1506            let value = evaluate(value, ctx)?;
1507            let index = evaluate(index, ctx)?;
1508            let rval = evaluate(rhs, ctx)?;
1509            value.set_index(index, rval.clone())?;
1510            NULL_VALUE
1511        }
1512        Ast::MemberAssign { value, member, rhs } => {
1513            let value = evaluate(value, ctx)?;
1514            let rval = evaluate(rhs, ctx)?;
1515            value.set_member(member, rval.clone())?;
1516            NULL_VALUE
1517        }
1518        Ast::FunctionCall { value, args } => {
1519            let val = evaluate(value, ctx)?;
1520            let args: Vec<_> = args
1521                .iter()
1522                .map(|ast| evaluate(ast, ctx))
1523                .collect::<Result<_, _>>()?;
1524            val.call(ctx, args)?
1525        }
1526        Ast::IfStatement {
1527            condition,
1528            if_body,
1529            else_body,
1530        } => {
1531            let condition = evaluate(condition, ctx)?;
1532            if condition.as_bool() {
1533                evaluate(if_body, ctx)?;
1534            } else if let Some(else_body) = else_body {
1535                evaluate(else_body, ctx)?;
1536            }
1537            NULL_VALUE
1538        }
1539        Ast::WhileLoop { condition, body } => {
1540            while evaluate(condition, ctx)?.as_bool() {
1541                match evaluate(body, ctx) {
1542                    Err(EvalError::InternalControlFlow(ControlFlow::Continue)) => continue,
1543                    Err(EvalError::InternalControlFlow(ControlFlow::Break)) => break,
1544                    e @ Err(_) => return e,
1545                    Ok(_) => (),
1546                }
1547            }
1548            NULL_VALUE
1549        }
1550        Ast::ForLoop {
1551            variable,
1552            iterable,
1553            body,
1554        } => {
1555            let iterable = evaluate(iterable, ctx)?;
1556            for value in iterable.get_iterable()? {
1557                ctx.set_var(variable, value);
1558                match evaluate(body, ctx) {
1559                    Err(EvalError::InternalControlFlow(ControlFlow::Continue)) => continue,
1560                    Err(EvalError::InternalControlFlow(ControlFlow::Break)) => break,
1561                    e @ Err(_) => return e,
1562                    Ok(_) => (),
1563                }
1564            }
1565            NULL_VALUE
1566        }
1567        Ast::Continue => {
1568            return Err(EvalError::InternalControlFlow(ControlFlow::Continue));
1569        }
1570        Ast::Break => {
1571            return Err(EvalError::InternalControlFlow(ControlFlow::Break));
1572        }
1573        Ast::Return(expr) => {
1574            let val = match expr {
1575                None => NULL_VALUE,
1576                Some(expr) => evaluate(expr, ctx)?,
1577            };
1578            return Err(EvalError::InternalControlFlow(ControlFlow::Return(val)));
1579        }
1580    };
1581
1582    Ok(result)
1583}
1584
1585fn print_values<W: Write>(to: &mut W, values: &[Value]) -> Result<(), EvalError> {
1586    let mut str_iter = values.iter().map(|v| v.convert_to_string());
1587    if let Some(first) = str_iter.next() {
1588        write!(to, "{}", first)?;
1589    }
1590    for str in str_iter {
1591        write!(to, " {}", str)?;
1592    }
1593    Ok(())
1594}