pax_lang/interpreter/
property_resolution.rs1use std::collections::{hash_set, HashMap};
2
3use pax_runtime_api::PaxValue;
4
5use super::{PaxExpression, PaxInfix, PaxPostfix, PaxPrefix, PaxPrimary};
6
7pub 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}