lox/
interpreter.rs

1use super::error_codes;
2use super::Ast;
3use super::Binary;
4use super::Expr;
5use super::Function as FunctionDecl;
6use super::Literal;
7use super::Logical;
8use super::Stmt;
9use super::Unary;
10
11use std::cell::Cell;
12use std::cell::RefCell;
13use std::cmp;
14use std::collections::HashMap;
15use std::fmt;
16use std::rc::Rc;
17use std::rc::Weak;
18
19use flexi_parse::error::Error;
20use flexi_parse::group::Delimiters as _;
21use flexi_parse::group::Parentheses;
22use flexi_parse::new_error;
23use flexi_parse::token::Ident;
24use flexi_parse::token::Token;
25use flexi_parse::Punct;
26use flexi_parse::Result;
27
28mod natives {
29    use super::Value;
30
31    use std::time::SystemTime;
32
33    use flexi_parse::Result;
34
35    #[allow(clippy::unnecessary_wraps)]
36    pub(super) fn clock(_: Vec<Value>) -> Result<Value> {
37        Ok(Value::Number(
38            SystemTime::now()
39                .duration_since(SystemTime::UNIX_EPOCH)
40                .unwrap()
41                .as_secs_f64(),
42        ))
43    }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47enum Ordering {
48    Less,
49    Equal,
50    Greater,
51    None,
52}
53
54impl Ordering {
55    fn gt(self) -> bool {
56        self == Ordering::Greater
57    }
58
59    fn ge(self) -> bool {
60        self == Ordering::Greater || self == Ordering::Equal
61    }
62
63    fn lt(self) -> bool {
64        self == Ordering::Less
65    }
66
67    fn le(self) -> bool {
68        self == Ordering::Less || self == Ordering::Equal
69    }
70}
71
72impl From<cmp::Ordering> for Ordering {
73    fn from(value: cmp::Ordering) -> Self {
74        match value {
75            cmp::Ordering::Less => Ordering::Less,
76            cmp::Ordering::Equal => Ordering::Equal,
77            cmp::Ordering::Greater => Ordering::Greater,
78        }
79    }
80}
81
82impl From<Option<cmp::Ordering>> for Ordering {
83    fn from(value: Option<cmp::Ordering>) -> Self {
84        value.map_or(Ordering::None, Into::into)
85    }
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89struct NativeFunction {
90    function: fn(Vec<Value>) -> Result<Value>,
91    arity: usize,
92    name: &'static str,
93}
94
95#[derive(Debug, Clone)]
96struct Function {
97    declaration: FunctionDecl,
98    closure: State,
99    is_initialiser: bool,
100}
101
102impl Function {
103    const fn new(declaration: FunctionDecl, closure: State, is_initialiser: bool) -> Function {
104        Function {
105            declaration,
106            closure,
107            is_initialiser,
108        }
109    }
110
111    fn call(&self, arguments: Vec<Value>, parentheses: &Parentheses) -> Result<Value> {
112        let state = self.closure.start_scope();
113        if self.declaration.params.len() != arguments.len() {
114            return Err(arity_error(
115                parentheses,
116                self.declaration.params.len(),
117                arguments.len(),
118            ));
119        }
120        for (name, arg) in self.declaration.params.iter().zip(arguments) {
121            state
122                .environment
123                .borrow_mut()
124                .define(name.string().to_owned(), arg);
125        }
126        for stmt in &self.declaration.body {
127            if let Some(value) = stmt.execute(&state)? {
128                return Ok(value);
129            }
130        }
131        Ok(Value::Nil)
132    }
133
134    fn bind(&self, instance: &'static RefCell<Instance>) -> Function {
135        let scope = self.closure.start_scope();
136        scope
137            .environment
138            .borrow_mut()
139            .define("this".to_string(), Value::Instance(instance));
140        Function {
141            declaration: self.declaration.clone(),
142            closure: scope,
143            is_initialiser: self.is_initialiser,
144        }
145    }
146}
147
148impl PartialEq for Function {
149    fn eq(&self, other: &Self) -> bool {
150        self.declaration == other.declaration
151    }
152}
153
154#[derive(Debug, Clone, PartialEq)]
155struct Class {
156    name: String,
157    superclass: Option<Rc<Class>>,
158    methods: HashMap<String, Function>,
159}
160
161impl Class {
162    const fn new(
163        name: String,
164        superclass: Option<Rc<Class>>,
165        methods: HashMap<String, Function>,
166    ) -> Class {
167        Class {
168            name,
169            superclass,
170            methods,
171        }
172    }
173
174    fn find_method(&self, name: &str) -> Option<&Function> {
175        self.methods.get(name).map_or_else(
176            || {
177                self.superclass
178                    .as_ref()
179                    .and_then(|superclass| superclass.find_method(name))
180            },
181            Some,
182        )
183    }
184
185    fn arity(&self) -> usize {
186        self.find_method("init")
187            .map_or(0, |f| f.declaration.params.len())
188    }
189}
190
191#[derive(Clone, PartialEq)]
192struct Instance {
193    class: Rc<Class>,
194    fields: HashMap<String, Value>,
195}
196
197impl Instance {
198    fn new(class: Rc<Class>) -> Instance {
199        Instance {
200            class,
201            fields: HashMap::new(),
202        }
203    }
204
205    fn set(&mut self, name: &Ident, value: Value) {
206        self.fields.insert(name.string().to_string(), value);
207    }
208}
209
210fn get(instance: &'static RefCell<Instance>, name: &Ident) -> Result<Value> {
211    let this = instance.borrow();
212    if let Some(value) = this.fields.get(name.string()) {
213        Ok(value.to_owned())
214    } else if let Some(function) = this.class.find_method(name.string()) {
215        Ok(Value::Function(function.bind(instance)))
216    } else {
217        Err(new_error(
218            format!("Undefined property '{}'", name.string()),
219            name,
220            error_codes::UNDEFINED_NAME,
221        ))
222    }
223}
224
225impl fmt::Debug for Instance {
226    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227        f.debug_struct("Instance")
228            .field("class", &self.class.name)
229            .field("fields", &self.fields)
230            .finish()
231    }
232}
233
234#[derive(Debug, Clone, PartialEq)]
235enum Value {
236    Nil,
237    String(String),
238    Number(f64),
239    Bool(bool),
240    Native(NativeFunction),
241    Function(Function),
242    Class(Rc<Class>),
243    Instance(&'static RefCell<Instance>),
244}
245
246fn arity_error(parentheses: &Parentheses, expected: usize, actual: usize) -> Error {
247    new_error(
248        format!("Expected {expected} arguments but got {actual}"),
249        parentheses.span().to_owned(),
250        error_codes::INCORRECT_ARITY,
251    )
252}
253
254impl Value {
255    const fn as_class(&self) -> Option<&Rc<Class>> {
256        if let Value::Class(class) = self {
257            Some(class)
258        } else {
259            None
260        }
261    }
262
263    const fn as_instance(&self) -> Option<&'static RefCell<Instance>> {
264        if let Value::Instance(instance) = self {
265            Some(*instance)
266        } else {
267            None
268        }
269    }
270
271    const fn is_truthy(&self) -> bool {
272        !matches!(self, Value::Nil | Value::Bool(false))
273    }
274
275    fn add(&self, op: &Punct!["+"], other: &Value) -> Result<Value> {
276        match (self, other) {
277            (Value::Number(n1), Value::Number(n2)) => Ok(Value::Number(n1 + n2)),
278            (Value::String(s1), Value::String(s2)) => Ok(Value::String(s1.to_owned() + s2)),
279            _ => Err(new_error(
280                format!("Can't add '{self}' to '{other}'"),
281                op,
282                error_codes::TYPE_ERROR,
283            )),
284        }
285    }
286
287    fn sub(&self, op: &Punct!["-"], other: &Value) -> Result<Value> {
288        if let (Value::Number(n1), Value::Number(n2)) = (self, other) {
289            Ok(Value::Number(n1 - n2))
290        } else {
291            Err(new_error(
292                format!("Can't subtract '{other}' from '{self}'"),
293                op,
294                error_codes::TYPE_ERROR,
295            ))
296        }
297    }
298
299    fn mul(&self, op: &Punct!["*"], other: &Value) -> Result<Value> {
300        if let (Value::Number(n1), Value::Number(n2)) = (self, other) {
301            Ok(Value::Number(n1 * n2))
302        } else {
303            Err(new_error(
304                format!("Can't multiply '{self}' by '{other}'"),
305                op,
306                error_codes::TYPE_ERROR,
307            ))
308        }
309    }
310
311    fn div(&self, op: &Punct!["/"], other: &Value) -> Result<Value> {
312        if let (Value::Number(n1), Value::Number(n2)) = (self, other) {
313            Ok(Value::Number(n1 / n2))
314        } else {
315            Err(new_error(
316                format!("Can't divide '{other}' by '{self}'"),
317                op,
318                error_codes::TYPE_ERROR,
319            ))
320        }
321    }
322
323    fn neg(&self, op: &Punct!["-"]) -> Result<Value> {
324        if let Value::Number(n) = self {
325            Ok(Value::Number(-n))
326        } else {
327            Err(new_error(
328                format!("Can't negate '{self}'"),
329                op,
330                error_codes::TYPE_ERROR,
331            ))
332        }
333    }
334
335    fn cmp<T: Token>(&self, op: &T, other: &Value) -> Result<Ordering> {
336        if self == other {
337            return Ok(Ordering::Equal);
338        }
339
340        match (self, other) {
341            (Value::String(s1), Value::String(s2)) => Ok(s1.cmp(s2).into()),
342            (Value::Number(n1), Value::Number(n2)) => Ok(n1.partial_cmp(n2).into()),
343            (Value::Bool(b1), Value::Bool(b2)) => Ok(b1.cmp(b2).into()),
344            _ => Err(new_error(
345                format!("Can't compare '{self}' with '{other}'"),
346                op,
347                error_codes::TYPE_ERROR,
348            )),
349        }
350    }
351
352    fn call(&self, arguments: Vec<Value>, parentheses: &Parentheses) -> Result<Value> {
353        match self {
354            Value::Native(NativeFunction {
355                function, arity, ..
356            }) => {
357                if *arity != arguments.len() {
358                    return Err(arity_error(parentheses, *arity, arguments.len()));
359                }
360                function(arguments)
361            }
362            Value::Function(function) => function.call(arguments, parentheses),
363            Value::Class(class) => {
364                if class.arity() != arguments.len() {
365                    return Err(arity_error(parentheses, class.arity(), arguments.len()));
366                }
367
368                let instance = allocate(Instance::new(Rc::clone(class)));
369                if let Some(initialiser) = class.find_method("init") {
370                    initialiser.bind(instance).call(arguments, parentheses)?;
371                }
372                Ok(Value::Instance(instance))
373            }
374            Value::Nil
375            | Value::String(_)
376            | Value::Number(_)
377            | Value::Bool(_)
378            | Value::Instance(_) => Err(new_error(
379                format!("Can't call '{self}'"),
380                parentheses.span().clone(),
381                error_codes::TYPE_ERROR,
382            )),
383        }
384    }
385}
386
387impl fmt::Display for Value {
388    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389        match self {
390            Value::Nil => f.write_str("nil"),
391            Value::String(s) => f.write_str(s),
392            Value::Number(n) => write!(f, "{n}"),
393            Value::Bool(b) => write!(f, "{b}"),
394            Value::Native(NativeFunction { name, .. }) => write!(f, "<native fn '{name}'>"),
395            Value::Function(Function {
396                declaration: FunctionDecl { name, .. },
397                ..
398            }) => write!(f, "<fn {}>", name.string()),
399            Value::Class(class) => f.write_str(&class.name),
400            Value::Instance(instance) => write!(f, "'{}' instance", instance.borrow().class.name),
401        }
402    }
403}
404
405#[derive(Debug, Clone)]
406struct State {
407    environment: Rc<RefCell<Environment>>,
408    globals: Rc<RefCell<Environment>>,
409}
410
411impl State {
412    fn new() -> Self {
413        let mut values = HashMap::new();
414
415        values.insert(
416            "clock".to_string(),
417            Value::Native(NativeFunction {
418                function: natives::clock,
419                arity: 0,
420                name: "clock",
421            }),
422        );
423
424        let environment = Rc::new(RefCell::new(Environment {
425            values,
426            enclosing: None,
427            sub: vec![],
428            mark: Cell::new(false),
429        }));
430
431        State {
432            environment: Rc::clone(&environment),
433            globals: environment,
434        }
435    }
436
437    #[must_use]
438    fn start_scope(&self) -> State {
439        let environment = Rc::new(RefCell::new(Environment {
440            values: HashMap::new(),
441            enclosing: Some(Rc::clone(&self.environment)),
442            sub: vec![],
443            mark: Cell::new(false),
444        }));
445        self.environment
446            .borrow_mut()
447            .sub
448            .push(Rc::downgrade(&environment));
449        State {
450            environment,
451            globals: Rc::clone(&self.globals),
452        }
453    }
454
455    fn super_scope(self) -> Option<State> {
456        Some(State {
457            environment: Rc::clone(self.environment.borrow().enclosing.as_ref()?),
458            globals: self.globals,
459        })
460    }
461}
462
463fn allocate<T>(value: T) -> &'static RefCell<T> {
464    Box::leak(Box::new(RefCell::new(value)))
465}
466
467struct Environment {
468    values: HashMap<String, Value>,
469    enclosing: Option<Rc<RefCell<Environment>>>,
470    sub: Vec<Weak<RefCell<Environment>>>,
471    mark: Cell<bool>,
472}
473
474impl Environment {
475    fn get(&self, name: &Ident) -> Result<Value> {
476        self.values.get(name.string()).map_or_else(
477            || {
478                self.enclosing.as_ref().map_or_else(
479                    || {
480                        Err(new_error(
481                            format!("Undefined variable '{}'", name.string()),
482                            name,
483                            error_codes::UNDEFINED_NAME,
484                        ))
485                    },
486                    |enclosing| enclosing.borrow().get(name),
487                )
488            },
489            |value| Ok(value.to_owned()),
490        )
491    }
492
493    fn get_at(&self, name: &Ident, distance: usize) -> Result<Value> {
494        if distance == 0 {
495            self.get(name)
496        } else {
497            self.enclosing
498                .as_ref()
499                .unwrap()
500                .borrow()
501                .get_at(name, distance - 1)
502        }
503    }
504
505    fn define(&mut self, name: String, value: Value) {
506        self.values.insert(name, value);
507    }
508
509    fn assign(&mut self, name: &Ident, value: Value) -> Result<()> {
510        if self.values.contains_key(name.string()) {
511            self.values.insert(name.string().clone(), value);
512            Ok(())
513        } else if let Some(enclosing) = &self.enclosing {
514            enclosing.borrow_mut().assign(name, value)
515        } else {
516            Err(new_error(
517                format!("Undefined variable '{}'", name.string()),
518                name,
519                error_codes::UNDEFINED_NAME,
520            ))
521        }
522    }
523
524    fn assign_at(&mut self, name: &Ident, value: Value, distance: usize) -> Result<()> {
525        if distance == 0 {
526            self.assign(name, value)
527        } else {
528            self.enclosing
529                .as_ref()
530                .unwrap()
531                .borrow_mut()
532                .assign_at(name, value, distance - 1)
533        }
534    }
535}
536
537struct EnvValuesDebug<'a>(&'a HashMap<String, Value>);
538
539impl fmt::Debug for EnvValuesDebug<'_> {
540    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
541        f.debug_map()
542            .entries(self.0.iter().map(|(k, v)| (k, v.to_string())))
543            .finish()
544    }
545}
546
547impl fmt::Debug for Environment {
548    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
549        f.debug_struct("Environment")
550            .field("values", &EnvValuesDebug(&self.values))
551            .field("enclosing", &self.enclosing)
552            .field("sub", &self.sub)
553            .field("mark", &self.mark)
554            .finish()
555    }
556}
557
558impl Binary {
559    fn evaluate(&self, state: &State) -> Result<Value> {
560        match self {
561            Binary::Mul(left, op, right) => left.evaluate(state)?.mul(op, &right.evaluate(state)?),
562            Binary::Div(left, op, right) => left.evaluate(state)?.div(op, &right.evaluate(state)?),
563            Binary::Add(left, op, right) => left.evaluate(state)?.add(op, &right.evaluate(state)?),
564            Binary::Sub(left, op, right) => left.evaluate(state)?.sub(op, &right.evaluate(state)?),
565            Binary::Equal(left, _, right) => {
566                Ok(Value::Bool(left.evaluate(state)? == right.evaluate(state)?))
567            }
568            Binary::NotEqual(left, _, right) => {
569                Ok(Value::Bool(left.evaluate(state)? != right.evaluate(state)?))
570            }
571            Binary::Greater(left, op, right) => Ok(Value::Bool(
572                left.evaluate(state)?.cmp(op, &right.evaluate(state)?)?.gt(),
573            )),
574            Binary::GreaterEqual(left, op, right) => Ok(Value::Bool(
575                left.evaluate(state)?.cmp(op, &right.evaluate(state)?)?.ge(),
576            )),
577            Binary::Less(left, op, right) => Ok(Value::Bool(
578                left.evaluate(state)?.cmp(op, &right.evaluate(state)?)?.lt(),
579            )),
580            Binary::LessEqual(left, op, right) => Ok(Value::Bool(
581                left.evaluate(state)?.cmp(op, &right.evaluate(state)?)?.le(),
582            )),
583        }
584    }
585}
586
587impl Literal {
588    fn evaluate(&self) -> Value {
589        match self {
590            Literal::False(_) => Value::Bool(false),
591            Literal::Float(value) => Value::Number(value.value()),
592            #[allow(clippy::cast_precision_loss)]
593            Literal::Int(value) => Value::Number(value.value() as f64),
594            Literal::Nil(_) => Value::Nil,
595            Literal::String(string) => Value::String(string.string().clone()),
596            Literal::True(_) => Value::Bool(true),
597        }
598    }
599}
600
601impl Logical {
602    fn evaluate(&self, state: &State) -> Result<Value> {
603        match self {
604            Logical::And(left, _, right) => {
605                let left = left.evaluate(state)?;
606                if left.is_truthy() {
607                    Ok(left)
608                } else {
609                    right.evaluate(state)
610                }
611            }
612            Logical::Or(left, _, right) => {
613                let left = left.evaluate(state)?;
614                if left.is_truthy() {
615                    right.evaluate(state)
616                } else {
617                    Ok(left)
618                }
619            }
620        }
621    }
622}
623
624impl Unary {
625    fn evaluate(&self, state: &State) -> Result<Value> {
626        match self {
627            Unary::Neg(op, expr) => expr.evaluate(state)?.neg(op),
628            Unary::Not(_, expr) => Ok(Value::Bool(!expr.evaluate(state)?.is_truthy())),
629        }
630    }
631}
632
633impl Expr {
634    fn evaluate(&self, state: &State) -> Result<Value> {
635        match self {
636            Expr::Assign {
637                name,
638                value,
639                distance,
640            } => {
641                let value = value.evaluate(state)?;
642                if let Some(distance) = distance.get() {
643                    state
644                        .environment
645                        .borrow_mut()
646                        .assign_at(name, value.clone(), distance)?;
647                } else {
648                    state.globals.borrow_mut().assign(name, value.clone())?;
649                }
650                Ok(value)
651            }
652            Expr::Binary(binary) => binary.evaluate(state),
653            Expr::Call {
654                callee,
655                paren,
656                arguments,
657            } => {
658                let callee = callee.evaluate(state)?;
659                let mut evaluated_args = Vec::with_capacity(arguments.len());
660                for arg in arguments {
661                    evaluated_args.push(arg.evaluate(state)?);
662                }
663                callee.call(evaluated_args, paren)
664            }
665            Expr::Get { object, name } => {
666                if let Value::Instance(instance) = object.evaluate(state)? {
667                    get(instance, name)
668                } else {
669                    Err(new_error(
670                        "Only instances have properties".to_string(),
671                        name,
672                        error_codes::TYPE_ERROR,
673                    ))
674                }
675            }
676            Expr::Group(expr) => expr.evaluate(state),
677            Expr::Literal(literal) => Ok(literal.evaluate()),
678            Expr::Logical(logical) => logical.evaluate(state),
679            Expr::Set {
680                object,
681                name,
682                value,
683            } => {
684                if let Value::Instance(instance) = object.evaluate(state)? {
685                    let value = value.evaluate(state)?;
686                    instance.borrow_mut().set(name, value.clone());
687                    Ok(value)
688                } else {
689                    Err(new_error(
690                        "Only instances have fields".to_string(),
691                        name,
692                        error_codes::TYPE_ERROR,
693                    ))
694                }
695            }
696            Expr::Super {
697                keyword,
698                distance,
699                dot: _,
700                method,
701            } => {
702                let superclass = state
703                    .environment
704                    .borrow()
705                    .get_at(keyword.ident(), distance.clone().into_inner().unwrap())?;
706
707                let object = state.environment.borrow().get_at(
708                    &Ident::new("this".to_string(), keyword.span().clone()),
709                    distance.clone().into_inner().unwrap() - 1,
710                )?;
711
712                superclass
713                    .as_class()
714                    .unwrap()
715                    .find_method(method.string())
716                    .map_or_else(
717                        || {
718                            Err(new_error(
719                                format!("Undefined property '{}'", method.string()),
720                                method,
721                                error_codes::UNDEFINED_NAME,
722                            ))
723                        },
724                        |method| Ok(Value::Function(method.bind(object.as_instance().unwrap()))),
725                    )
726            }
727            Expr::This { keyword, distance } => distance.get().map_or_else(
728                || state.globals.borrow().get(keyword.ident()),
729                |distance| state.environment.borrow().get_at(keyword.ident(), distance),
730            ),
731            Expr::Unary(unary) => unary.evaluate(state),
732            Expr::Variable { name, distance } => distance.get().map_or_else(
733                || state.globals.borrow().get(name),
734                |distance| state.environment.borrow().get_at(name, distance),
735            ),
736        }
737    }
738}
739
740macro_rules! propagate_return {
741    ( $expr:expr ) => {
742        if let Some(_tmp) = $expr {
743            return Ok(Some(_tmp));
744        }
745    };
746}
747
748impl Stmt {
749    fn execute(&self, state: &State) -> Result<Option<Value>> {
750        match self {
751            Stmt::Block(stmts) => {
752                let inner_state = state.start_scope();
753                for stmt in stmts {
754                    propagate_return!(stmt.execute(&inner_state)?);
755                }
756            }
757            Stmt::Class {
758                name,
759                superclass,
760                superclass_distance,
761                methods,
762            } => {
763                let superclass = if let Some(superclass_name) = superclass {
764                    let superclass = Expr::Variable {
765                        name: superclass_name.clone(),
766                        distance: superclass_distance.clone(),
767                    }
768                    .evaluate(state)?;
769                    if let Value::Class(superclass) = superclass {
770                        Some(superclass)
771                    } else {
772                        return Err(new_error(
773                            "Superclass must be a class".to_string(),
774                            superclass_name,
775                            error_codes::INHERIT_FROM_VALUE,
776                        ));
777                    }
778                } else {
779                    None
780                };
781
782                state
783                    .environment
784                    .borrow_mut()
785                    .define(name.string().to_owned(), Value::Nil);
786
787                let superclass_is_some = superclass.is_some();
788                let mut state = superclass.as_ref().map_or_else(
789                    || state.clone(),
790                    |superclass| {
791                        let state = state.start_scope();
792                        state
793                            .environment
794                            .borrow_mut()
795                            .define("super".to_string(), Value::Class(Rc::clone(superclass)));
796                        state
797                    },
798                );
799
800                let methods = methods
801                    .iter()
802                    .map(|declaration| {
803                        (
804                            declaration.name.string().to_owned(),
805                            Function::new(
806                                declaration.clone(),
807                                state.clone(),
808                                declaration.name.string() == "init",
809                            ),
810                        )
811                    })
812                    .collect();
813                let class = Class::new(name.string().to_owned(), superclass, methods);
814
815                if superclass_is_some {
816                    state = state.super_scope().unwrap();
817                }
818
819                state
820                    .environment
821                    .borrow_mut()
822                    .assign(name, Value::Class(Rc::new(class)))?;
823            }
824            Stmt::Expr(expr) => {
825                expr.evaluate(state)?;
826            }
827            Stmt::Function(function) => {
828                let value =
829                    Value::Function(Function::new(function.to_owned(), state.clone(), false));
830                state
831                    .environment
832                    .borrow_mut()
833                    .define(function.name.string().to_owned(), value);
834            }
835            Stmt::If {
836                condition,
837                then_branch,
838                else_branch,
839            } => {
840                if condition.evaluate(state)?.is_truthy() {
841                    propagate_return!(then_branch.execute(state)?);
842                } else if let Some(else_branch) = else_branch {
843                    propagate_return!(else_branch.execute(state)?);
844                }
845            }
846            Stmt::Print(expr) => {
847                let value = expr.evaluate(state)?;
848                println!("{value}");
849            }
850            Stmt::Return { keyword: _, value } => {
851                return Ok(Some(
852                    value
853                        .as_ref()
854                        .map_or(Ok(Value::Nil), |v| v.evaluate(state))?,
855                ));
856            }
857            Stmt::Variable { name, initialiser } => {
858                let value = if let Some(initialiser) = initialiser {
859                    initialiser.evaluate(state)?
860                } else {
861                    Value::Nil
862                };
863                state
864                    .environment
865                    .borrow_mut()
866                    .define(name.string().to_owned(), value);
867            }
868            Stmt::While { condition, body } => {
869                while condition.evaluate(state)?.is_truthy() {
870                    propagate_return!(body.execute(state)?);
871                }
872            }
873        }
874
875        Ok(None)
876    }
877}
878
879pub(super) fn interpret(ast: Ast) -> Result<()> {
880    let state = State::new();
881    for stmt in ast.0 {
882        stmt.execute(&state)?;
883    }
884    Ok(())
885}