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#[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(®istry, 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(®istry, namespace));
141 }
142 }
143 force_lazy_alias(®istry, 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(®istry, namespace));
351 }
352 }
353 force_lazy_alias(®istry, 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()?
599 .current()
600 .unmap(&crate::lang::data::Symbol::parse(&name));
601 env.remove(&name);
602 }
603 }
604 prepare_owned_definition(env, &name)?;
605 let cell = match env.get(&name) {
606 Some(Value::Var(cell)) if binding_is_local(cell) => cell.clone(),
607 _ => KernelVar::new(local_var_name(&name), Value::Nil),
608 };
609 if metadata.is_some() {
610 cell.set_hara_metadata(metadata);
611 }
612 env.insert(name.clone(), Value::Var(cell.clone()));
613 if rest.is_empty() {
614 return Err("defmacro expects a name, parameters, and a body".into());
615 }
616 let function = if matches!(
617 rest.first().map(form_without_metadata),
618 Some(Form::Vector(_))
619 ) {
620 let params = match form_without_metadata(&rest[0]) {
621 Form::Vector(params) => params,
622 _ => unreachable!(),
623 };
624 let mut macro_params =
625 vec![Form::Symbol("&form".into()), Form::Symbol("&env".into())];
626 macro_params.extend_from_slice(params);
627 let (params, variadic, patterns, variadic_pattern) =
628 function_parts(&Form::Vector(macro_params))?;
629 let body = rest[1..].to_vec();
630 Value::Function(Rc::new(Function {
631 params,
632 variadic,
633 patterns,
634 variadic_pattern,
635 captured: Rc::new(RefCell::new(capture_environment(&body, env))),
636 body,
637 name: Some(name.clone()),
638 namespace: function_definition_namespace(),
639 native: None,
640 fiber_native: None,
641 clauses: Vec::new(),
642 metadata: None,
643 is_macro: true,
644 }))
645 } else {
646 let clauses = rest
647 .iter()
648 .map(macro_clause_with_implicit_params)
649 .collect::<Result<Vec<_>, _>>()?;
650 multi_arity_function(&name, &clauses, env, true)?
651 };
652 if let Value::Function(ref function) = function {
653 let namespace = namespace_registry()?.current().name().as_str().to_owned();
654 register_macro(&namespace, &name, function.clone())?;
655 }
656 cell.reset_value(function.clone());
657 cell.set_origin(definition_origin());
658 refresh_schema_contract(&cell)?;
659 Ok(function)
660 }
661 Form::Symbol(n) if n == "defn" => {
662 if fs.len() < 4 {
663 return Err("defn expects a name, parameters, and a body".into());
664 }
665 let (name, metadata) = binding_symbol(&fs[1], "defn name")?;
666 let (metadata, rest) = definition_metadata(metadata, &fs[2..], false, false)
667 .map_err(|error| format!("{name}: {error}"))?;
668 if let Some(schema) = schema_var_reference(metadata.as_deref()) {
669 if binding_var(env, schema.as_str()).is_none() {
670 return Err(format!("schema Var does not exist: {schema}"));
671 }
672 }
673 prepare_owned_definition(env, &name)?;
674 let cell = match env.get(&name) {
675 Some(Value::Var(cell)) if binding_is_local(cell) => cell.clone(),
676 _ => KernelVar::new(local_var_name(&name), Value::Nil),
677 };
678 if metadata.is_some() {
679 cell.set_hara_metadata(metadata);
680 }
681 env.insert(name.clone(), Value::Var(cell.clone()));
682 if rest.is_empty() {
683 return Err("defn expects a name, parameters, and a body".into());
684 }
685 let function = if matches!(
686 rest.first().map(form_without_metadata),
687 Some(Form::Vector(_))
688 ) {
689 let (params, variadic, patterns, variadic_pattern) =
690 function_parts(&rest[0])?;
691 let body = rest[1..].to_vec();
692 Value::Function(Rc::new(Function {
693 params,
694 variadic,
695 patterns,
696 variadic_pattern,
697 captured: Rc::new(RefCell::new(capture_environment(&body, env))),
698 body,
699 name: Some(name.clone()),
700 namespace: function_definition_namespace(),
701 native: None,
702 fiber_native: None,
703 clauses: Vec::new(),
704 metadata: None,
705 is_macro: false,
706 }))
707 } else {
708 multi_arity_function(&name, rest, env, false)?
709 };
710 cell.reset_value(function.clone());
711 cell.set_origin(definition_origin());
712 refresh_schema_contract(&cell)?;
713 Ok(Value::Var(cell))
714 }
715 Form::Symbol(n) if n == "do" => {
716 let mut result = Value::Nil;
717 for form in &fs[1..] {
718 result = eval(form, env)?;
719 if matches!(result, Value::Recur(_)) {
720 return Ok(result);
721 }
722 }
723 Ok(result)
724 }
725 Form::Symbol(n) if n == "declare" => {
726 for form in &fs[1..] {
727 if !matches!(form, Form::Symbol(_)) {
728 return Err("declare expects symbols".into());
729 }
730 }
731 Ok(Value::Nil)
732 }
733 Form::Symbol(n) if n == "ns" || n == "ns+" || n == "require" => {
734 eval_namespace_form(fs, env)
735 }
736 Form::Symbol(n)
737 if resolve_macro(n).is_none()
738 && binding_value(env, n)
739 .is_some_and(|value| matches!(value, Value::Function(_))) =>
740 {
741 let function =
742 binding_value(env, n).expect("namespace function binding was checked");
743 let arguments = fs[1..]
744 .iter()
745 .map(|form| eval(form, env))
746 .collect::<Result<Vec<_>, _>>()?;
747 call_value(function, arguments)
748 }
749 Form::Symbol(n) if n == "." => {
750 if fs.len() != 3 {
751 return Err("dot expects a receiver and method".into());
752 }
753 let receiver = eval(&fs[1], env)?;
754 dot_call(receiver, &fs[2], env)
755 }
756 Form::Symbol(n) if n == "recur" => {
757 if fs.len() < 2 {
758 return Err("recur expects values".into());
759 }
760 Ok(Value::Recur(
761 fs[1..]
762 .iter()
763 .map(|form| eval(form, env))
764 .collect::<Result<Vec<_>, _>>()?,
765 ))
766 }
767 Form::Symbol(n) if n == "binding" => {
768 if fs.len() < 3 {
769 return Err("binding expects bindings and a body".into());
770 }
771 let pairs = match &fs[1] {
772 Form::List(values) | Form::Vector(values) => values,
773 _ => return Err("binding expects a binding list or vector".into()),
774 };
775 if pairs.len() % 2 != 0 {
776 return Err("binding bindings require name/value pairs".into());
777 }
778 let mut pending = Vec::new();
779 for pair in pairs.chunks(2) {
780 let name = match &pair[0] {
781 Form::Symbol(name) => name,
782 _ => return Err("binding name must be a symbol".into()),
783 };
784 let var = binding_var(env, name)
785 .ok_or_else(|| format!("binding expects a Var: {name}"))?;
786 if !var.is_dynamic() {
787 return Err(format!("binding expects a dynamic Var: {name}"));
788 }
789 let value = eval(&pair[1], env)?;
790 pending.push((var, value));
791 }
792 for (var, value) in &pending {
793 var.bind(value.clone());
794 }
795 let bound = pending.into_iter().map(|(var, _)| var).collect::<Vec<_>>();
796 let mut result = Ok(Value::Nil);
797 for form in &fs[2..] {
798 result = eval(form, env);
799 if result.is_err() {
800 break;
801 }
802 }
803 for var in bound.into_iter().rev() {
804 if let Err(error) = var.unbind() {
805 if result.is_ok() {
806 result = Err(error);
807 }
808 }
809 }
810 result
811 }
812 Form::Symbol(n) if n == "loop" => {
813 if fs.len() != 3 {
814 return Err("loop expects bindings and a body".into());
815 }
816 let bindings = match &fs[1] {
817 Form::List(values) | Form::Vector(values) => values,
818 _ => return Err("loop expects a binding list or vector".into()),
819 };
820 if bindings.len() % 2 != 0 {
821 return Err("loop bindings require name/value pairs".into());
822 }
823 let mut previous = Vec::new();
824 let mut patterns = Vec::new();
825 let mut pattern_names = Vec::new();
826 for pair in bindings.chunks(2) {
827 let value = eval(&pair[1], env)?;
828 let before = env.clone();
829 let mut names = Vec::new();
830 bind_pattern(&pair[0], value, env, &mut names, None)
831 .map_err(|error| format!("loop destructuring failed: {error}"))?;
832 for name in &names {
833 previous.push((name.clone(), before.get(name).cloned()));
834 }
835 patterns.push(pair[0].clone());
836 pattern_names.push(names);
837 }
838 let result = loop {
839 match eval(&fs[2], env)? {
840 Value::Recur(values) => {
841 if values.len() != patterns.len() {
842 break Err("loop recur arity mismatch".into());
843 }
844 for names in &pattern_names {
845 for name in names {
846 env.remove(name);
847 }
848 }
849 pattern_names.clear();
850 for (pattern, value) in patterns.iter().zip(values) {
851 let mut names = Vec::new();
852 bind_pattern(pattern, value, env, &mut names, None)?;
853 pattern_names.push(names);
854 }
855 }
856 result => break Ok(result),
857 }
858 };
859 for (name, old) in previous.into_iter().rev() {
860 if let Some(old) = old {
861 env.insert(name, old);
862 } else {
863 env.remove(&name);
864 }
865 }
866 result
867 }
868 Form::Symbol(n) if n == "if" => {
869 if fs.len() != 3 && fs.len() != 4 {
870 return Err("if expects 2 or 3 arguments".into());
871 }
872 if eval(&fs[1], env)?.truthy() {
873 eval(&fs[2], env)
874 } else if fs.len() == 4 {
875 eval(&fs[3], env)
876 } else {
877 Ok(Value::Nil)
878 }
879 }
880 Form::Symbol(n) if n == "and" => {
881 let mut result = Value::Bool(true);
882 for form in &fs[1..] {
883 result = eval(form, env)?;
884 if !result.truthy() {
885 return Ok(result);
886 }
887 }
888 Ok(result)
889 }
890 Form::Symbol(n) if n == "or" => {
891 let mut result = Value::Nil;
892 for form in &fs[1..] {
893 result = eval(form, env)?;
894 if result.truthy() {
895 return Ok(result);
896 }
897 }
898 Ok(result)
899 }
900 Form::Symbol(n) if n == "cond" => {
901 if fs.len() % 2 == 0 {
902 return Err("cond expects test/expression pairs".into());
903 }
904 let mut clauses = fs[1..].chunks_exact(2);
905 for clause in &mut clauses {
906 if eval(&clause[0], env)?.truthy() {
907 return eval(&clause[1], env);
908 }
909 }
910 Ok(Value::Nil)
911 }
912 Form::Symbol(n) if n == "let" => {
913 if fs.len() < 3 {
914 return Err("let expects bindings and a body".into());
915 }
916 let bindings = match &fs[1] {
917 Form::List(values) | Form::Vector(values) => values,
918 _ => return Err("let expects a binding list or vector".into()),
919 };
920 if bindings.len() % 2 != 0 {
921 return Err("let bindings require name/value pairs".into());
922 }
923 let mut previous = Vec::new();
924 for pair in bindings.chunks(2) {
925 let value = eval(&pair[1], env)?;
926 let before = env.clone();
927 let mut names = Vec::new();
928 bind_pattern(&pair[0], value, env, &mut names, None)
929 .map_err(|error| format!("let destructuring failed: {error}"))?;
930 for name in names {
931 previous.push((name.clone(), before.get(&name).cloned()));
932 }
933 }
934 let mut result = Ok(Value::Nil);
935 for body in &fs[2..] {
936 result = eval(body, env);
937 if result.is_err() {
938 break;
939 }
940 }
941 for (name, old) in previous.into_iter().rev() {
942 if let Some(old) = old {
943 env.insert(name, old);
944 } else {
945 env.remove(&name);
946 }
947 }
948 result
949 }
950 _ => {
951 if let Form::Symbol(name) = &fs[0] {
952 if let Some(expanded) = macroexpand_call(name, fs, env)? {
953 return eval(&expanded, env);
954 }
955 }
956 let function = eval(&fs[0], env)?;
957 let arguments = fs[1..]
958 .iter()
959 .map(|form| eval(form, env))
960 .collect::<Result<Vec<_>, _>>()?;
961 call_value(function, arguments)
962 }
963 }
964 }
965 }
966}
967
968pub fn eval_traced(form: &Form, env: &mut HashMap<String, Value>) -> Result<Value, String> {
969 let _guard = StackTraceGuard::enable();
970 eval(form, env).map_err(append_trace)
971}
972
973pub fn eval_text(source: &str, env: &mut HashMap<String, Value>) -> Result<String, String> {
974 Ok(eval_value_text(source, env)?.display())
975}
976
977pub fn eval_text_traced(source: &str, env: &mut HashMap<String, Value>) -> Result<String, String> {
978 let _guard = StackTraceGuard::enable();
979 eval_text(source, env).map_err(append_trace)
980}
981
982pub fn eval_value_text_traced(
983 source: &str,
984 env: &mut HashMap<String, Value>,
985) -> Result<Value, String> {
986 let _guard = StackTraceGuard::enable();
987 eval_value_text(source, env).map_err(append_trace)
988}
989
990pub fn eval_value_text(source: &str, env: &mut HashMap<String, Value>) -> Result<Value, String> {
991 let forms = parse_forms(source)?;
992 let mut result = Value::Nil;
993 for form in forms {
994 result = eval(&form, env)?;
995 if matches!(result, Value::Recur(_)) {
996 return Err("recur must be inside loop".into());
997 }
998 }
999 Ok(result)
1000}