devalang_wasm/language/preprocessor/resolver/
value.rs1use crate::language::syntax::ast::Value;
2use std::collections::HashMap;
3
4pub fn resolve_value(value: &Value, variables: &HashMap<String, Value>, depth: usize) -> Value {
6 const MAX_DEPTH: usize = 32;
7
8 if depth > MAX_DEPTH {
9 return value.clone();
10 }
11
12 match value {
13 Value::Identifier(name) => {
14 if let Some(resolved) = variables.get(name) {
15 resolve_value(resolved, variables, depth + 1)
17 } else {
18 value.clone()
19 }
20 }
21 Value::Map(map) => {
22 let mut resolved_map = HashMap::new();
23 for (k, v) in map {
24 resolved_map.insert(k.clone(), resolve_value(v, variables, depth + 1));
25 }
26 Value::Map(resolved_map)
27 }
28 Value::Array(arr) => {
29 let resolved: Vec<Value> = arr
30 .iter()
31 .map(|v| resolve_value(v, variables, depth + 1))
32 .collect();
33 Value::Array(resolved)
34 }
35 _ => value.clone(),
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn test_resolve_identifier() {
45 let mut vars = HashMap::new();
46 vars.insert("x".to_string(), Value::Number(42.0));
47
48 let result = resolve_value(&Value::Identifier("x".to_string()), &vars, 0);
49 assert!(matches!(result, Value::Number(n) if (n - 42.0).abs() < f32::EPSILON));
50 }
51
52 #[test]
53 fn test_resolve_chained_identifier() {
54 let mut vars = HashMap::new();
55 vars.insert("x".to_string(), Value::Identifier("y".to_string()));
56 vars.insert("y".to_string(), Value::Number(100.0));
57
58 let result = resolve_value(&Value::Identifier("x".to_string()), &vars, 0);
59 assert!(matches!(result, Value::Number(n) if (n - 100.0).abs() < f32::EPSILON));
60 }
61
62 #[test]
63 fn test_resolve_map() {
64 let mut vars = HashMap::new();
65 vars.insert("gain".to_string(), Value::Number(0.8));
66
67 let mut input_map = HashMap::new();
68 input_map.insert("vol".to_string(), Value::Identifier("gain".to_string()));
69
70 let result = resolve_value(&Value::Map(input_map), &vars, 0);
71 if let Value::Map(m) = result {
72 if let Some(Value::Number(n)) = m.get("vol") {
73 assert!((n - 0.8).abs() < f32::EPSILON);
74 return;
75 }
76 }
77 panic!("Expected resolved map with vol=0.8");
78 }
79}