Skip to main content

code_moniker_core/lang/sdk/
scope.rs

1use 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}