code_moniker_core/lang/sdk/
scope.rs1use std::collections::BTreeMap;
2
3use crate::core::moniker::Moniker;
4
5#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
6pub enum Namespace {
7 Unified,
8 Value,
9 Type,
10 Macro,
11 Lifetime,
12 Module,
13 Schema,
14 Custom(&'static str),
15}
16
17#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
18pub struct ScopeId(pub usize);
19
20#[derive(Clone, Debug, Default, Eq, PartialEq)]
21pub struct Rib {
22 bindings: BTreeMap<Vec<u8>, Vec<Moniker>>,
23}
24
25impl Rib {
26 pub fn insert(&mut self, name: impl Into<Vec<u8>>, target: Moniker) {
27 self.bindings.entry(name.into()).or_default().push(target);
28 }
29
30 pub fn get(&self, name: &[u8]) -> &[Moniker] {
31 self.bindings
32 .get(name)
33 .map(Vec::as_slice)
34 .unwrap_or_default()
35 }
36
37 pub fn is_empty(&self) -> bool {
38 self.bindings.is_empty()
39 }
40}
41
42#[derive(Clone, Debug, Eq, PartialEq)]
43pub struct Scope {
44 pub id: ScopeId,
45 pub parent: Option<ScopeId>,
46 pub owner: Moniker,
47 ribs: BTreeMap<Namespace, Rib>,
48}
49
50impl Scope {
51 fn new(id: ScopeId, parent: Option<ScopeId>, owner: Moniker) -> Self {
52 Self {
53 id,
54 parent,
55 owner,
56 ribs: BTreeMap::new(),
57 }
58 }
59
60 pub fn insert(&mut self, namespace: Namespace, name: impl Into<Vec<u8>>, target: Moniker) {
61 self.ribs.entry(namespace).or_default().insert(name, target);
62 }
63
64 pub fn rib(&self, namespace: Namespace) -> Option<&Rib> {
65 self.ribs.get(&namespace)
66 }
67}
68
69#[derive(Clone, Debug, Eq, PartialEq)]
70pub struct ScopeTree {
71 scopes: Vec<Scope>,
72}
73
74impl ScopeTree {
75 pub fn new(root_owner: Moniker) -> Self {
76 Self {
77 scopes: vec![Scope::new(ScopeId(0), None, root_owner)],
78 }
79 }
80
81 pub fn root(&self) -> ScopeId {
82 ScopeId(0)
83 }
84
85 pub fn add_scope(&mut self, parent: ScopeId, owner: Moniker) -> ScopeId {
86 let id = ScopeId(self.scopes.len());
87 self.scopes.push(Scope::new(id, Some(parent), owner));
88 id
89 }
90
91 pub fn scope(&self, id: ScopeId) -> Option<&Scope> {
92 self.scopes.get(id.0)
93 }
94
95 pub fn scope_mut(&mut self, id: ScopeId) -> Option<&mut Scope> {
96 self.scopes.get_mut(id.0)
97 }
98
99 pub fn resolve(&self, start: ScopeId, namespace: Namespace, name: &[u8]) -> &[Moniker] {
100 let mut current = Some(start);
101 while let Some(id) = current {
102 let Some(scope) = self.scope(id) else {
103 break;
104 };
105 if let Some(rib) = scope.rib(namespace) {
106 let targets = rib.get(name);
107 if !targets.is_empty() {
108 return targets;
109 }
110 }
111 current = scope.parent;
112 }
113 &[]
114 }
115}