1use crate::builtins::form::{form_to_value, resolve_auto_forms};
4use cljrs_reader::Form;
5use cljrs_reader::form::FormKind;
6use cljrs_types::span::Span;
7use cljrs_value::{Symbol, Value};
8use std::sync::Arc;
9
10use crate::env::env::Env;
11use crate::env::error::{EvalError, EvalResult};
12
13pub fn macroexpand_1(form: &Form, env: &mut Env) -> EvalResult<Form> {
15 if let FormKind::List(parts) = &form.kind
17 && let Some(FormKind::Symbol(s)) = parts.first().map(|f| &f.kind)
18 && let Some(macro_fn) = resolve_macro(s, env)
19 {
20 let resolved = resolve_auto_forms(form, env)?;
25 let parts = if let FormKind::List(p) = &resolved.kind {
26 p
27 } else {
28 unreachable!()
29 };
30
31 let env_val = {
33 let (names, vals) = env.all_local_bindings();
34 let mut m = cljrs_value::MapValue::empty();
35 for (name, val) in names.iter().zip(vals.iter()) {
36 m = m.assoc(Value::symbol(Symbol::simple(name.as_ref())), val.clone());
37 }
38 Value::Map(m)
39 };
40
41 let spliced = parts
53 .iter()
54 .any(|f| matches!(f.kind, FormKind::ReaderCond { .. }));
55 let (form_val, arg_vals) = if spliced {
56 let mut arg_vals = Vec::with_capacity(parts.len() - 1);
57 for p in &parts[1..] {
58 arg_vals.push(form_to_value(p)?);
59 }
60 (form_to_value(&resolved)?, arg_vals)
61 } else {
62 let mut vals = Vec::with_capacity(parts.len());
63 for p in parts.iter() {
64 vals.push(form_to_value(p)?);
65 }
66 let form_val = crate::builtins::form::values_to_list(vals.iter().cloned());
67 let arg_vals = vals.split_off(1);
68 (form_val, arg_vals)
69 };
70
71 let mut args = Vec::with_capacity(arg_vals.len() + 2);
72 args.push(form_val);
73 args.push(env_val);
74 args.extend(arg_vals);
75 let expanded = crate::interp::apply::call_cljrs_fn(¯o_fn, &args, env)?;
76 let dummy = Span::new(Arc::new("<macro>".to_string()), 0, 0, 1, 1);
77 return value_to_form(&expanded, dummy);
78 }
79 Ok(form.clone())
80}
81
82pub fn macroexpand(form: &Form, env: &mut Env) -> EvalResult<Form> {
84 let mut current = form.clone();
85 loop {
86 let is_macro_call = matches!(
91 ¤t.kind,
92 FormKind::List(parts)
93 if matches!(parts.first().map(|f| &f.kind), Some(FormKind::Symbol(s)) if resolve_macro(s, env).is_some())
94 );
95 if !is_macro_call {
96 return Ok(current);
97 }
98
99 let expanded = macroexpand_1(¤t, env)?;
100 if expanded == current {
101 return Ok(current);
102 }
103 current = expanded;
104 }
105}
106
107pub fn macroexpand_all(form: &Form, env: &mut Env) -> EvalResult<Form> {
112 let expanded = macroexpand(form, env)?;
114
115 let span = expanded.span.clone();
116 let kind = match &expanded.kind {
117 FormKind::List(parts) if !parts.is_empty() => {
118 let head_name = match &parts[0].kind {
120 FormKind::Symbol(s) => Some(s.as_str()),
121 _ => None,
122 };
123 match head_name {
124 Some("quote") => return Ok(expanded),
126 Some("fn*") => {
128 let mut new_parts = vec![parts[0].clone()];
129 if parts.len() > 1 {
132 if let FormKind::Vector(_) = &parts[1].kind {
133 new_parts.push(parts[1].clone()); for p in &parts[2..] {
136 new_parts.push(macroexpand_all(p, env)?);
137 }
138 } else {
139 for arity in &parts[1..] {
141 if let FormKind::List(arity_parts) = &arity.kind {
142 let mut new_arity = Vec::new();
143 if let Some(params) = arity_parts.first() {
144 new_arity.push(params.clone()); }
146 for p in arity_parts.iter().skip(1) {
147 new_arity.push(macroexpand_all(p, env)?);
148 }
149 new_parts.push(Form::new(
150 FormKind::List(new_arity),
151 arity.span.clone(),
152 ));
153 } else {
154 new_parts.push(arity.clone());
156 }
157 }
158 }
159 }
160 FormKind::List(new_parts)
161 }
162 Some("let*") | Some("loop*") => {
164 let mut new_parts = vec![parts[0].clone()];
165 if parts.len() > 1 {
166 if let FormKind::Vector(bindings) = &parts[1].kind {
168 let mut new_bindings = Vec::new();
169 for (i, b) in bindings.iter().enumerate() {
170 if i % 2 == 0 {
171 new_bindings.push(b.clone()); } else {
173 new_bindings.push(macroexpand_all(b, env)?);
174 }
175 }
176 new_parts.push(Form::new(
177 FormKind::Vector(new_bindings),
178 parts[1].span.clone(),
179 ));
180 } else {
181 new_parts.push(parts[1].clone());
182 }
183 for p in &parts[2..] {
184 new_parts.push(macroexpand_all(p, env)?);
185 }
186 }
187 FormKind::List(new_parts)
188 }
189 _ => {
191 let new_parts = parts
193 .iter()
194 .map(|p| macroexpand_all(p, env))
195 .collect::<EvalResult<Vec<_>>>()?;
196 FormKind::List(new_parts)
197 }
198 }
199 }
200 FormKind::Vector(items) => {
201 let new_items = items
202 .iter()
203 .map(|i| macroexpand_all(i, env))
204 .collect::<EvalResult<Vec<_>>>()?;
205 FormKind::Vector(new_items)
206 }
207 FormKind::Map(items) => {
208 let new_items = items
209 .iter()
210 .map(|i| macroexpand_all(i, env))
211 .collect::<EvalResult<Vec<_>>>()?;
212 FormKind::Map(new_items)
213 }
214 FormKind::Set(items) => {
215 let new_items = items
216 .iter()
217 .map(|i| macroexpand_all(i, env))
218 .collect::<EvalResult<Vec<_>>>()?;
219 FormKind::Set(new_items)
220 }
221 _ => return Ok(expanded),
223 };
224 Ok(Form::new(kind, span))
225}
226
227fn resolve_macro(sym: &str, env: &Env) -> Option<cljrs_value::CljxFn> {
229 let parsed = Symbol::parse(sym);
230 let ns: Arc<str> = env.resolve_ns_or_current(parsed.namespace.as_deref());
231 let name = parsed.name.as_ref();
232
233 let v = env.globals.lookup_in_ns(&ns, name)?;
234 if let Value::Macro(f) = v {
235 Some(f.get().clone())
236 } else {
237 None
238 }
239}
240
241pub fn value_to_form(val: &Value, span: Span) -> EvalResult<Form> {
245 let kind = match val {
246 Value::Nil => FormKind::Nil,
247 Value::Bool(b) => FormKind::Bool(*b),
248 Value::Long(n) => FormKind::Int(*n),
249 Value::Double(f) => FormKind::Float(*f),
250 Value::Str(s) => FormKind::Str(s.get().clone()),
251 Value::Char(c) => FormKind::Char(*c),
252 Value::BigInt(b) => FormKind::BigInt(b.get().to_string()),
253 Value::BigDecimal(d) => FormKind::BigDecimal(d.get().to_string()),
254 Value::Ratio(r) => FormKind::Ratio(format!("{}/{}", r.get().numer(), r.get().denom())),
255
256 Value::Symbol(s) => FormKind::Symbol(s.get().full_name()),
257 Value::Keyword(k) => FormKind::Keyword(k.get().full_name()),
258
259 Value::List(l) => {
260 let items = l.get();
261 let head_sym = items.iter().next().and_then(|v| {
263 if let Value::Symbol(s) = v {
264 Some(s.get().name.clone())
265 } else {
266 None
267 }
268 });
269 match (head_sym.as_deref(), items.count()) {
270 (Some("syntax-quote"), 2) => {
271 let inner = value_to_form(items.iter().nth(1).unwrap(), span.clone())?;
272 FormKind::SyntaxQuote(Box::new(inner))
273 }
274 (Some("unquote"), 2) => {
275 let inner = value_to_form(items.iter().nth(1).unwrap(), span.clone())?;
276 FormKind::Unquote(Box::new(inner))
277 }
278 (Some("unquote-splicing"), 2) => {
279 let inner = value_to_form(items.iter().nth(1).unwrap(), span.clone())?;
280 FormKind::UnquoteSplice(Box::new(inner))
281 }
282 _ => {
283 let forms: Vec<Form> = items
284 .iter()
285 .map(|v| value_to_form(v, span.clone()))
286 .collect::<EvalResult<_>>()?;
287 FormKind::List(forms)
288 }
289 }
290 }
291 Value::Vector(v) => {
292 let forms: Vec<Form> = v
293 .get()
294 .iter()
295 .map(|v| value_to_form(v, span.clone()))
296 .collect::<EvalResult<_>>()?;
297 FormKind::Vector(forms)
298 }
299 Value::Map(m) => {
300 let mut forms = Vec::new();
301 let mut err: Option<EvalError> = None;
302 let sc = span.clone();
303 m.for_each(|k, v| {
304 if err.is_none() {
305 match (value_to_form(k, sc.clone()), value_to_form(v, sc.clone())) {
306 (Ok(kf), Ok(vf)) => {
307 forms.push(kf);
308 forms.push(vf);
309 }
310 (Err(e), _) | (_, Err(e)) => err = Some(e),
311 }
312 }
313 });
314 if let Some(e) = err {
315 return Err(e);
316 }
317 FormKind::Map(forms)
318 }
319 Value::Set(s) => {
320 let forms: Vec<Form> = s
321 .iter()
322 .map(|v| value_to_form(v, span.clone()))
323 .collect::<EvalResult<_>>()?;
324 FormKind::Set(forms)
325 }
326
327 Value::LazySeq(ls) => {
330 return value_to_form(&ls.get().realize(), span);
331 }
332 Value::Cons(c) => {
333 let mut items: Vec<Form> = Vec::new();
334 let mut cur = Value::Cons(c.clone());
335 loop {
336 match cur {
337 Value::Cons(cell) => {
338 items.push(value_to_form(&cell.get().head, span.clone())?);
339 cur = cell.get().tail.clone();
340 }
341 Value::LazySeq(ls) => cur = ls.get().realize(),
342 Value::List(l) => {
343 for v in l.get().iter() {
344 items.push(value_to_form(v, span.clone())?);
345 }
346 break;
347 }
348 Value::Nil => break,
349 _ => break,
350 }
351 }
352 FormKind::List(items)
353 }
354
355 Value::Uuid(u) => {
356 let uuid_str = uuid::Uuid::from_u128(*u).to_string();
357 FormKind::TaggedLiteral(
358 "uuid".to_string(),
359 Box::new(Form::new(FormKind::Str(uuid_str), span.clone())),
360 )
361 }
362
363 Value::WithMeta(inner, meta) => {
370 if matches!(**meta, Value::Nil) {
371 return value_to_form(inner, span);
372 }
373 let inner_form = value_to_form(inner, span.clone())?;
374 let meta_form = value_to_form(meta, span.clone())?;
375 let quoted_meta = Form::new(FormKind::Quote(Box::new(meta_form)), span.clone());
376 FormKind::Meta(Box::new(quoted_meta), Box::new(inner_form))
377 }
378
379 Value::Pattern(p) => FormKind::Regex(p.get().as_str().to_string()),
380
381 other => FormKind::Symbol(format!("#<{}>", other.type_name())),
383 };
384 Ok(Form::new(kind, span))
385}