pax_lang/interpreter/
property_resolution.rs

1use std::collections::{hash_set, HashMap};
2
3use pax_runtime_api::PaxValue;
4
5use super::{PaxExpression, PaxInfix, PaxPostfix, PaxPrefix, PaxPrimary};
6
7/// Trait for resolving identifiers to values
8/// This is implemented by RuntimePropertyStackFrame
9pub trait IdentifierResolver {
10    fn resolve(&self, name: String) -> Result<PaxValue, String>;
11}
12
13pub trait DependencyCollector {
14    fn collect_dependencies(&self) -> Vec<String>;
15}
16
17impl DependencyCollector for PaxExpression {
18    fn collect_dependencies(&self) -> Vec<String> {
19        match self {
20            PaxExpression::Primary(p) => p.collect_dependencies(),
21            PaxExpression::Prefix(p) => p.collect_dependencies(),
22            PaxExpression::Infix(p) => p.collect_dependencies(),
23            PaxExpression::Postfix(p) => p.collect_dependencies(),
24        }
25    }
26}
27
28impl DependencyCollector for PaxPrimary {
29    fn collect_dependencies(&self) -> Vec<String> {
30        let ret = match self {
31            PaxPrimary::Literal(_) => vec![],
32            PaxPrimary::Grouped(expr, _) => expr.collect_dependencies(),
33            PaxPrimary::Identifier(i, _) => vec![i.name.clone()],
34            PaxPrimary::Object(o) => o
35                .iter()
36                .flat_map(|(_, v)| v.collect_dependencies())
37                .collect(),
38            PaxPrimary::FunctionOrEnum(_, _, args) => {
39                args.iter().flat_map(|a| a.collect_dependencies()).collect()
40            }
41            PaxPrimary::Range(start, end) => {
42                let mut deps = start.collect_dependencies();
43                deps.extend(end.collect_dependencies());
44                deps
45            }
46            PaxPrimary::Tuple(t) => t.iter().flat_map(|e| e.collect_dependencies()).collect(),
47            PaxPrimary::List(l) => l.iter().flat_map(|e| e.collect_dependencies()).collect(),
48        };
49        let deduped_deps: std::collections::HashSet<String> = ret.into_iter().collect();
50        deduped_deps.into_iter().collect()
51    }
52}
53
54impl DependencyCollector for PaxPrefix {
55    fn collect_dependencies(&self) -> Vec<String> {
56        self.rhs.collect_dependencies()
57    }
58}
59
60impl DependencyCollector for PaxInfix {
61    fn collect_dependencies(&self) -> Vec<String> {
62        let mut deps = self.lhs.collect_dependencies();
63        deps.extend(self.rhs.collect_dependencies());
64        deps
65    }
66}
67
68impl DependencyCollector for PaxPostfix {
69    fn collect_dependencies(&self) -> Vec<String> {
70        self.lhs.collect_dependencies()
71    }
72}
73
74impl IdentifierResolver for HashMap<String, PaxValue> {
75    fn resolve(&self, name: String) -> Result<PaxValue, String> {
76        self.get(&name)
77            .map(|v| v.clone())
78            .ok_or(format!("Identifier not found: {}", name))
79    }
80}