hara_native/kernel/generated/
rewrite.rs1use super::super::Form;
2use super::{canonical, known_namespace, GeneratedNamespaceConfig};
3
4impl GeneratedNamespaceConfig {
5 pub fn rewrite(&self, form: Form) -> Form {
6 self.rewrite_form(form, false)
7 }
8
9 pub fn rewrite_for_macroexpand(&self, form: Form) -> Form {
13 self.rewrite_form(form, true)
14 }
15
16 fn rewrite_form(&self, form: Form, macro_head: bool) -> Form {
17 match form {
18 Form::Symbol(name) => Form::Symbol(self.resolve_symbol(&name)),
19 Form::List(values) => {
20 if matches!(
21 values.first(),
22 Some(Form::Symbol(name))
23 if name == "quote"
24 || name == "require"
25 || (macro_head && name == "syntax-quote")
26 ) {
27 return Form::List(values);
28 }
29 let mut values = values.into_iter();
30 let Some(head) = values.next() else {
31 return Form::List(Vec::new());
32 };
33 let head = match head {
34 Form::Symbol(name) if macro_head => {
35 Form::Symbol(self.resolve_macro_symbol(&name))
36 }
37 value => self.rewrite_form(value, macro_head),
38 };
39 Form::List(
40 std::iter::once(head)
41 .chain(values.map(|value| self.rewrite_form(value, macro_head)))
42 .collect(),
43 )
44 }
45 Form::Vector(values) => Form::Vector(
46 values
47 .into_iter()
48 .map(|value| self.rewrite_form(value, macro_head))
49 .collect(),
50 ),
51 Form::Set(values) => Form::Set(
52 values
53 .into_iter()
54 .map(|value| self.rewrite_form(value, macro_head))
55 .collect(),
56 ),
57 Form::Map(values) => Form::Map(
58 values
59 .into_iter()
60 .map(|(key, value)| {
61 (
62 self.rewrite_form(key, macro_head),
63 self.rewrite_form(value, macro_head),
64 )
65 })
66 .collect(),
67 ),
68 Form::Tagged(tag, value) => {
69 Form::Tagged(tag, Box::new(self.rewrite_form(*value, macro_head)))
70 }
71 Form::Metadata(meta, value) => {
72 Form::Metadata(meta, Box::new(self.rewrite_form(*value, macro_head)))
73 }
74 value => value,
75 }
76 }
77
78 fn resolve_macro_symbol(&self, symbol: &str) -> String {
79 self.macro_refers
80 .get(symbol)
81 .cloned()
82 .unwrap_or_else(|| self.resolve_symbol(symbol))
83 }
84
85 fn resolve_symbol(&self, symbol: &str) -> String {
86 if let Some(canonical) = crate::core::canonical_native_symbol(symbol) {
87 return canonical;
88 }
89 if let Some(canonical) = self.refers.get(symbol) {
90 return canonical.clone();
91 }
92 if symbol.contains('/') {
93 if let Ok(registry) = crate::core::namespace_registry() {
94 if let Some(variable) = registry.resolve(&crate::lang::data::Symbol::parse(symbol)) {
95 return variable.symbol().as_str().to_owned();
96 }
97 }
98 }
99 let Some((alias, method)) = symbol.split_once('/') else {
100 return symbol.into();
101 };
102 if self.lazy_aliases.contains_key(alias) {
103 return symbol.into();
104 }
105 if let Some(namespace) = self.global_aliases.get(alias) {
106 return canonical(namespace, method);
107 }
108 if let Some(namespace) = self.aliases.get(alias) {
109 return canonical(namespace, method);
110 }
111 if known_namespace(alias) {
112 return canonical(alias, method);
113 }
114 symbol.into()
115 }
116}