compose_eval/expression/
block.rs1use 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}