compose_eval/expression/
map.rs

1use crate::{Eval, Evaluated, Machine};
2use compose_library::diag::{bail, SourceResult};
3use compose_library::{MapValue, Value, Vm};
4use compose_syntax::ast;
5use compose_syntax::ast::{AstNode, Expr};
6use std::collections::HashMap;
7
8impl Eval for ast::MapLiteral<'_> {
9    fn eval(self, vm: &mut Machine) -> SourceResult<Evaluated> {
10        let mut map = HashMap::new();
11
12        for entry in self.entries() {
13            let key = match entry.key() {
14                Expr::Ident(i) => i.get().clone(),
15                other => {
16                    let evaluated = other.eval(vm)?;
17
18                    let Value::Str(as_str) = &evaluated.value else {
19                        bail!(entry.key().span(), "map keys must be strings");
20                    };
21
22                    as_str.0.clone()
23                }
24            };
25
26            let value = entry.value().eval(vm)?.value;
27
28            map.insert(key, value);
29        }
30
31        Ok(Evaluated::mutable(Value::Map(MapValue::from(
32            vm.heap_mut(),
33            map.into(),
34        ))))
35    }
36}