compose_eval/expression/
block.rs

1use crate::{Eval, Evaluated, Machine};
2use compose_library::diag::SourceResult;
3use compose_syntax::ast::CodeBlock;
4
5impl Eval for CodeBlock<'_> {
6    fn eval(self, vm: &mut Machine) -> SourceResult<Evaluated> {
7        let flow = vm.flow.take();
8        let mut result = Evaluated::unit();
9
10        let statements = self.statements();
11
12        vm.in_scope(|vm| {
13            for statement in statements {
14                result = statement.eval(vm)?;
15                if vm.flow.is_some() {
16                    break;
17                }
18            }
19            SourceResult::Ok(())
20        })?;
21
22        if let Some(flow) = flow {
23            vm.flow = Some(flow);
24        }
25
26        Ok(result)
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use crate::test::assert_eval;
33    use compose_library::Value;
34
35    #[test]
36    fn test_block() {
37        let result = assert_eval(
38            r#"
39            let a = 4;
40            let val = {
41                let a = 3;
42                a + 5;
43            };
44            a + val;
45        "#,
46        );
47
48        assert_eq!(result, Value::Int(12));
49    }
50
51    #[test]
52    fn access_outer_scope() {
53        let result = assert_eval(
54            r#"
55            let a = 4;
56            let val = {
57                a + 5;
58            };
59            val;
60        "#,
61        );
62
63        assert_eq!(result, Value::Int(9));
64    }
65}