Skip to main content

hara_native/core/
special_forms.rs

1thread_local! {
2    static PRINTER_CAPTURES: RefCell<Vec<String>> = const { RefCell::new(Vec::new()) };
3}
4
5fn printer_write(text: &str) -> Result<(), String> {
6    use std::io::Write;
7    if PRINTER_CAPTURES.with(|captures| {
8        let mut captures = captures.borrow_mut();
9        captures
10            .last_mut()
11            .map(|output| output.push_str(text))
12            .is_some()
13    }) {
14        return Ok(());
15    }
16    print!("{text}");
17    std::io::stdout()
18        .flush()
19        .map_err(|error| format!("Printer output failed: {error}"))
20}
21
22// This compatibility evaluator is also used while loading source-backed
23// namespaces. Keeping its large dispatch match out of line prevents the
24// recursive namespace/evaluator path from multiplying that frame until a
25// normal test or Wasm stack overflows. The fiber evaluator remains the
26// stack-safe execution path for ordinary evaluation.
27#[inline(never)]
28pub fn eval(form: &Form, env: &mut HashMap<String, Value>) -> Result<Value, String> {
29    check_evaluation_interrupt()?;
30    #[cfg(all(feature = "direct-native", not(target_arch = "wasm32")))]
31    if direct_native_execution() {
32        let location = current_exception_site().map_or_else(String::new, |site| {
33            format!(
34                " at {}:{}:{}",
35                site.namespace.as_deref().unwrap_or("<source>"),
36                site.line,
37                site.column
38            )
39        });
40        return Err(format!(
41            "direct-native cannot enter the tree evaluator{location}"
42        ));
43    }
44    match form {
45        Form::Number(v) => Ok(Value::Number(*v)),
46        Form::String(v) => Ok(Value::String(v.clone())),
47        Form::Keyword(v) => Ok(Value::Keyword(v.clone().into())),
48        Form::Nil => Ok(Value::Nil),
49        Form::Bool(value) => Ok(Value::Bool(*value)),
50        Form::Character(value) => Ok(Value::Character(*value)),
51        Form::Float(value) => Ok(Value::Float(crate::numeric::finite_float(*value)?)),
52        Form::BigInteger(value) => Ok(crate::numeric::compact_integer(value.clone())),
53        Form::Regex(value) => Ok(Value::Regex(value.clone())),
54        Form::Tagged(tag, value) if tag == "ptr" => pointer_from_descriptor(literal_value(value)?),
55        Form::Tagged(tag, value) if tag == "uuid" => {
56            crate::core::uuid_tag_value(literal_value(value)?)
57        }
58        Form::Tagged(tag, value) if tag == "arr" => {
59            let Form::Vector(values) = value.as_ref() else {
60                return Err("#arr expects a vector literal".into());
61            };
62            Ok(Value::Array(Rc::new(RefCell::new(
63                values
64                    .iter()
65                    .map(|value| eval(value, env))
66                    .collect::<Result<Vec<_>, _>>()?,
67            ))))
68        }
69        Form::Tagged(tag, value) if tag == "obj" => {
70            let Form::Map(entries) = value.as_ref() else {
71                return Err("#obj expects a map literal".into());
72            };
73            Ok(Value::Object(Rc::new(RefCell::new(
74                entries
75                    .iter()
76                    .map(|(key, value)| {
77                        Ok((marker_key(&eval(key, env)?, "#obj")?, eval(value, env)?))
78                    })
79                    .collect::<Result<Vec<_>, String>>()?,
80            ))))
81        }
82        Form::Tagged(tag, value) => Ok(Value::Tagged(Box::new(PTaggedLiteral::new(
83            Symbol::parse(tag),
84            literal_value(value)?,
85        )))),
86        Form::Metadata(metadata, value) => {
87            if let Some((line, column)) = exception_location_from_metadata(metadata) {
88                with_exception_site(
89                    exception_site_at(line, column).expect("exception site always exists"),
90                    || eval(value, env),
91                )
92            } else {
93                eval(value, env)
94            }
95        }
96        Form::List(fs)
97            if fs.len() == 2 && matches!(&fs[0], Form::Symbol(name) if name == "syntax-quote") =>
98        {
99            syntax_quote_value(&fs[1], env)
100        }
101        Form::List(fs)
102            if fs.len() == 2 && matches!(&fs[0], Form::Symbol(name) if name == "quote") =>
103        {
104            literal_value(&fs[1])
105        }
106        Form::List(fs) if matches!(fs.first(), Some(Form::Symbol(name)) if name == "comment") => {
107            Ok(Value::Nil)
108        }
109        Form::Map(values) => Ok(Value::Map(
110            values
111                .iter()
112                .map(|(key, value)| Ok((eval(key, env)?, eval(value, env)?)))
113                .collect::<Result<_, String>>()?,
114        )),
115        Form::Set(values) => Ok(Value::OrderedSet(Box::new(
116            unique_values(
117                values
118                    .iter()
119                    .map(|value| eval(value, env))
120                    .collect::<Result<_, _>>()?,
121            )
122            .into_iter()
123            .collect(),
124        ))),
125        Form::Vector(values) => vector_literal(
126            values
127                .iter()
128                .map(|value| eval(value, env))
129                .collect::<Result<_, _>>()?,
130        ),
131        Form::Symbol(n) if n == "nil" => Ok(Value::Nil),
132        Form::Symbol(n) if n == "true" => Ok(Value::Bool(true)),
133        Form::Symbol(n) if n == "false" => Ok(Value::Bool(false)),
134        Form::Symbol(n) => {
135            if n.contains('/') {
136                if let Ok(registry) = namespace_registry() {
137                    ensure_foundation_namespace_for_symbol(&registry, env, n)?;
138                    if let Some((namespace, _)) = n.split_once('/') {
139                        if registry.load_state(namespace) == Some(NamespaceLoadState::Failed) {
140                            return Err(previously_failed_error(&registry, namespace));
141                        }
142                    }
143                    force_lazy_alias(&registry, env, n)?;
144                }
145            }
146            if let Some(value) = binding_value(env, n) {
147                return Ok(value);
148            }
149            if !n.contains('/') {
150                if let Ok(registry) = namespace_registry() {
151                    if let Some((_, namespace)) = registry
152                        .current()
153                        .aliases()
154                        .into_iter()
155                        .find(|(alias, _)| alias.as_str() == n)
156                    {
157                        return Ok(Value::Namespace(Rc::new(namespace)));
158                    }
159                    if let Some(namespace) = registry.find(n) {
160                        return Ok(Value::Namespace(Rc::new(namespace)));
161                    }
162                }
163            }
164            Err(format!("unbound symbol: {n}"))
165        }
166        Form::List(fs) if fs.is_empty() => Ok(Value::List(PList::new())),
167        Form::List(fs) => {
168            let operator = &fs[0];
169            if let Form::Symbol(name) = operator {
170                if foundation_fallback_omitted(env, name) {
171                    return Err(format!("unbound symbol: {name}"));
172                }
173            }
174            match operator {
175                Form::Symbol(n) if n == "fn" => {
176                    if fs.len() < 3 {
177                        return Err("fn expects parameters and a body".into());
178                    }
179                    if !matches!(form_without_metadata(&fs[1]), Form::Vector(_)) {
180                        return multi_arity_function("<anonymous>", &fs[1..], env, false);
181                    }
182                    let (params, variadic, patterns, variadic_pattern) = function_parts(&fs[1])?;
183                    let body = fs[2..].to_vec();
184                    Ok(Value::Function(Rc::new(Function {
185                        params,
186                        variadic,
187                        patterns,
188                        variadic_pattern,
189                        captured: Rc::new(RefCell::new(capture_environment(&body, env))),
190                        body,
191                        name: None,
192                        namespace: function_definition_namespace(),
193                        native: None,
194                        fiber_native: None,
195                        clauses: Vec::new(),
196                        metadata: None,
197                        is_macro: false,
198                    })))
199                }
200                Form::Symbol(n) if n == "letfn" => {
201                    if fs.len() < 3 {
202                        return Err("letfn expects a function binding vector and a body".into());
203                    }
204                    let definitions = match &fs[1] {
205                        Form::Vector(values) => values,
206                        _ => {
207                            return Err("letfn expects a function binding vector and a body".into())
208                        }
209                    };
210                    let mut capture_forms = fs[2..].to_vec();
211                    capture_forms.extend(definitions.iter().cloned());
212                    let captured = Rc::new(RefCell::new(capture_environment(&capture_forms, env)));
213                    let mut functions = Vec::with_capacity(definitions.len());
214                    let mut names = std::collections::HashSet::new();
215                    for definition in definitions {
216                        let Form::List(parts) = definition else {
217                            return Err(
218                                "letfn definitions must be (name [arguments] body...)".into()
219                            );
220                        };
221                        if parts.len() < 3 {
222                            return Err(
223                                "letfn definitions must be (name [arguments] body...)".into()
224                            );
225                        }
226                        let Form::Symbol(name) = &parts[0] else {
227                            return Err("letfn names must be unqualified symbols".into());
228                        };
229                        if name.contains('/') {
230                            return Err("letfn names must be unqualified symbols".into());
231                        }
232                        if !names.insert(name.clone()) {
233                            return Err(format!("Duplicate letfn name: {name}"));
234                        }
235                        let (params, variadic, patterns, variadic_pattern) =
236                            function_parts(&parts[1])
237                                .map_err(|_| "letfn parameters must be a binding vector")?;
238                        functions.push((
239                            name.clone(),
240                            Value::Function(Rc::new(Function {
241                                params,
242                                variadic,
243                                patterns,
244                                variadic_pattern,
245                                body: parts[2..].to_vec(),
246                                captured: captured.clone(),
247                                name: Some(name.clone()),
248                                namespace: function_definition_namespace(),
249                                native: None,
250                                fiber_native: None,
251                                clauses: Vec::new(),
252                                metadata: None,
253                                is_macro: false,
254                            })),
255                        ));
256                    }
257                    for (name, function) in &functions {
258                        captured.borrow_mut().insert(name.clone(), function.clone());
259                    }
260                    let mut previous = Vec::with_capacity(functions.len());
261                    for (name, function) in functions {
262                        previous.push((name.clone(), env.insert(name, function)));
263                    }
264                    let mut result = Ok(Value::Nil);
265                    for body in &fs[2..] {
266                        result = eval(body, env);
267                        if result.is_err() {
268                            break;
269                        }
270                    }
271                    for (name, old) in previous.into_iter().rev() {
272                        if let Some(old) = old {
273                            env.insert(name, old);
274                        } else {
275                            env.remove(&name);
276                        }
277                    }
278                    result
279                }
280                Form::Symbol(n) if n == "read-forms" => {
281                    if fs.len() != 2 {
282                        return Err("read-forms expects a path string".into());
283                    }
284                    let path = match eval(&fs[1], env)? {
285                        Value::String(path) => path,
286                        _ => return Err("read-forms expects a path string".into()),
287                    };
288                    if !(path.ends_with(".hal") || path.ends_with(".hrl")) {
289                        return Err("read-forms expects a .hal or .hrl path".into());
290                    }
291                    let promise = file_provider("read-forms")?
292                        .read(&path)
293                        .map_err(|error| file_error("read-forms", error))?;
294                    let bytes = match promise.wait_state() {
295                        PromiseState::Fulfilled(Value::Bytes(bytes)) => bytes,
296                        PromiseState::Fulfilled(Value::ByteBuffer(bytes)) => bytes.borrow().clone(),
297                        PromiseState::Fulfilled(value) => {
298                            return Err(format!(
299                                "read-forms expected file bytes, got {}",
300                                value.display()
301                            ))
302                        }
303                        PromiseState::Rejected(error) => {
304                            return Err(promise_rejection_error(error))
305                        }
306                        PromiseState::Pending => {
307                            return Err("read-forms file read is still pending".into())
308                        }
309                    };
310                    let source = String::from_utf8(bytes)
311                        .map_err(|_| format!("read-forms source is not UTF-8: {path}"))?;
312                    let forms = crate::kernel::parse_forms(&source)
313                        .map_err(|error| format!("read-forms failed: {error}"))?;
314                    let values = forms
315                        .iter()
316                        .map(form_to_value)
317                        .collect::<Result<Vec<_>, _>>()?;
318                    Ok(Value::Vector(PVector::from_iter(values)))
319                }
320                Form::Symbol(n) if n.ends_with("/var-sym") => {
321                    if fs.len() != 2 {
322                        return Err("var-sym expects one var".into());
323                    }
324                    let target = match &fs[1] {
325                        Form::Symbol(name) => match env.get(name) {
326                            Some(Value::Var(var)) => Value::Var(var.clone()),
327                            _ => eval(&fs[1], env)?,
328                        },
329                        _ => eval(&fs[1], env)?,
330                    };
331                    match target {
332                        Value::Var(var) => Ok(Value::Symbol(var.symbol().clone())),
333                        value => Err(format!("var-sym expects a var, got {}", value.display())),
334                    }
335                }
336                Form::Symbol(n) if n == "var" => {
337                    if fs.len() != 2 {
338                        return Err("var expects a symbol".into());
339                    }
340                    let name = match &fs[1] {
341                        Form::Symbol(name) => name,
342                        _ => return Err("var expects a symbol".into()),
343                    };
344                    if name.contains('/') {
345                        if let Ok(registry) = namespace_registry() {
346                            if let Some((namespace, _)) = name.split_once('/') {
347                                if registry.load_state(namespace)
348                                    == Some(NamespaceLoadState::Failed)
349                                {
350                                    return Err(previously_failed_error(&registry, namespace));
351                                }
352                            }
353                            force_lazy_alias(&registry, env, name)?;
354                        }
355                    }
356                    let cell =
357                        binding_var(env, name).ok_or_else(|| format!("unbound symbol: {name}"))?;
358                    Ok(Value::Var(cell))
359                }
360                Form::Symbol(n) if n == "set!" || n == "var/set" => {
361                    if fs.len() != 3 {
362                        return Err(format!("{n} expects a symbol and value"));
363                    }
364                    if n == "set!" {
365                        if let Form::List(place) = &fs[1] {
366                            if matches!(place.first(), Some(Form::Symbol(operation)) if operation == "field")
367                            {
368                                if place.len() != 3 {
369                                    return Err(
370                                        "set! field place expects a receiver and field".into()
371                                    );
372                                }
373                                let field = match &place[2] {
374                                    Form::Keyword(field) if !field.contains('/') => field.as_str(),
375                                    Form::Symbol(field) if !field.contains('/') => field.as_str(),
376                                    _ => {
377                                        return Err(
378                                            "set! field place expects an unqualified literal field"
379                                                .into(),
380                                        )
381                                    }
382                                };
383                                let receiver = eval(&place[1], env)?;
384                                let replacement = eval(&fs[2], env)?;
385                                return mutable_field_set(&receiver, field, replacement);
386                            }
387                        }
388                    }
389                    let name = match &fs[1] {
390                        Form::Symbol(name) => name,
391                        _ => return Err(format!("{n} expects a symbol")),
392                    };
393                    let value = eval(&fs[2], env)?;
394                    let cell =
395                        binding_var(env, name).ok_or_else(|| format!("unbound var: {name}"))?;
396                    if !binding_is_local(&cell) {
397                        return Err(format!(
398                            "Cannot replace referred Var without ns omission: {name}"
399                        ));
400                    }
401                    cell.reset_value(value.clone());
402                    Ok(value)
403                }
404                Form::Symbol(n) if n == "throw" => {
405                    if fs.len() != 2 {
406                        return Err("throw expects one value".into());
407                    }
408                    let value = eval(&fs[1], env)?;
409                    if !matches!(value, Value::ExceptionInfo(_)) {
410                        return Err("throw expects an Exception value created by ex".into());
411                    }
412                    Err(thrown_error(value))
413                }
414                Form::Symbol(n) if n == "try" => {
415                    if fs.len() < 2 {
416                        return Err("try expects a body".into());
417                    }
418                    let mut body = Vec::new();
419                    let mut catch_forms = Vec::new();
420                    let mut finally_forms = Vec::new();
421                    let mut clauses_started = false;
422                    for form in &fs[1..] {
423                        match form {
424                            Form::List(parts)
425                                if !parts.is_empty()
426                                    && matches!(&parts[0],Form::Symbol(name) if name=="catch") =>
427                            {
428                                clauses_started = true;
429                                catch_forms.push(parts)
430                            }
431                            Form::List(parts)
432                                if !parts.is_empty()
433                                    && matches!(&parts[0],Form::Symbol(name) if name=="finally") =>
434                            {
435                                clauses_started = true;
436                                finally_forms.extend_from_slice(&parts[1..])
437                            }
438                            _ if !clauses_started => body.push(form),
439                            _ => return Err("try clauses must follow the body".into()),
440                        }
441                    }
442                    let mut result = Ok(Value::Nil);
443                    for form in body {
444                        result = eval(form, env);
445                        if result.is_err() {
446                            break;
447                        }
448                    }
449                    if let Err(ref error) = result {
450                        for parts in catch_forms {
451                            if parts.len() < 3 {
452                                return Err("catch expects a selector, name, and body".into());
453                            }
454                            let (selector, binding_index, body_index) = match parts.as_slice() {
455                                [_, Form::Symbol(name), _]
456                                    if name != "Exception" && name != "Throwable" =>
457                                {
458                                    ("Exception".to_owned(), 1, 2)
459                                }
460                                [_, Form::Symbol(name), body, ..]
461                                    if name != "Exception"
462                                        && name != "Throwable"
463                                        && !matches!(body, Form::Symbol(_)) =>
464                                {
465                                    ("Exception".to_owned(), 1, 2)
466                                }
467                                [_, Form::Symbol(class), Form::Symbol(_), ..] => {
468                                    (class.clone(), 2, 3)
469                                }
470                                [_, Form::Keyword(code), Form::Symbol(_), ..]
471                                    if code.contains('/') =>
472                                {
473                                    (format!(":{code}"), 2, 3)
474                                }
475                                [_, Form::Vector(codes), Form::Symbol(_), ..]
476                                    if !codes.is_empty()
477                                        && codes.iter().all(|code| matches!(code, Form::Keyword(name) if name.contains('/'))) =>
478                                {
479                                    let selectors = codes
480                                        .iter()
481                                        .map(|code| match code {
482                                            Form::Keyword(name) => format!(":{name}"),
483                                            _ => unreachable!(),
484                                        })
485                                        .collect::<Vec<_>>()
486                                        .join(",");
487                                    (format!("[{selectors}]"), 2, 3)
488                                }
489                                _ => return Err("catch selector must be a namespaced keyword, a non-empty vector of namespaced keywords, or omitted".into()),
490                            };
491                            if !catch_matches(error, &selector) {
492                                continue;
493                            }
494                            let name = match &parts[binding_index] {
495                                Form::Symbol(name) => name.clone(),
496                                _ => return Err("catch name must be a symbol".into()),
497                            };
498                            let old = env.insert(name.clone(), caught_error(error));
499                            result = Ok(Value::Nil);
500                            for form in &parts[body_index..] {
501                                result = eval(form, env);
502                                if result.is_err() {
503                                    break;
504                                }
505                            }
506                            if let Some(old) = old {
507                                env.insert(name, old);
508                            } else {
509                                env.remove(&name);
510                            }
511                            break;
512                        }
513                    }
514                    for form in finally_forms {
515                        let final_result = eval(&form, env);
516                        if final_result.is_err() {
517                            result = final_result;
518                        }
519                    }
520                    result
521                }
522                Form::Symbol(n) if n == "def" => {
523                    if fs.len() != 3 {
524                        return Err("def expects a name and value".into());
525                    }
526                    let (name, metadata) = binding_symbol(&fs[1], "def name")?;
527                    prepare_owned_definition(env, &name)?;
528                    let value = eval(&fs[2], env)?;
529                    let var = if namespace_registry().is_ok() {
530                        let var = vm_def_global(&name, value, metadata)?;
531                        env.insert(name, Value::Var(var.clone()));
532                        var
533                    } else if let Some(Value::Var(var)) = env.get(&name) {
534                        if !binding_is_local(var) {
535                            let var = KernelVar::new(local_var_name(&name), value.clone());
536                            var.set_origin(definition_origin());
537                            var.set_hara_metadata(metadata);
538                            env.insert(name, Value::Var(var.clone()));
539                            var
540                        } else {
541                            var.reset_value(value);
542                            var.set_origin(definition_origin());
543                            if metadata.is_some() {
544                                var.set_hara_metadata(metadata);
545                            }
546                            var.clone()
547                        }
548                    } else {
549                        let var = KernelVar::new(local_var_name(&name), value);
550                        var.set_origin(definition_origin());
551                        var.set_hara_metadata(metadata);
552                        env.insert(name, Value::Var(var.clone()));
553                        var
554                    };
555                    refresh_schema_contract(&var)?;
556                    Ok(Value::Var(var))
557                }
558                Form::Symbol(n) if n == "declare" => {
559                    if fs.len() < 2 {
560                        return Err("declare expects at least one symbol".into());
561                    }
562                    for form in &fs[1..] {
563                        let name = match form {
564                            Form::Symbol(name) => name.clone(),
565                            _ => return Err("declare expects symbols".into()),
566                        };
567                        prepare_owned_definition(env, &name)?;
568                        let cell = match env.get(&name) {
569                            Some(Value::Var(cell)) if binding_is_local(cell) => cell.clone(),
570                            _ => KernelVar::new(local_var_name(&name), Value::Nil),
571                        };
572                        cell.set_origin(definition_origin());
573                        env.insert(name, Value::Var(cell));
574                    }
575                    Ok(Value::Nil)
576                }
577                Form::Symbol(n) if n == "field" => {
578                    if fs.len() != 3 {
579                        return Err("field expects a mutable value and field name".into());
580                    }
581                    let field = match &fs[2] {
582                        Form::Keyword(field) | Form::Symbol(field) if !field.contains('/') => field,
583                        _ => {
584                            return Err("field name must be an unqualified keyword or symbol".into())
585                        }
586                    };
587                    let value = eval(&fs[1], env)?;
588                    mutable_field_value(&value, field)
589                }
590                Form::Symbol(n) if n == "defmacro" => {
591                    if fs.len() < 3 {
592                        return Err("defmacro expects a name, parameters, and a body".into());
593                    }
594                    let (name, metadata) = binding_symbol(&fs[1], "defmacro name")?;
595                    let (metadata, rest) = definition_metadata(metadata, &fs[2..], false, true)?;
596                    if let Some(Value::Var(var)) = env.get(&name) {
597                        if var.symbol().get_namespace() == Some("std.foundation")
598                            && namespace_registry()?.current().name().as_str() != "std.foundation"
599                        {
600                            namespace_registry()?
601                                .current()
602                                .unmap(&crate::lang::data::Symbol::parse(&name));
603                            env.remove(&name);
604                        }
605                    }
606                    prepare_owned_definition(env, &name)?;
607                    let cell = match env.get(&name) {
608                        Some(Value::Var(cell)) if binding_is_local(cell) => cell.clone(),
609                        _ => KernelVar::new(local_var_name(&name), Value::Nil),
610                    };
611                    if metadata.is_some() {
612                        cell.set_hara_metadata(metadata);
613                    }
614                    env.insert(name.clone(), Value::Var(cell.clone()));
615                    if rest.is_empty() {
616                        return Err("defmacro expects a name, parameters, and a body".into());
617                    }
618                    let function = if matches!(
619                        rest.first().map(form_without_metadata),
620                        Some(Form::Vector(_))
621                    ) {
622                        let params = match form_without_metadata(&rest[0]) {
623                            Form::Vector(params) => params,
624                            _ => unreachable!(),
625                        };
626                        let mut macro_params =
627                            vec![Form::Symbol("&form".into()), Form::Symbol("&env".into())];
628                        macro_params.extend_from_slice(params);
629                        let (params, variadic, patterns, variadic_pattern) =
630                            function_parts(&Form::Vector(macro_params))?;
631                        let body = rest[1..].to_vec();
632                        Value::Function(Rc::new(Function {
633                            params,
634                            variadic,
635                            patterns,
636                            variadic_pattern,
637                            captured: Rc::new(RefCell::new(capture_environment(&body, env))),
638                            body,
639                            name: Some(name.clone()),
640                            namespace: function_definition_namespace(),
641                            native: None,
642                            fiber_native: None,
643                            clauses: Vec::new(),
644                            metadata: None,
645                            is_macro: true,
646                        }))
647                    } else {
648                        let clauses = rest
649                            .iter()
650                            .map(macro_clause_with_implicit_params)
651                            .collect::<Result<Vec<_>, _>>()?;
652                        multi_arity_function(&name, &clauses, env, true)?
653                    };
654                    if let Value::Function(ref function) = function {
655                        let namespace = namespace_registry()?.current().name().as_str().to_owned();
656                        register_macro(&namespace, &name, function.clone())?;
657                    }
658                    cell.reset_value(function.clone());
659                    cell.set_origin(definition_origin());
660                    refresh_schema_contract(&cell)?;
661                    Ok(function)
662                }
663                Form::Symbol(n) if n == "defn" => {
664                    if fs.len() < 4 {
665                        return Err("defn expects a name, parameters, and a body".into());
666                    }
667                    let (name, metadata) = binding_symbol(&fs[1], "defn name")?;
668                    let (metadata, rest) = definition_metadata(metadata, &fs[2..], false, false)
669                        .map_err(|error| format!("{name}: {error}"))?;
670                    if let Some(schema) = schema_var_reference(metadata.as_deref()) {
671                        if binding_var(env, schema.as_str()).is_none() {
672                            return Err(format!("schema Var does not exist: {schema}"));
673                        }
674                    }
675                    prepare_owned_definition(env, &name)?;
676                    let cell = match env.get(&name) {
677                        Some(Value::Var(cell)) if binding_is_local(cell) => cell.clone(),
678                        _ => KernelVar::new(local_var_name(&name), Value::Nil),
679                    };
680                    if metadata.is_some() {
681                        cell.set_hara_metadata(metadata);
682                    }
683                    env.insert(name.clone(), Value::Var(cell.clone()));
684                    if rest.is_empty() {
685                        return Err("defn expects a name, parameters, and a body".into());
686                    }
687                    let function = if matches!(
688                        rest.first().map(form_without_metadata),
689                        Some(Form::Vector(_))
690                    ) {
691                        let (params, variadic, patterns, variadic_pattern) =
692                            function_parts(&rest[0])?;
693                        let body = rest[1..].to_vec();
694                        Value::Function(Rc::new(Function {
695                            params,
696                            variadic,
697                            patterns,
698                            variadic_pattern,
699                            captured: Rc::new(RefCell::new(capture_environment(&body, env))),
700                            body,
701                            name: Some(name.clone()),
702                            namespace: function_definition_namespace(),
703                            native: None,
704                            fiber_native: None,
705                            clauses: Vec::new(),
706                            metadata: None,
707                            is_macro: false,
708                        }))
709                    } else {
710                        multi_arity_function(&name, rest, env, false)?
711                    };
712                    cell.reset_value(function.clone());
713                    cell.set_origin(definition_origin());
714                    refresh_schema_contract(&cell)?;
715                    Ok(Value::Var(cell))
716                }
717                Form::Symbol(n) if n == "do" => {
718                    let mut result = Value::Nil;
719                    for form in &fs[1..] {
720                        result = eval(form, env)?;
721                        if matches!(result, Value::Recur(_)) {
722                            return Ok(result);
723                        }
724                    }
725                    Ok(result)
726                }
727                Form::Symbol(n) if n == "declare" => {
728                    for form in &fs[1..] {
729                        if !matches!(form, Form::Symbol(_)) {
730                            return Err("declare expects symbols".into());
731                        }
732                    }
733                    Ok(Value::Nil)
734                }
735                Form::Symbol(n) if n == "ns" || n == "ns+" || n == "require" => {
736                    eval_namespace_form(fs, env)
737                }
738                Form::Symbol(n)
739                    if resolve_macro(n).is_none()
740                        && binding_value(env, n)
741                            .is_some_and(|value| matches!(value, Value::Function(_))) =>
742                {
743                    let function =
744                        binding_value(env, n).expect("namespace function binding was checked");
745                    let arguments = fs[1..]
746                        .iter()
747                        .map(|form| eval(form, env))
748                        .collect::<Result<Vec<_>, _>>()?;
749                    call_value(function, arguments)
750                }
751                Form::Symbol(n) if n == "." => {
752                    if fs.len() != 3 {
753                        return Err("dot expects a receiver and method".into());
754                    }
755                    let receiver = eval(&fs[1], env)?;
756                    dot_call(receiver, &fs[2], env)
757                }
758                Form::Symbol(n) if n == "recur" => {
759                    if fs.len() < 2 {
760                        return Err("recur expects values".into());
761                    }
762                    Ok(Value::Recur(
763                        fs[1..]
764                            .iter()
765                            .map(|form| eval(form, env))
766                            .collect::<Result<Vec<_>, _>>()?,
767                    ))
768                }
769                Form::Symbol(n) if n == "binding" => {
770                    if fs.len() < 3 {
771                        return Err("binding expects bindings and a body".into());
772                    }
773                    let pairs = match &fs[1] {
774                        Form::List(values) | Form::Vector(values) => values,
775                        _ => return Err("binding expects a binding list or vector".into()),
776                    };
777                    if pairs.len() % 2 != 0 {
778                        return Err("binding bindings require name/value pairs".into());
779                    }
780                    let mut pending = Vec::new();
781                    for pair in pairs.chunks(2) {
782                        let name = match &pair[0] {
783                            Form::Symbol(name) => name,
784                            _ => return Err("binding name must be a symbol".into()),
785                        };
786                        let var = binding_var(env, name)
787                            .ok_or_else(|| format!("binding expects a Var: {name}"))?;
788                        if !var.is_dynamic() {
789                            return Err(format!("binding expects a dynamic Var: {name}"));
790                        }
791                        let value = eval(&pair[1], env)?;
792                        pending.push((var, value));
793                    }
794                    for (var, value) in &pending {
795                        var.bind(value.clone());
796                    }
797                    let bound = pending.into_iter().map(|(var, _)| var).collect::<Vec<_>>();
798                    let mut result = Ok(Value::Nil);
799                    for form in &fs[2..] {
800                        result = eval(form, env);
801                        if result.is_err() {
802                            break;
803                        }
804                    }
805                    for var in bound.into_iter().rev() {
806                        if let Err(error) = var.unbind() {
807                            if result.is_ok() {
808                                result = Err(error);
809                            }
810                        }
811                    }
812                    result
813                }
814                Form::Symbol(n) if n == "loop" => {
815                    if fs.len() != 3 {
816                        return Err("loop expects bindings and a body".into());
817                    }
818                    let bindings = match &fs[1] {
819                        Form::List(values) | Form::Vector(values) => values,
820                        _ => return Err("loop expects a binding list or vector".into()),
821                    };
822                    if bindings.len() % 2 != 0 {
823                        return Err("loop bindings require name/value pairs".into());
824                    }
825                    let mut previous = Vec::new();
826                    let mut patterns = Vec::new();
827                    let mut pattern_names = Vec::new();
828                    for pair in bindings.chunks(2) {
829                        let value = eval(&pair[1], env)?;
830                        let before = env.clone();
831                        let mut names = Vec::new();
832                        bind_pattern(&pair[0], value, env, &mut names, None)
833                            .map_err(|error| format!("loop destructuring failed: {error}"))?;
834                        for name in &names {
835                            previous.push((name.clone(), before.get(name).cloned()));
836                        }
837                        patterns.push(pair[0].clone());
838                        pattern_names.push(names);
839                    }
840                    let result = loop {
841                        match eval(&fs[2], env)? {
842                            Value::Recur(values) => {
843                                if values.len() != patterns.len() {
844                                    break Err("loop recur arity mismatch".into());
845                                }
846                                for names in &pattern_names {
847                                    for name in names {
848                                        env.remove(name);
849                                    }
850                                }
851                                pattern_names.clear();
852                                for (pattern, value) in patterns.iter().zip(values) {
853                                    let mut names = Vec::new();
854                                    bind_pattern(pattern, value, env, &mut names, None)?;
855                                    pattern_names.push(names);
856                                }
857                            }
858                            result => break Ok(result),
859                        }
860                    };
861                    for (name, old) in previous.into_iter().rev() {
862                        if let Some(old) = old {
863                            env.insert(name, old);
864                        } else {
865                            env.remove(&name);
866                        }
867                    }
868                    result
869                }
870                Form::Symbol(n) if n == "if" => {
871                    if fs.len() != 3 && fs.len() != 4 {
872                        return Err("if expects 2 or 3 arguments".into());
873                    }
874                    if eval(&fs[1], env)?.truthy() {
875                        eval(&fs[2], env)
876                    } else if fs.len() == 4 {
877                        eval(&fs[3], env)
878                    } else {
879                        Ok(Value::Nil)
880                    }
881                }
882                Form::Symbol(n) if n == "and" => {
883                    let mut result = Value::Bool(true);
884                    for form in &fs[1..] {
885                        result = eval(form, env)?;
886                        if !result.truthy() {
887                            return Ok(result);
888                        }
889                    }
890                    Ok(result)
891                }
892                Form::Symbol(n) if n == "or" => {
893                    let mut result = Value::Nil;
894                    for form in &fs[1..] {
895                        result = eval(form, env)?;
896                        if result.truthy() {
897                            return Ok(result);
898                        }
899                    }
900                    Ok(result)
901                }
902                Form::Symbol(n) if n == "cond" => {
903                    if fs.len() % 2 == 0 {
904                        return Err("cond expects test/expression pairs".into());
905                    }
906                    let mut clauses = fs[1..].chunks_exact(2);
907                    for clause in &mut clauses {
908                        if eval(&clause[0], env)?.truthy() {
909                            return eval(&clause[1], env);
910                        }
911                    }
912                    Ok(Value::Nil)
913                }
914                Form::Symbol(n) if n == "let" => {
915                    if fs.len() < 3 {
916                        return Err("let expects bindings and a body".into());
917                    }
918                    let bindings = match &fs[1] {
919                        Form::List(values) | Form::Vector(values) => values,
920                        _ => return Err("let expects a binding list or vector".into()),
921                    };
922                    if bindings.len() % 2 != 0 {
923                        return Err("let bindings require name/value pairs".into());
924                    }
925                    let mut previous = Vec::new();
926                    for pair in bindings.chunks(2) {
927                        let value = eval(&pair[1], env)?;
928                        let before = env.clone();
929                        let mut names = Vec::new();
930                        bind_pattern(&pair[0], value, env, &mut names, None)
931                            .map_err(|error| format!("let destructuring failed: {error}"))?;
932                        for name in names {
933                            previous.push((name.clone(), before.get(&name).cloned()));
934                        }
935                    }
936                    let mut result = Ok(Value::Nil);
937                    for body in &fs[2..] {
938                        result = eval(body, env);
939                        if result.is_err() {
940                            break;
941                        }
942                    }
943                    for (name, old) in previous.into_iter().rev() {
944                        if let Some(old) = old {
945                            env.insert(name, old);
946                        } else {
947                            env.remove(&name);
948                        }
949                    }
950                    result
951                }
952                _ => {
953                    if let Form::Symbol(name) = &fs[0] {
954                        if let Some(expanded) = macroexpand_call(name, fs, env)? {
955                            return eval(&expanded, env);
956                        }
957                    }
958                    let function = eval(&fs[0], env)?;
959                    let arguments = fs[1..]
960                        .iter()
961                        .map(|form| eval(form, env))
962                        .collect::<Result<Vec<_>, _>>()?;
963                    call_value(function, arguments)
964                }
965            }
966        }
967    }
968}
969
970pub fn eval_traced(form: &Form, env: &mut HashMap<String, Value>) -> Result<Value, String> {
971    let _guard = StackTraceGuard::enable();
972    eval(form, env).map_err(append_trace)
973}
974
975pub fn eval_text(source: &str, env: &mut HashMap<String, Value>) -> Result<String, String> {
976    Ok(eval_value_text(source, env)?.display())
977}
978
979pub fn eval_text_traced(source: &str, env: &mut HashMap<String, Value>) -> Result<String, String> {
980    let _guard = StackTraceGuard::enable();
981    eval_text(source, env).map_err(append_trace)
982}
983
984pub fn eval_value_text_traced(
985    source: &str,
986    env: &mut HashMap<String, Value>,
987) -> Result<Value, String> {
988    let _guard = StackTraceGuard::enable();
989    eval_value_text(source, env).map_err(append_trace)
990}
991
992pub fn eval_value_text(source: &str, env: &mut HashMap<String, Value>) -> Result<Value, String> {
993    let forms = parse_forms(source)?;
994    let mut result = Value::Nil;
995    for form in forms {
996        result = eval(&form, env)?;
997        if matches!(result, Value::Recur(_)) {
998            return Err("recur must be inside loop".into());
999        }
1000    }
1001    Ok(result)
1002}