Skip to main content

hara_native/core/
value.rs

1#[derive(Debug, Clone, PartialEq, Eq)]
2pub struct ExceptionSite {
3    pub namespace: Option<String>,
4    pub resource: Option<String>,
5    pub line: usize,
6    pub column: usize,
7}
8
9#[derive(Debug, Clone, Default)]
10pub struct ExceptionProvenance {
11    pub created_at: Option<ExceptionSite>,
12    pub throws: Vec<ExceptionSite>,
13}
14
15#[derive(Debug, Clone)]
16pub struct ExceptionInfo {
17    pub message: String,
18    pub data: Box<Value>,
19    pub cause: Option<Box<Value>>,
20    pub provenance: Rc<RefCell<ExceptionProvenance>>,
21}
22
23/// A callable frame collected while an evaluation boundary has tracing
24/// enabled.  Keep this structured until a presentation boundary chooses how
25/// to render it: editor clients need the namespace and source site separately
26/// from the human-readable stack label.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct TraceFrame {
29    pub name: String,
30    pub namespace: Option<String>,
31    pub site: Option<ExceptionSite>,
32}
33
34impl TraceFrame {
35    pub fn label(&self) -> String {
36        let label = self
37            .namespace
38            .as_ref()
39            .map(|namespace| format!("{namespace}/{}", self.name))
40            .unwrap_or_else(|| self.name.clone());
41        match &self.site {
42            Some(site) if site.line > 0 => format!("{label} @ {}:{}", site.line, site.column),
43            _ => label,
44        }
45    }
46}
47
48fn default_exception_class(code: &Keyword) -> Option<Keyword> {
49    if code.get_namespace() != Some("hara") {
50        return None;
51    }
52    let class = match code.get_name() {
53        "security" | "timeout" | "not-found" | "conflict" | "limit" | "syntax" | "io"
54        | "database" | "dependency" | "serialization" | "argument" | "state" | "host" => {
55            code.get_name()
56        }
57        "generic" => "internal",
58        _ => return None,
59    };
60    Keyword::parse(&format!("ex.class/{class}")).ok()
61}
62
63fn normalize_exception_code(code: &Keyword) -> Result<Keyword, String> {
64    if code.get_namespace().is_some() {
65        return Ok(code.clone());
66    }
67    let canonical = Keyword::parse(&format!("hara/{}", code.get_name()))?;
68    if default_exception_class(&canonical).is_some() {
69        Ok(canonical)
70    } else {
71        Err("ex expects a registered standard keyword or namespaced keyword code".into())
72    }
73}
74
75pub(crate) fn record_exception_throw(value: &Value, site: Option<ExceptionSite>) {
76    let (Value::ExceptionInfo(exception), Some(site)) = (value, site) else {
77        return;
78    };
79    let mut provenance = exception.provenance.borrow_mut();
80    provenance.throws.push(site);
81}
82
83pub(crate) fn record_exception_creation(value: &Value, site: Option<ExceptionSite>) {
84    let (Value::ExceptionInfo(exception), Some(site)) = (value, site) else {
85        return;
86    };
87    let mut provenance = exception.provenance.borrow_mut();
88    if provenance.created_at.is_none() {
89        provenance.created_at = Some(site);
90    }
91}
92
93pub(crate) fn exception_site_value(site: &ExceptionSite) -> Value {
94    Value::Map(
95        [
96            (
97                "namespace",
98                site.namespace
99                    .clone()
100                    .map(Value::String)
101                    .unwrap_or(Value::Nil),
102            ),
103            (
104                "resource",
105                site.resource
106                    .clone()
107                    .map(Value::String)
108                    .unwrap_or(Value::Nil),
109            ),
110            ("line", Value::Number(site.line as i64)),
111            ("column", Value::Number(site.column as i64)),
112        ]
113        .into_iter()
114        .map(|(key, value)| (Value::Keyword(key.into()), value))
115        .collect(),
116    )
117}
118
119pub(crate) fn exception_provenance_value(exception: &ExceptionInfo) -> Value {
120    let provenance = exception.provenance.borrow();
121    Value::Map(
122        [
123            (
124                Value::Keyword("ex/created-at".into()),
125                provenance
126                    .created_at
127                    .as_ref()
128                    .map(exception_site_value)
129                    .unwrap_or(Value::Nil),
130            ),
131            (
132                Value::Keyword("ex/throws".into()),
133                Value::Vector(provenance.throws.iter().map(exception_site_value).collect()),
134            ),
135        ]
136        .into_iter()
137        .collect(),
138    )
139}
140
141#[derive(Debug, Clone)]
142pub enum Value {
143    Number(i64),
144    Float(f64),
145    BigInteger(BigInt),
146    Character(char),
147    Regex(String),
148    Tagged(Box<PTaggedLiteral<Value>>),
149    Bool(bool),
150    String(String),
151    Keyword(Keyword),
152    Bytes(Vec<u8>),
153    ByteBuffer(Rc<RefCell<Vec<u8>>>),
154    Array(Rc<RefCell<Vec<Value>>>),
155    Object(Rc<RefCell<Vec<(String, Value)>>>),
156    Promise(Promise),
157    Atom(Box<RuntimeAtom>),
158    Recur(Vec<Value>),
159    Map(PMap<Value, Value>),
160    OrderedMap(Box<POrderedMap<Value, Value>>),
161    SortedMap(Box<PSortedMap<Value, Value>>),
162    Trie(Box<PTrie<Value>>),
163    Set(PSet<Value>),
164    OrderedSet(Box<POrderedSet<Value>>),
165    SortedSet(Box<PSortedSet<Value>>),
166    List(PList<Value>),
167    Cons(Box<PCons<Value>>),
168    Deque(Box<PDeque<Value>>),
169    Queue(Box<PQueue<Value>>),
170    PriorityMap(Box<PPriorityMap<Value, Value>>),
171    Symbol(Symbol),
172    Pointer(PPointer),
173    Function(Rc<Function>),
174    Tuple(Box<PTuple<Value>>),
175    Vector(PVector<Value>),
176    MapEntry(Box<PMapEntry>),
177    MutableCollection(Rc<RefCell<Option<MutableCollection>>>),
178    Seq(Box<PSeq<Result<Value, String>>>),
179    Iterator(Rc<RefCell<IteratorState>>),
180    Var(KernelVar<Value>),
181    Namespace(Rc<crate::kernel::Namespace<Value>>),
182    Extension(ExtensionValue),
183    StructType(Rc<StructType>),
184    Struct(Rc<StructValue>),
185    MutableType(Rc<MutableType>),
186    Mutable(Rc<MutableValue>),
187    Protocol(Rc<GuestProtocol>),
188    NativeType(Rc<NativeType>),
189    Schema(Rc<RuntimeSchema>),
190    Coroutine(Rc<Coroutine>),
191    Stream(Rc<RuntimeStream>),
192    Result(Rc<ResultValue>),
193    ExceptionInfo(Rc<ExceptionInfo>),
194    Nil,
195}
196
197const UUID_TAG: &str = "uuid";
198
199fn uuid_value_from_uuid(value: uuid::Uuid) -> Value {
200    Value::Tagged(Box::new(PTaggedLiteral::new(
201        Symbol::parse(UUID_TAG),
202        Value::String(value.hyphenated().to_string()),
203    )))
204}
205
206fn uuid_from_bytes(bytes: &[u8]) -> uuid::Uuid {
207    let digest = md5::compute(bytes);
208    let mut value = digest.0;
209    value[6] = (value[6] & 0x0f) | 0x30;
210    value[8] = (value[8] & 0x3f) | 0x80;
211    uuid::Uuid::from_bytes(value)
212}
213
214fn uuid_from_parts(most: i64, least: i64) -> uuid::Uuid {
215    let value = ((most as u64 as u128) << 64) | least as u64 as u128;
216    uuid::Uuid::from_u128(value)
217}
218
219fn uuid_from_value(value: &Value) -> Result<uuid::Uuid, String> {
220    match value {
221        Value::String(value) => uuid::Uuid::parse_str(value)
222            .map_err(|_| "Base/uuid expects a valid UUID string".into()),
223        Value::Bytes(value) => Ok(uuid_from_bytes(value)),
224        Value::ByteBuffer(value) => Ok(uuid_from_bytes(&value.borrow())),
225        Value::Keyword(value) => Ok(uuid_from_parts(
226            crate::lang::hash::java_string_hash(value.as_str()) as i64,
227            crate::lang::hash::java_string_hash(value.get_name()) as i64,
228        )),
229        _ => Err("Base/uuid expects a string, bytes, or keyword".into()),
230    }
231}
232
233fn random_uuid() -> uuid::Uuid {
234    let mut bytes = [0u8; 16];
235    getrandom::getrandom(&mut bytes)
236        .unwrap_or_else(|_| panic!("could not retrieve random bytes for uuid"));
237    bytes[6] = (bytes[6] & 0x0f) | 0x40;
238    bytes[8] = (bytes[8] & 0x3f) | 0x80;
239    uuid::Uuid::from_bytes(bytes)
240}
241
242pub(crate) fn uuid_value(values: &[Value]) -> Result<Value, String> {
243    let value = match values {
244        [] => random_uuid(),
245        [value] => uuid_from_value(value)?,
246        [Value::Number(most), Value::Number(least)] => uuid_from_parts(*most, *least),
247        _ if values.len() == 2 => {
248            return Err("Base/uuid expects two integer arguments".into())
249        }
250        _ => return Err("Base/uuid expects zero, one, or two arguments".into()),
251    };
252    Ok(uuid_value_from_uuid(value))
253}
254
255pub(crate) fn uuid_tag_value(value: Value) -> Result<Value, String> {
256    let Value::String(text) = value else {
257        return Err("#uuid expects a UUID string literal".into());
258    };
259    let uuid =
260        uuid::Uuid::parse_str(&text).map_err(|_| "#uuid expects a valid UUID string literal")?;
261    Ok(uuid_value_from_uuid(uuid))
262}
263
264pub(crate) fn uuid_text_from_tagged(value: &PTaggedLiteral<Value>) -> Option<&str> {
265    if value.tag().as_str() != UUID_TAG {
266        return None;
267    }
268    let Value::String(text) = value.form() else {
269        return None;
270    };
271    uuid::Uuid::parse_str(text)
272        .ok()
273        .filter(|uuid| uuid.hyphenated().to_string() == *text)
274        .map(|_| text.as_str())
275}
276
277pub(crate) fn is_uuid_tagged(value: &PTaggedLiteral<Value>) -> bool {
278    uuid_text_from_tagged(value).is_some()
279}
280
281#[derive(Debug, Clone)]
282pub enum MutableCollection {
283    Map(MutableMap<Value, Value>),
284    OrderedMap(MutableOrderedMap<Value, Value>),
285    SortedMap(MutableSortedMap<Value, Value>),
286    Trie(MutableTrie<Value>),
287    Set(MutableSet<Value>),
288    OrderedSet(MutableOrderedSet<Value>),
289    SortedSet(MutableSortedSet<Value>),
290    List(MutableList<Value>),
291    Queue(MutableQueue<Value>),
292    Vector(MutableVector<Value>),
293}
294
295fn named_field_key(field: &str) -> Value {
296    Value::Keyword(Keyword::from(field))
297}
298
299fn named_field_name(value: &Value) -> Option<&str> {
300    match value {
301        Value::String(name) => Some(name.as_str()),
302        Value::Keyword(name) if name.get_namespace().is_none() => Some(name.get_name()),
303        Value::Symbol(name) if name.get_namespace().is_none() => Some(name.get_name()),
304        _ => None,
305    }
306}
307
308impl StructValue {
309    pub(crate) fn from_values(
310        ty: Rc<StructType>,
311        values: Vec<Value>,
312        metadata: Option<Rc<Metadata>>,
313    ) -> Result<Self, String> {
314        if values.len() != ty.fields.len() {
315            return Err(format!("{} expects {} arguments", ty.name, ty.fields.len()));
316        }
317        let values = ty
318            .fields
319            .iter()
320            .zip(values)
321            .fold(POrderedMap::new(), |values, (field, value)| {
322                values.assoc_value(named_field_key(field), value)
323            });
324        Ok(Self {
325            ty,
326            values,
327            metadata,
328        })
329    }
330
331    pub(crate) fn get(&self, field: &str) -> Option<&Value> {
332        self.values.get(&named_field_key(field))
333    }
334
335    pub(crate) fn ordered_values(&self) -> Vec<&Value> {
336        self.ty
337            .fields
338            .iter()
339            .filter_map(|field| self.get(field))
340            .collect()
341    }
342
343    pub(crate) fn ordered_entries(&self) -> Vec<(Value, Value)> {
344        self.ty
345            .fields
346            .iter()
347            .filter_map(|field| {
348                self.get(field)
349                    .cloned()
350                    .map(|value| (named_field_key(field), value))
351            })
352            .collect()
353    }
354}
355
356impl MutableValue {
357    pub(crate) fn from_values(
358        ty: Rc<MutableType>,
359        values: Vec<Value>,
360        metadata: Option<Rc<Metadata>>,
361    ) -> Result<Self, String> {
362        if values.len() != ty.fields.len() {
363            return Err(format!("{} expects {} arguments", ty.name, ty.fields.len()));
364        }
365        Ok(Self {
366            ty,
367            values: Rc::new(RefCell::new(values)),
368            metadata,
369        })
370    }
371
372    fn field_index(&self, field: &str) -> Option<usize> {
373        self.ty
374            .fields
375            .iter()
376            .position(|candidate| candidate == field)
377    }
378
379    pub(crate) fn get(&self, field: &str) -> Option<Value> {
380        let index = self.field_index(field)?;
381        self.values.borrow().get(index).cloned()
382    }
383
384    pub(crate) fn set(&self, field: &str, replacement: Value) -> Result<Value, String> {
385        let index = self
386            .field_index(field)
387            .ok_or_else(|| format!("unknown mutable field: {field}"))?;
388        self.values.borrow_mut()[index] = replacement.clone();
389        Ok(replacement)
390    }
391
392    pub(crate) fn ordered_values(&self) -> Vec<Value> {
393        self.values.borrow().clone()
394    }
395
396    pub(crate) fn ordered_entries(&self) -> Vec<(Value, Value)> {
397        self.ty
398            .fields
399            .iter()
400            .cloned()
401            .zip(self.ordered_values())
402            .map(|(field, value)| (named_field_key(&field), value))
403            .collect()
404    }
405
406    fn same_identity(&self, other: &Self) -> bool {
407        Rc::ptr_eq(&self.values, &other.values)
408    }
409
410    fn identity_address(&self) -> usize {
411        Rc::as_ptr(&self.values) as usize
412    }
413}
414
415#[derive(Clone)]
416pub struct Function {
417    params: Vec<String>,
418    variadic: Option<String>,
419    patterns: Vec<Form>,
420    variadic_pattern: Option<Form>,
421    body: Vec<Form>,
422    captured: Rc<RefCell<HashMap<String, Value>>>,
423    pub name: Option<String>,
424    /// Namespace in which the function body was defined. Lazy aliases and
425    /// qualified Vars are resolved against this namespace when invoked.
426    namespace: Option<String>,
427    native: Option<Rc<dyn Fn(Vec<Value>) -> Result<Value, String>>>,
428    fiber_native: Option<Rc<dyn Fn(Vec<Value>, Cont) -> Step>>,
429    /// Arity clauses for multi-arity `defn`/`fn` dispatchers; empty otherwise.
430    clauses: Vec<Rc<Function>>,
431    /// Runtime-neutral metadata attached through IObjType.
432    metadata: Option<Rc<Metadata>>,
433    /// Whether this function is a macro expander.
434    is_macro: bool,
435}
436
437impl Function {
438    pub(crate) fn accepts_arity(&self, argument_count: usize) -> bool {
439        if !self.clauses.is_empty() {
440            return self
441                .clauses
442                .iter()
443                .any(|clause| clause.accepts_arity(argument_count));
444        }
445        self.variadic.is_some() && argument_count >= self.params.len()
446            || self.variadic.is_none() && argument_count == self.params.len()
447    }
448
449    /// Returns the symbol that identifies this callable's definition.
450    /// Named source functions use their defining namespace as the origin;
451    /// native callables may already carry a qualified display name.
452    pub(crate) fn origin_symbol(&self) -> Option<Symbol> {
453        let name = self.name.as_deref()?;
454        if name.contains('/') {
455            Some(Symbol::parse(name))
456        } else {
457            Some(Symbol::create(self.namespace.as_deref(), name))
458        }
459    }
460}
461
462#[derive(Clone)]
463pub(crate) struct MultiMethod {
464    dispatch: Rc<Function>,
465    methods: Vec<(Value, Rc<Function>)>,
466    default: Option<Rc<Function>>,
467}
468
469impl std::fmt::Debug for Function {
470    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
471        formatter
472            .debug_struct("Function")
473            .field("params", &self.params)
474            .field("variadic", &self.variadic)
475            .field("name", &self.name)
476            .field("native", &self.native.is_some())
477            .finish()
478    }
479}
480
481/// State of a portable coroutine value.
482pub enum CoroutineState {
483    /// The body has not started yet; stores the body function.
484    New(Value),
485    /// Parked at a yield/await; stores the continuation that resumes the body.
486    Suspended(Box<dyn FnOnce(Value) -> Step>),
487    /// Currently executing on a fiber.
488    Running,
489    /// Completed, closed, or killed by an error.
490    Dead,
491}
492
493impl std::fmt::Debug for CoroutineState {
494    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
495        match self {
496            Self::New(_) => formatter.debug_tuple("New").finish(),
497            Self::Suspended(_) => formatter.debug_tuple("Suspended").finish(),
498            Self::Running => formatter.write_str("Running"),
499            Self::Dead => formatter.write_str("Dead"),
500        }
501    }
502}
503
504/// A re-entrant coroutine implemented with the fiber/CPS evaluator.
505pub struct Coroutine {
506    pub state: RefCell<CoroutineState>,
507}
508
509impl std::fmt::Debug for Coroutine {
510    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
511        formatter
512            .debug_struct("Coroutine")
513            .field("state", &self.state.borrow())
514            .finish()
515    }
516}
517
518impl Coroutine {
519    pub fn new(body: Value) -> Self {
520        Self {
521            state: RefCell::new(CoroutineState::New(body)),
522        }
523    }
524}
525
526pub struct RuntimeStream {
527    source: RuntimeStreamSource,
528    pending: Rc<Cell<bool>>,
529    closed: Rc<Cell<bool>>,
530}
531
532enum RuntimeStreamSource {
533    Coroutine {
534        coroutine: Rc<Coroutine>,
535        initial_arguments: RefCell<Option<Vec<Value>>>,
536    },
537    Guest {
538        next: Rc<Function>,
539        close: Option<Rc<Function>>,
540    },
541    Host {
542        next: Rc<dyn Fn() -> Result<Promise, String>>,
543        close: Rc<dyn Fn() -> Result<(), String>>,
544    },
545}
546
547impl std::fmt::Debug for RuntimeStream {
548    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
549        f.debug_struct("RuntimeStream")
550            .field("closed", &self.closed.get())
551            .finish()
552    }
553}
554
555impl RuntimeStream {
556    fn new(body: Value, initial_arguments: Vec<Value>) -> Self {
557        Self {
558            source: RuntimeStreamSource::Coroutine {
559                coroutine: Rc::new(Coroutine::new(body)),
560                initial_arguments: RefCell::new(Some(initial_arguments)),
561            },
562            pending: Rc::new(Cell::new(false)),
563            closed: Rc::new(Cell::new(false)),
564        }
565    }
566    fn host(
567        next: Rc<dyn Fn() -> Result<Promise, String>>,
568        close: Rc<dyn Fn() -> Result<(), String>>,
569    ) -> Self {
570        Self {
571            source: RuntimeStreamSource::Host { next, close },
572            pending: Rc::new(Cell::new(false)),
573            closed: Rc::new(Cell::new(false)),
574        }
575    }
576    fn guest(next: Rc<Function>, close: Option<Rc<Function>>) -> Self {
577        Self {
578            source: RuntimeStreamSource::Guest { next, close },
579            pending: Rc::new(Cell::new(false)),
580            closed: Rc::new(Cell::new(false)),
581        }
582    }
583}
584
585#[derive(Clone)]
586pub struct RuntimeAtom {
587    value: PAtom<Value>,
588    watches: Rc<RefCell<Vec<(Value, Rc<Function>)>>>,
589    watchable: bool,
590}
591
592impl RuntimeAtom {
593    pub(crate) fn new(value: Value, watchable: bool) -> Self {
594        Self {
595            value: PAtom::new(value),
596            watches: Rc::new(RefCell::new(Vec::new())),
597            watchable,
598        }
599    }
600    fn same_identity(&self, other: &Self) -> bool {
601        self.value.same_identity(&other.value)
602    }
603    fn identity_address(&self) -> usize {
604        self.value.identity_address()
605    }
606    pub(crate) fn deref_value(&self) -> Value {
607        self.value.deref_value()
608    }
609    fn reset(&self, new_value: Value) -> Result<Value, String> {
610        let old_value = self.value.deref_value();
611        let result = self.value.reset(new_value.clone())?;
612        self.notify(old_value, new_value)?;
613        Ok(result)
614    }
615    fn compare_and_set(&self, old: &Value, new_value: Value) -> Result<bool, String> {
616        let prior = self.value.deref_value();
617        let changed = self.value.compare_and_set(old, new_value.clone())?;
618        if changed {
619            self.notify(prior, new_value)?;
620        }
621        Ok(changed)
622    }
623    fn add_watch(&self, key: Value, function: Rc<Function>) -> Result<(), String> {
624        if !self.watchable {
625            return Err("watch-add expects a standard atom".into());
626        }
627        let mut watches = self.watches.borrow_mut();
628        watches.retain(|(candidate, _)| candidate != &key);
629        watches.push((key, function));
630        Ok(())
631    }
632    fn remove_watch(&self, key: &Value) -> Result<(), String> {
633        if !self.watchable {
634            return Err("watch-remove expects a standard atom".into());
635        }
636        self.watches
637            .borrow_mut()
638            .retain(|(candidate, _)| candidate != key);
639        Ok(())
640    }
641    fn watch_entries(&self) -> Result<Vec<Value>, String> {
642        if !self.watchable {
643            return Err("watch-list expects a standard atom".into());
644        }
645        self.watches
646            .borrow()
647            .iter()
648            .map(|(key, function)| {
649                vector_literal(vec![key.clone(), Value::Function(function.clone())])
650            })
651            .collect()
652    }
653    fn notify(&self, old_value: Value, new_value: Value) -> Result<(), String> {
654        let watches = self.watches.borrow().clone();
655        for (key, function) in watches {
656            call_function(
657                &function,
658                vec![
659                    key,
660                    Value::Atom(Box::new(self.clone())),
661                    old_value.clone(),
662                    new_value.clone(),
663                ],
664            )?;
665        }
666        Ok(())
667    }
668}
669
670impl std::fmt::Debug for RuntimeAtom {
671    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
672        formatter
673            .debug_struct("RuntimeAtom")
674            .finish_non_exhaustive()
675    }
676}
677
678fn function_definition_namespace() -> Option<String> {
679    namespace_registry()
680        .ok()
681        .map(|registry| registry.current().name().as_str().to_owned())
682}
683
684/// Builds a fixed-arity native callable for embedding-owned namespaces.
685pub fn native_function(
686    name: &str,
687    arity: usize,
688    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
689) -> Value {
690    let function = Rc::new(Function {
691        params: (0..arity).map(|index| format!("arg{index}")).collect(),
692        variadic: None,
693        patterns: Vec::new(),
694        variadic_pattern: None,
695        body: Vec::new(),
696        captured: Rc::new(RefCell::new(HashMap::new())),
697        name: Some(name.into()),
698        namespace: function_definition_namespace(),
699        native: Some(Rc::new(callback)),
700        fiber_native: None,
701        clauses: Vec::new(),
702        metadata: None,
703        is_macro: false,
704    });
705    debug_assert!(function.origin_symbol().is_some());
706    Value::Function(function)
707}
708
709/// A native function wrapper with an exact fixed parameter list and an
710/// optional rest marker: `params.len()` reflects the fixed arity so the
711/// multi-arity `select_clause` boundary can dispatch on it, unlike
712/// [`native_variadic_function`] whose parameter list is empty. Used by
713/// the bytecode VM for variadic closures (issue #223).
714pub(crate) fn native_fixed_variadic_function(
715    name: &str,
716    fixed_arity: usize,
717    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
718) -> Value {
719    let function = Rc::new(Function {
720        params: (0..fixed_arity)
721            .map(|index| format!("arg{index}"))
722            .collect(),
723        variadic: Some("rest".into()),
724        patterns: Vec::new(),
725        variadic_pattern: None,
726        body: Vec::new(),
727        captured: Rc::new(RefCell::new(HashMap::new())),
728        name: Some(name.into()),
729        namespace: function_definition_namespace(),
730        native: Some(Rc::new(callback)),
731        fiber_native: None,
732        clauses: Vec::new(),
733        metadata: None,
734        is_macro: false,
735    });
736    debug_assert!(function.origin_symbol().is_some());
737    Value::Function(function)
738}
739
740pub fn native_variadic_function(
741    name: &str,
742    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
743) -> Value {
744    let function = Rc::new(Function {
745        params: Vec::new(),
746        variadic: Some("arguments".into()),
747        patterns: Vec::new(),
748        variadic_pattern: None,
749        body: Vec::new(),
750        captured: Rc::new(RefCell::new(HashMap::new())),
751        name: Some(name.into()),
752        namespace: function_definition_namespace(),
753        native: Some(Rc::new(callback)),
754        fiber_native: None,
755        clauses: Vec::new(),
756        metadata: None,
757        is_macro: false,
758    });
759    debug_assert!(function.origin_symbol().is_some());
760    Value::Function(function)
761}
762
763pub(crate) fn native_fiber_function(
764    name: &str,
765    fixed_arity: usize,
766    variadic: bool,
767    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
768    fiber_callback: impl Fn(Vec<Value>, Cont) -> Step + 'static,
769) -> Value {
770    native_fiber_function_with_arity_error(
771        name,
772        fixed_arity,
773        variadic,
774        callback,
775        fiber_callback,
776        |expectation, _received| format!("function expects {expectation} arguments"),
777    )
778}
779
780pub(crate) fn native_protocol_fiber_function(
781    name: &str,
782    protocol: &str,
783    method: &str,
784    fixed_arity: usize,
785    variadic: bool,
786    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
787    fiber_callback: impl Fn(Vec<Value>, Cont) -> Step + 'static,
788) -> Value {
789    let display_name = format!("{protocol}/{method}");
790    native_fiber_function_with_arity_error(
791        name,
792        fixed_arity,
793        variadic,
794        callback,
795        fiber_callback,
796        move |expectation, received| {
797            format!(
798                "protocol/arity: {display_name} expects {expectation} arguments, received {received}"
799            )
800        },
801    )
802}
803
804fn native_fiber_function_with_arity_error(
805    name: &str,
806    fixed_arity: usize,
807    variadic: bool,
808    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
809    fiber_callback: impl Fn(Vec<Value>, Cont) -> Step + 'static,
810    arity_error: impl Fn(String, usize) -> String + 'static,
811) -> Value {
812    let fiber_callback = move |arguments: Vec<Value>, continuation: Cont| {
813        let valid = if variadic {
814            arguments.len() >= fixed_arity
815        } else {
816            arguments.len() == fixed_arity
817        };
818        if !valid {
819            let expectation = if variadic {
820                format!("at least {fixed_arity}")
821            } else {
822                fixed_arity.to_string()
823            };
824            return continuation(Err(arity_error(expectation, arguments.len())));
825        }
826        fiber_callback(arguments, continuation)
827    };
828    let function = Rc::new(Function {
829        params: (0..fixed_arity)
830            .map(|index| format!("arg{index}"))
831            .collect(),
832        variadic: variadic.then(|| "rest".into()),
833        patterns: Vec::new(),
834        variadic_pattern: None,
835        body: Vec::new(),
836        captured: Rc::new(RefCell::new(HashMap::new())),
837        name: Some(name.into()),
838        namespace: function_definition_namespace(),
839        native: Some(Rc::new(callback)),
840        fiber_native: Some(Rc::new(fiber_callback)),
841        clauses: Vec::new(),
842        metadata: None,
843        is_macro: false,
844    });
845    debug_assert!(function.origin_symbol().is_some());
846    Value::Function(function)
847}
848
849pub(crate) fn exception_function_values() -> Vec<(&'static str, Value)> {
850    vec![
851        (
852            "ex",
853            native_variadic_function("ex", |arguments| {
854                if arguments.len() < 2 || arguments.len() % 2 != 0 {
855                    return Err("ex expects a code, attributes map, and key/value pairs".into());
856                }
857                let Value::Keyword(input_code) = &arguments[0] else {
858                    return Err(
859                        "ex expects a registered standard keyword or namespaced keyword code"
860                            .into(),
861                    );
862                };
863                let code = normalize_exception_code(input_code)?;
864                let mut attributes = arguments[1].clone();
865                for pair in arguments[2..].chunks_exact(2) {
866                    attributes = map_assoc_value(&attributes, pair[0].clone(), pair[1].clone())?;
867                }
868                let Some(entries) = map_entries(&attributes) else {
869                    return Err("ex expects an attributes map".into());
870                };
871                let lookup = |name: &str| {
872                    entries.iter().find_map(|(key, value)| {
873                        matches!(key, Value::Keyword(key_name) if key_name.as_str() == name)
874                            .then_some(value)
875                    })
876                };
877                let message = match lookup("ex/message") {
878                    Some(Value::String(message)) => message.clone(),
879                    Some(_) => return Err(":ex/message must be a string".into()),
880                    None => format!(":{code}"),
881                };
882                if lookup("ex/code").is_some() {
883                    return Err("ex attributes must not contain :ex/code; pass the code as the first argument".into());
884                }
885                if let Some(class) = lookup("ex/class") {
886                    match class {
887                        Value::Keyword(class) if class.get_namespace().is_some() => {
888                            if let Some(expected) = default_exception_class(&code) {
889                                if class != &expected {
890                                    return Err(":ex/class conflicts with the registered class for :ex/code".into());
891                                }
892                            }
893                        }
894                        _ => return Err(":ex/class must be a namespaced keyword".into()),
895                    }
896                }
897                let cause = match lookup("ex/cause") {
898                    Some(cause @ Value::ExceptionInfo(_)) => Some(cause.clone()),
899                    Some(_) => return Err(":ex/cause must be an Exception".into()),
900                    None => None,
901                };
902                if let Some(context) = lookup("ex/context") {
903                    if map_entries(context).is_none() {
904                        return Err(":ex/context must be a map".into());
905                    }
906                }
907                let mut data = map_assoc_value(
908                    &attributes,
909                    Value::Keyword("ex/code".into()),
910                    Value::Keyword(code.clone()),
911                )?;
912                if lookup("ex/class").is_none() {
913                    if let Some(class) = default_exception_class(&code) {
914                        data = map_assoc_value(
915                            &data,
916                            Value::Keyword("ex/class".into()),
917                            Value::Keyword(class),
918                        )?;
919                    }
920                }
921                if let Some(cause) = &cause {
922                    data =
923                        map_assoc_value(&data, Value::Keyword("ex/cause".into()), cause.clone())?;
924                }
925                let value = Value::ExceptionInfo(Rc::new(ExceptionInfo {
926                    message,
927                    cause: cause.map(Box::new),
928                    data: Box::new(data),
929                    provenance: Rc::new(RefCell::new(ExceptionProvenance {
930                        created_at: None,
931                        throws: Vec::new(),
932                    })),
933                }));
934                record_exception_creation(&value, current_exception_site());
935                Ok(value)
936            }),
937        ),
938        (
939            "ex-data",
940            native_function("ex-data", 1, |arguments| match &arguments[0] {
941                Value::ExceptionInfo(value) => Ok((*value.data).clone()),
942                _ => Ok(Value::Nil),
943            }),
944        ),
945        (
946            "ex-message",
947            native_function("ex-message", 1, |arguments| match &arguments[0] {
948                Value::ExceptionInfo(value) => Ok(Value::String(value.message.clone())),
949                Value::String(value) => Ok(Value::String(value.clone())),
950                value => Ok(Value::String(value.display())),
951            }),
952        ),
953        (
954            "ex-cause",
955            native_function("ex-cause", 1, |arguments| match &arguments[0] {
956                Value::ExceptionInfo(value) => {
957                    Ok(value.cause.as_deref().cloned().unwrap_or(Value::Nil))
958                }
959                _ => Err("ex-cause expects an Exception".into()),
960            }),
961        ),
962        (
963            "ex-provenance",
964            native_function("ex-provenance", 1, |arguments| match &arguments[0] {
965                Value::ExceptionInfo(value) => Ok(exception_provenance_value(value)),
966                _ => Err("ex-provenance expects an Exception".into()),
967            }),
968        ),
969        (
970            "ex-class",
971            native_function("ex-class", 1, |arguments| match &arguments[0] {
972                Value::ExceptionInfo(value) => {
973                    let Some(entries) = map_entries(&value.data) else {
974                        return Err("Exception data must be a map".into());
975                    };
976                    match entries.iter().find_map(|(key, value)| {
977                        matches!(key, Value::Keyword(name) if name.as_str() == "ex/class")
978                            .then_some(value)
979                    }) {
980                        None => Ok(Value::Nil),
981                        Some(Value::Keyword(class)) if class.get_namespace().is_some() => {
982                            Ok(Value::Keyword(class.clone()))
983                        }
984                        Some(_) => Err(":ex/class must be a namespaced keyword".into()),
985                    }
986                }
987                _ => Err("ex-class expects an Exception".into()),
988            }),
989        ),
990        (
991            "ex-native-type",
992            native_function("ex-native-type", 1, |arguments| match &arguments[0] {
993                Value::ExceptionInfo(_) => Ok(Value::Nil),
994                _ => Err("ex-native-type expects an Exception".into()),
995            }),
996        ),
997    ]
998}
999
1000pub(crate) fn direct_function_value(name: &str) -> Option<Value> {
1001    match name {
1002        "pair" => Some(native_function("pair", 2, |arguments| {
1003            Ok(Value::MapEntry(Box::new(PMapEntry::new(
1004                arguments[0].clone(),
1005                arguments[1].clone(),
1006            ))))
1007        })),
1008        "disj" => Some(native_variadic_function("disj", |arguments| {
1009            let (collection, values) = arguments
1010                .split_first()
1011                .ok_or_else(|| "disj expects a collection".to_string())?;
1012            let mut output = collection.clone();
1013            for value in values {
1014                if matches!(output, Value::Nil) {
1015                    break;
1016                }
1017                output = crate::core::protocol_intrinsic_call(
1018                    "std.protocol.idissoc.IDissoc/dissoc",
1019                    &[output, value.clone()],
1020                )?;
1021            }
1022            Ok(output)
1023        })),
1024        "quot" => Some(native_function("quot", 2, |arguments| {
1025            numeric::numeric_quotient(&arguments[0], &arguments[1])
1026        })),
1027        "rem" => Some(native_function("rem", 2, |arguments| {
1028            apply_binary_intrinsic(IntrinsicOp::Remainder, &arguments[0], &arguments[1])
1029        })),
1030        "mod" => Some(native_variadic_function("mod", |arguments| {
1031            if arguments.len() != 2 {
1032                return Err("mod expects arguments".into());
1033            }
1034            numeric::numeric_binary(ArithmeticOp::Modulo, &arguments[0], &arguments[1])
1035        })),
1036        _ => IntrinsicOp::from_symbol(name).map(|primitive| {
1037            native_variadic_function(name, move |arguments| {
1038                apply_intrinsic(primitive, &arguments)
1039            })
1040        }),
1041    }
1042}
1043
1044/// Creates a callable exported by a `std.native.*` namespace.
1045///
1046/// Native type methods must terminate in their Rust implementation. They must
1047/// not resolve their public HAL facade name and re-enter `eval`, because doing
1048/// so makes alias precedence part of native invocation and permits facade →
1049/// native → facade recursion.
1050pub fn native_type_function_value(native_type: &str, method: &str) -> Result<Value, String> {
1051    native_qualified_type_function_value(&format!("std.native.{native_type}"), method)
1052}
1053
1054/// Creates a callable owned by an explicitly qualified native type namespace.
1055///
1056/// Short type names deliberately continue to resolve through the closed
1057/// `std.native` compatibility surface; new host families must opt into their
1058/// full identity to avoid global alias collisions.
1059pub fn native_qualified_type_function_value(
1060    native_type: &str,
1061    method: &str,
1062) -> Result<Value, String> {
1063    let declaration = NATIVE_DECLARATIONS
1064        .iter()
1065        .find(|declaration| declaration.qualified_name() == native_type)
1066        .ok_or_else(|| {
1067            format!("missing annotated native declaration: {native_type}/{method}")
1068        })?;
1069    if !declaration.method(method) {
1070        return Err(format!("unknown annotated native method: {native_type}/{method}"));
1071    }
1072    (declaration.provider)(declaration.name, method)
1073}
1074
1075fn native_display_name(native_type: &str, method: &str) -> String {
1076    format!("std.native.{native_type}/{method}")
1077}
1078
1079fn native_base_provider(native_type: &str, method: &str) -> Result<Value, String> {
1080    let display_name = native_display_name(native_type, method);
1081    let method = method.to_owned();
1082    Ok(native_variadic_function(&display_name, move |arguments| {
1083        native_base_values(&method, &arguments)
1084    }))
1085}
1086
1087fn native_schema_provider(native_type: &str, method: &str) -> Result<Value, String> {
1088    let display_name = native_display_name(native_type, method);
1089    let method = method.to_owned();
1090    Ok(native_variadic_function(&display_name, move |arguments| {
1091        native_schema_values(&method, &arguments)
1092    }))
1093}
1094
1095fn native_string_provider(native_type: &str, method: &str) -> Result<Value, String> {
1096    let display_name = native_display_name(native_type, method);
1097    let operation = format!("str/{method}");
1098    Ok(native_variadic_function(&display_name, move |arguments| {
1099        string_operation(&operation, arguments)
1100    }))
1101}
1102
1103fn native_bytes_provider(native_type: &str, method: &str) -> Result<Value, String> {
1104    let display_name = native_display_name(native_type, method);
1105    let method = method.to_owned();
1106    Ok(native_variadic_function(&display_name, move |arguments| {
1107        native_bytes_operation(&method, arguments)
1108    }))
1109}
1110
1111fn native_iter_provider(native_type: &str, method: &str) -> Result<Value, String> {
1112    let display_name = native_display_name(native_type, method);
1113    let method = method.to_owned();
1114    Ok(native_variadic_function(&display_name, move |arguments| {
1115        native_iter_operation(&method, arguments)
1116    }))
1117}
1118
1119fn native_maths_provider(native_type: &str, method: &str) -> Result<Value, String> {
1120    let display_name = native_display_name(native_type, method);
1121    let method = method.to_owned();
1122    Ok(native_variadic_function(&display_name, move |arguments| {
1123        math_values(&method, arguments)
1124    }))
1125}
1126
1127fn native_num_provider(native_type: &str, method: &str) -> Result<Value, String> {
1128    let display_name = native_display_name(native_type, method);
1129    let method = method.to_owned();
1130    Ok(native_variadic_function(&display_name, move |arguments| {
1131        if arguments.len() != 1 {
1132            return Err(format!("{method} expects one value"));
1133        }
1134        number_conversion_value(&method, arguments.into_iter().next().unwrap())
1135    }))
1136}
1137
1138fn native_bits_provider(native_type: &str, method: &str) -> Result<Value, String> {
1139    let display_name = native_display_name(native_type, method);
1140    let method = method.to_owned();
1141    Ok(native_variadic_function(&display_name, move |arguments| {
1142        bit_values(&method, &arguments)
1143    }))
1144}
1145
1146fn native_kernel_provider(native_type: &str, method: &str) -> Result<Value, String> {
1147    let display_name = native_display_name(native_type, method);
1148    let method = method.to_owned();
1149    Ok(native_variadic_function(&display_name, move |arguments| {
1150        require_native_capability("Kernel", &method, "kernel")?;
1151        kernel_provider(&method)?(method.clone(), arguments)
1152    }))
1153}
1154
1155fn native_sandbox_provider(native_type: &str, method: &str) -> Result<Value, String> {
1156    let display_name = native_display_name(native_type, method);
1157    let operation = format!("sandbox-{method}");
1158    let method = method.to_owned();
1159    Ok(native_variadic_function(&display_name, move |arguments| {
1160        require_native_capability("Sandbox", &method, "sandbox")?;
1161        kernel_provider(&operation)?(operation.clone(), arguments)
1162    }))
1163}
1164
1165fn native_crypto_provider(native_type: &str, method: &str) -> Result<Value, String> {
1166    let display_name = native_display_name(native_type, method);
1167    let method = method.to_owned();
1168    Ok(native_variadic_function(&display_name, move |arguments| {
1169        native_crypto::operation(&method, arguments)
1170    }))
1171}
1172
1173fn native_document_provider(native_type: &str, method: &str) -> Result<Value, String> {
1174    let display_name = native_display_name(native_type, method);
1175    let method = method.to_owned();
1176    Ok(native_variadic_function(&display_name, move |arguments| {
1177        document_operation(&method, arguments)
1178    }))
1179}
1180
1181fn native_package_provider(native_type: &str, method: &str) -> Result<Value, String> {
1182    let display_name = native_display_name(native_type, method);
1183    let method = method.to_owned();
1184    Ok(native_variadic_function(&display_name, move |arguments| {
1185        require_native_capability("Package", &method, "kernel")?;
1186        native_package_values(&method, arguments, &mut HashMap::new())
1187    }))
1188}
1189
1190fn native_hbx_provider(native_type: &str, method: &str) -> Result<Value, String> {
1191    let display_name = native_display_name(native_type, method);
1192    let method = method.to_owned();
1193    Ok(native_variadic_function(&display_name, move |arguments| {
1194        hbx_operation(&method, arguments)
1195    }))
1196}
1197
1198fn native_instrument_provider(native_type: &str, method: &str) -> Result<Value, String> {
1199    let display_name = native_display_name(native_type, method);
1200    let method = method.to_owned();
1201    Ok(native_variadic_function(&display_name, move |arguments| {
1202        native_instrument_values(&method, arguments)
1203    }))
1204}
1205
1206fn native_os_provider(native_type: &str, method: &str) -> Result<Value, String> {
1207    let display_name = native_display_name(native_type, method);
1208    let native_type = native_type.to_owned();
1209    let method = method.to_owned();
1210    let operation = native_display_name(&native_type, &method);
1211    Ok(native_variadic_function(&display_name, move |arguments| {
1212        if native_type == "Process" {
1213            require_native_capability("Process", &method, "native-runtime")?;
1214        }
1215        os_values(&operation, arguments)
1216    }))
1217}
1218
1219fn native_file_provider(native_type: &str, method: &str) -> Result<Value, String> {
1220    let display_name = native_display_name(native_type, method);
1221    let method = method.to_owned();
1222    let operation = native_display_name(native_type, &method);
1223    Ok(native_variadic_function(&display_name, move |arguments| {
1224        require_native_capability("File", &method, "file")?;
1225        file_values(&operation, arguments)
1226    }))
1227}
1228
1229fn native_socket_provider(native_type: &str, method: &str) -> Result<Value, String> {
1230    let display_name = native_display_name(native_type, method);
1231    let method = method.to_owned();
1232    let operation = native_display_name(native_type, &method);
1233    Ok(native_variadic_function(&display_name, move |arguments| {
1234        require_native_capability("Socket", &method, "network")?;
1235        socket_values(&operation, arguments)
1236    }))
1237}
1238
1239fn native_promise_provider(native_type: &str, method: &str) -> Result<Value, String> {
1240    let display_name = native_display_name(native_type, method);
1241    let method = method.to_owned();
1242    Ok(native_variadic_function(&display_name, move |arguments| {
1243        native_promise_values(&method, arguments)
1244    }))
1245}
1246
1247fn native_coroutine_provider(native_type: &str, method: &str) -> Result<Value, String> {
1248    let display_name = native_display_name(native_type, method);
1249    match method {
1250        "create" => Ok(native_fiber_function(
1251            &display_name,
1252            1,
1253            false,
1254            native_coroutine_create,
1255            native_coroutine_create_fiber,
1256        )),
1257        "yield" => Ok(native_fiber_function(
1258            &display_name,
1259            1,
1260            false,
1261            native_coroutine_yield,
1262            native_coroutine_yield_fiber,
1263        )),
1264        "await" => Ok(native_fiber_function(
1265            &display_name,
1266            1,
1267            false,
1268            native_coroutine_await,
1269            native_coroutine_await_fiber,
1270        )),
1271        _ => Err(format!("unknown std.native.Coroutine operation: {method}")),
1272    }
1273}
1274
1275fn native_stream_provider(native_type: &str, method: &str) -> Result<Value, String> {
1276    let display_name = native_display_name(native_type, method);
1277    let method = method.to_owned();
1278    Ok(native_variadic_function(&display_name, move |arguments| {
1279        native_stream_values(&method, arguments)
1280    }))
1281}
1282
1283fn native_mutable_provider(native_type: &str, method: &str) -> Result<Value, String> {
1284    let display_name = native_display_name(native_type, method);
1285    let operation = native_display_name(native_type, method);
1286    Ok(native_variadic_function(&display_name, move |arguments| {
1287        native_mutable_values(&operation, arguments)
1288    }))
1289}
1290
1291fn native_runtime_provider(native_type: &str, method: &str) -> Result<Value, String> {
1292    let display_name = native_display_name(native_type, method);
1293    let method = method.to_owned();
1294    Ok(native_variadic_function(&display_name, move |arguments| {
1295        native_runtime_values(&method, arguments, &mut HashMap::new())
1296    }))
1297}
1298
1299fn native_printer_provider(native_type: &str, method: &str) -> Result<Value, String> {
1300    let display_name = native_display_name(native_type, method);
1301    let method = method.to_owned();
1302    Ok(native_variadic_function(&display_name, move |arguments| {
1303        native_printer_values(&method, arguments)
1304    }))
1305}
1306
1307fn native_edn_provider(native_type: &str, method: &str) -> Result<Value, String> {
1308    let display_name = native_display_name(native_type, method);
1309    let method = method.to_owned();
1310    Ok(native_variadic_function(&display_name, move |arguments| {
1311        native_edn_values(&method, arguments)
1312    }))
1313}
1314
1315fn native_json_provider(native_type: &str, method: &str) -> Result<Value, String> {
1316    let display_name = native_display_name(native_type, method);
1317    let method = method.to_owned();
1318    Ok(native_variadic_function(&display_name, move |arguments| {
1319        match (method.as_str(), arguments.as_slice()) {
1320            ("read", [Value::String(source)]) => crate::json::read(source),
1321            ("write", [value]) => crate::json::write(value).map(Value::String),
1322            ("pretty", [value, options]) if map_entries(options).is_some() => {
1323                crate::json::write_pretty(value).map(Value::String)
1324            }
1325            ("pretty", [_, _]) => Err("json/pretty expects an options map".into()),
1326            ("read", _) => Err("json/read expects a string".into()),
1327            ("write", _) => Err("json/write expects one value".into()),
1328            ("pretty", _) => Err("json/pretty expects a value and options map".into()),
1329            _ => Err(format!("unknown std.native.Json operation: {method}")),
1330        }
1331    }))
1332}
1333
1334fn native_host_provider(native_type: &str, method: &str) -> Result<Value, String> {
1335    let display_name = native_display_name(native_type, method);
1336    let method = method.to_owned();
1337    Ok(native_variadic_function(&display_name, move |arguments| {
1338        if !native_capability_granted("host-call") {
1339            return Ok(native_capability_denied_promise(
1340                "Host",
1341                &method,
1342                "host-call",
1343            ));
1344        }
1345        native_host_values(&method, arguments)
1346    }))
1347}
1348
1349fn native_test_provider(native_type: &str, method: &str) -> Result<Value, String> {
1350    let display_name = native_display_name(native_type, method);
1351    let method = method.to_owned();
1352    Ok(native_variadic_function(&display_name, move |arguments| {
1353        native_test_values(&method, arguments)
1354    }))
1355}
1356
1357fn native_command_provider(native_type: &str, method: &str) -> Result<Value, String> {
1358    let display_name = native_display_name(native_type, method);
1359    let method = method.to_owned();
1360    Ok(native_variadic_function(&display_name, move |arguments| {
1361        native_command_values(&method, arguments)
1362    }))
1363}
1364
1365fn native_regexp_provider(native_type: &str, method: &str) -> Result<Value, String> {
1366    let display_name = native_display_name(native_type, method);
1367    let method = method.to_owned();
1368    Ok(native_variadic_function(&display_name, move |arguments| {
1369        native_regex_values(&method, arguments)
1370    }))
1371}
1372
1373fn native_result_provider(native_type: &str, method: &str) -> Result<Value, String> {
1374    let display_name = native_display_name(native_type, method);
1375    let method = method.to_owned();
1376    Ok(native_variadic_function(&display_name, move |arguments| {
1377        native_result_values(&method, arguments)
1378    }))
1379}
1380
1381fn native_exception_provider(native_type: &str, method: &str) -> Result<Value, String> {
1382    let display_name = native_display_name(native_type, method);
1383    let method = method.to_owned();
1384    Ok(native_variadic_function(&display_name, move |arguments| {
1385        native_exception_values(&method, arguments)
1386    }))
1387}
1388
1389fn native_algo_provider(native_type: &str, method: &str) -> Result<Value, String> {
1390    let display_name = native_display_name(native_type, method);
1391    let operation = native_display_name(native_type, method);
1392    Ok(native_variadic_function(&display_name, move |arguments| {
1393        native_algo_values(&operation, arguments)
1394    }))
1395}
1396
1397fn native_work_provider(_native_type: &str, method: &str) -> Result<Value, String> {
1398    crate::work::guest::values()
1399        .into_iter()
1400        .find(|(name, _)| *name == method)
1401        .map(|(_, value)| value)
1402        .ok_or_else(|| format!("unknown std.native.Work operation: {method}"))
1403}
1404
1405fn native_lang_provider(native_type: &str, method: &str) -> Result<Value, String> {
1406    crate::lang_harness::function(native_type, method)
1407}
1408
1409fn native_coroutine_create(arguments: Vec<Value>) -> Result<Value, String> {
1410    match arguments.as_slice() {
1411        [Value::Function(function)] => Ok(Value::Coroutine(Rc::new(Coroutine::new(
1412            Value::Function(function.clone()),
1413        )))),
1414        _ => Err("Coroutine/create expects one function".into()),
1415    }
1416}
1417
1418fn native_coroutine_create_fiber(arguments: Vec<Value>, k: Cont) -> Step {
1419    match arguments.as_slice() {
1420        [Value::Function(function)] => k(Ok(Value::Coroutine(Rc::new(Coroutine::new(
1421            Value::Function(function.clone()),
1422        ))))),
1423        _ => k(Err("Coroutine/create expects one function".into())),
1424    }
1425}
1426
1427fn native_coroutine_yield(_arguments: Vec<Value>) -> Result<Value, String> {
1428    Err("Coroutine/yield requires the fiber evaluator".into())
1429}
1430
1431fn native_coroutine_yield_fiber(arguments: Vec<Value>, k: Cont) -> Step {
1432    match arguments.as_slice() {
1433        [value] => Step::Yield(value.clone(), Box::new(move |resumed| k(Ok(resumed)))),
1434        _ => k(Err("Coroutine/yield expects one value".into())),
1435    }
1436}
1437
1438fn native_coroutine_await(_arguments: Vec<Value>) -> Result<Value, String> {
1439    Err("Coroutine/await requires the fiber evaluator".into())
1440}
1441
1442fn native_coroutine_await_fiber(arguments: Vec<Value>, k: Cont) -> Step {
1443    match arguments.as_slice() {
1444        [Value::Var(reference)] => k(Ok(reference.deref_value())),
1445        [Value::Promise(promise)] => match promise.state() {
1446            PromiseState::Fulfilled(value) => k(Ok(value)),
1447            PromiseState::Rejected(error) => k(Err(crate::core::promise_rejection_error(error))),
1448            PromiseState::Pending => Step::Wait(
1449                promise.clone(),
1450                Box::new(move |state| match state {
1451                    PromiseState::Fulfilled(value) => k(Ok(value)),
1452                    PromiseState::Rejected(error) => {
1453                        k(Err(crate::core::promise_rejection_error(error)))
1454                    }
1455                    PromiseState::Pending => k(Err("Coroutine/await resumed pending".into())),
1456                }),
1457            ),
1458        },
1459        _ => k(Err("Coroutine/await expects a derefable (e.g. a promise)".into())),
1460    }
1461}
1462
1463fn native_reader_position_value(position: crate::kernel::Position) -> Value {
1464    Value::Map(PMap::from_iter([
1465        (Value::Keyword("offset".into()), Value::Number(position.offset as i64)),
1466        (Value::Keyword("line".into()), Value::Number(position.line as i64)),
1467        (
1468            Value::Keyword("column".into()),
1469            Value::Number(position.column as i64),
1470        ),
1471    ]))
1472}
1473
1474fn native_spanned_form_value(form: &crate::kernel::SpannedForm) -> Result<Value, String> {
1475    let children = form
1476        .children
1477        .iter()
1478        .map(native_spanned_form_value)
1479        .collect::<Result<Vec<_>, _>>()?;
1480    Ok(Value::Map(PMap::from_iter([
1481        (Value::Keyword("form".into()), form_to_value(&form.form)?),
1482        (
1483            Value::Keyword("start".into()),
1484            native_reader_position_value(form.span.start),
1485        ),
1486        (
1487            Value::Keyword("end".into()),
1488            native_reader_position_value(form.span.end),
1489        ),
1490        (
1491            Value::Keyword("children".into()),
1492            Value::Vector(PVector::from_iter(children)),
1493        ),
1494    ])))
1495}
1496
1497fn native_edn_values(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1498    match (method, arguments.as_slice()) {
1499        ("read", [Value::String(source)]) => read_edn(source),
1500        ("read-forms-spanned", [Value::String(source)]) => {
1501            let forms = crate::kernel::read_forms(source)
1502                .map_err(|error| format!("read-forms-spanned failed: {error}"))?;
1503            Ok(Value::Vector(PVector::from_iter(
1504                forms
1505                    .iter()
1506                    .map(native_spanned_form_value)
1507                    .collect::<Result<Vec<_>, _>>()?,
1508            )))
1509        }
1510        ("read-forms", [Value::String(path)]) => {
1511            if !(path.ends_with(".hal") || path.ends_with(".hrl")) {
1512                return Err("read-forms expects a .hal or .hrl path".into());
1513            }
1514            let promise = file_provider("read-forms")?
1515                .read(path)
1516                .map_err(|error| file_error("read-forms", error))?;
1517            let bytes = match promise.wait_state() {
1518                PromiseState::Fulfilled(Value::Bytes(bytes)) => bytes,
1519                PromiseState::Fulfilled(Value::ByteBuffer(bytes)) => bytes.borrow().clone(),
1520                PromiseState::Fulfilled(value) => {
1521                    return Err(format!(
1522                        "read-forms expected file bytes, got {}",
1523                        value.display()
1524                    ));
1525                }
1526                PromiseState::Rejected(error) => return Err(error.message()),
1527                PromiseState::Pending => return Err("read-forms file read is still pending".into()),
1528            };
1529            let source = String::from_utf8(bytes)
1530                .map_err(|_| format!("read-forms source is not UTF-8: {path}"))?;
1531            let forms = crate::kernel::parse_forms(&source)
1532                .map_err(|error| format!("read-forms failed: {error}"))?;
1533            Ok(Value::Vector(PVector::from_iter(
1534                forms
1535                    .iter()
1536                    .map(form_to_value)
1537                    .collect::<Result<Vec<_>, _>>()?,
1538            )))
1539        }
1540        ("write", [value]) => Ok(Value::String(value.display())),
1541        ("pretty", [value, options]) if map_entries(options).is_some() => {
1542            Ok(Value::String(value.display()))
1543        }
1544        ("pretty", [_, _]) => Err("edn/pretty expects an options map".into()),
1545        ("read", _) => Err("edn/read expects one string".into()),
1546        ("read-forms", _) => Err("read-forms expects a path string".into()),
1547        ("read-forms-spanned", _) => {
1548            Err("read-forms-spanned expects one source string".into())
1549        }
1550        ("write", _) => Err("std.native.Edn/write expects one value".into()),
1551        ("pretty", _) => Err("std.native.Edn/pretty expects a value and options map".into()),
1552        _ => Err(format!("unknown std.native.Edn operation: {method}")),
1553    }
1554}
1555
1556fn native_printer_values(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1557    match method {
1558        "capture" => {
1559            let [callable] = arguments.as_slice() else {
1560                return Err("Printer/capture expects one callable".into());
1561            };
1562            PRINTER_CAPTURES.with(|captures| captures.borrow_mut().push(String::new()));
1563            let result = call_value(callable.clone(), Vec::new());
1564            let output = PRINTER_CAPTURES.with(|captures| {
1565                captures
1566                    .borrow_mut()
1567                    .pop()
1568                    .expect("Printer/capture stack must contain the active capture")
1569            });
1570            result.map(|_| Value::String(output))
1571        }
1572        "p" | "println" => {
1573            let text = arguments
1574                .iter()
1575                .map(|value| match (method, value) {
1576                    ("p", Value::Nil) => String::new(),
1577                    ("p", Value::String(text)) => text.clone(),
1578                    ("p", Value::Character(character)) => character.to_string(),
1579                    (_, Value::String(text)) => text.clone(),
1580                    _ => value.display(),
1581                })
1582                .collect::<Vec<_>>()
1583                .join(if method == "println" { " " } else { "" });
1584            let output = if method == "println" {
1585                format!("{text}\n")
1586            } else {
1587                text
1588            };
1589            printer_write(&output)?;
1590            Ok(Value::Nil)
1591        }
1592        _ => Err(format!("unknown std.native.Printer operation: {method}")),
1593    }
1594}
1595
1596fn native_promise_values(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1597    match (method, arguments.as_slice()) {
1598        ("from", [value]) => Ok(Value::Promise(promise_from(value.clone()))),
1599        ("all", [values]) => Ok(Value::Promise(promise_all(iterator_values(
1600            values.clone(),
1601        )?))),
1602        ("run", [Value::Function(function)]) => {
1603            let function = function.clone();
1604            let context = crate::core::NativeCallbackContext::capture();
1605            let task = Rc::new(move || context.with(|| call_function(&function, Vec::new())));
1606            Ok(Value::Promise(promise_provider().run(task)))
1607        }
1608        ("new", [Value::Function(function)]) => {
1609            let promise = Promise::new();
1610            let resolving = promise.clone();
1611            let resolve = native_function("promise-resolve", 1, move |mut values| {
1612                let value = values.remove(0);
1613                settle_promise_result(&resolving, Ok(value.clone()));
1614                Ok(value)
1615            });
1616            let rejecting = promise.clone();
1617            let reject = native_function("promise-reject", 1, move |mut values| {
1618                let value = values.remove(0);
1619                rejecting.reject_value(value.clone());
1620                Ok(value)
1621            });
1622            if let Err(error) = call_function(function, vec![resolve, reject]) {
1623                promise.reject(error);
1624            }
1625            Ok(Value::Promise(promise))
1626        }
1627        ("delay", [millis, Value::Function(function)]) => {
1628            let millis = value_u64_integer(millis, "promise/delay")
1629                .map_err(|_| "promise/delay expects non-negative milliseconds".to_string())?;
1630            let function = function.clone();
1631            let context = crate::core::NativeCallbackContext::capture();
1632            let task = Rc::new(move || context.with(|| call_function(&function, Vec::new())));
1633            Ok(Value::Promise(
1634                promise_provider().delay(std::time::Duration::from_millis(millis), task),
1635            ))
1636        }
1637        ("run", _) => Err("promise/run expects one function".into()),
1638        ("new", [_]) => Err("promise/new expects a function".into()),
1639        ("new", _) => Err("promise/new expects one function".into()),
1640        ("from", _) => Err("promise/from expects one value".into()),
1641        ("all", _) => Err("promise/all expects one collection".into()),
1642        ("delay", _) => Err("promise/delay expects milliseconds and a function".into()),
1643        _ => Err(format!("unknown std.native.Promise operation: {method}")),
1644    }
1645}
1646
1647fn native_iter_operation(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1648    let unary = |label: &str| {
1649        arguments
1650            .first()
1651            .cloned()
1652            .filter(|_| arguments.len() == 1)
1653            .ok_or_else(|| format!("Iter/{label} expects one argument"))
1654    };
1655    let binary = |label: &str| {
1656        if arguments.len() == 2 {
1657            Ok((arguments[0].clone(), arguments[1].clone()))
1658        } else {
1659            Err(format!("Iter/{label} expects two arguments"))
1660        }
1661    };
1662    match method {
1663        "seq" => iterator_seq(unary(method)?),
1664        "iter" => make_iterator(unary(method)?),
1665        "iter-finite?" => Ok(Value::Bool(iterator_is_finite(&unary(method)?))),
1666        "iter-materialize" => Ok(Value::Vector(iterator_to_vec(unary(method)?)?.into())),
1667        "iter-next?" => iterator_has_next(&unary(method)?),
1668        "iter-next" => iterator_next(&unary(method)?),
1669        "iter-close" => iterator_close(&unary(method)?),
1670        "iter-concat" => iterator_concat(arguments),
1671        "iter-interleave" => iterator_interleave(arguments),
1672        "iter-zip" => iterator_zip(arguments),
1673        "iter-map" => {
1674            let (function, source) = binary(method)?;
1675            iterator_map(function, source)
1676        }
1677        "iter-filter" => {
1678            let (function, source) = binary(method)?;
1679            iterator_filter(function, source)
1680        }
1681        "iter-take-while" => {
1682            let (function, source) = binary(method)?;
1683            iterator_take_while(function, source)
1684        }
1685        "iter-drop-while" => {
1686            let (function, source) = binary(method)?;
1687            iterator_drop_while(function, source)
1688        }
1689        "iter-mapcat" => {
1690            let (function, source) = binary(method)?;
1691            iterator_mapcat(function, source)
1692        }
1693        "iter-keep" => {
1694            let (function, source) = binary(method)?;
1695            iterator_keep(function, source)
1696        }
1697        "iter-interpose" => {
1698            let (separator, source) = binary(method)?;
1699            iterator_interpose(separator, source)
1700        }
1701        "iter-every?" | "iter-any?" => {
1702            let (predicate, source) = binary(method)?;
1703            let iterator = make_iterator(source)?;
1704            let expect_every = method == "iter-every?";
1705            let result = (|| {
1706                while let Some(value) = iterator_try_next(&iterator)? {
1707                    let matched = call_value(predicate.clone(), vec![value])?.truthy();
1708                    if matched != expect_every {
1709                        return Ok(Value::Bool(!expect_every));
1710                    }
1711                }
1712                Ok(Value::Bool(expect_every))
1713            })();
1714            let close = iterator_close(&iterator);
1715            close?;
1716            result
1717        }
1718        "iter-take" | "iter-drop" => {
1719            let (amount, source) = binary(method)?;
1720            let amount = value_index(&amount)?;
1721            if method == "iter-take" {
1722                iterator_take(source, amount)
1723            } else {
1724                iterator_drop(source, amount)
1725            }
1726        }
1727        "iter-cycle" => iterator_cycle(unary(method)?),
1728        "iter-partition-pair" => iterator_partition(unary(method)?, 2, false),
1729        "iter-partition" | "iter-partition-all" => {
1730            let (amount, source) = binary(method)?;
1731            iterator_partition(source, value_index(&amount)?, method.ends_with("-all"))
1732        }
1733        "iter-range" => {
1734            let bounds = arguments
1735                .iter()
1736                .map(|value| {
1737                    numeric::to_i64_exact(value).map_err(|_| {
1738                        "iter-range bounds must fit signed 64-bit integers".to_string()
1739                    })
1740                })
1741                .collect::<Result<Vec<_>, _>>()?;
1742            let (start, end) = match bounds.as_slice() {
1743                [end] => (0, *end),
1744                [start, end] => (*start, *end),
1745                _ => return Err("iter-range expects an end or start and end".into()),
1746            };
1747            Ok(iterator_from_values(
1748                (start..end).map(Value::Number).collect(),
1749            ))
1750        }
1751        "iter-constantly" => Ok(iterator_constant(unary(method)?)),
1752        "iter-repeatedly" => Ok(iterator_repeated(unary(method)?)),
1753        "iter-iterate" => {
1754            let (function, seed) = binary(method)?;
1755            Ok(iterator_iterate(function, seed))
1756        }
1757        _ => Err(format!("unknown std.native.Iter operation: {method}")),
1758    }
1759}
1760
1761fn native_bytes_operation(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1762    match (method, arguments.as_slice()) {
1763        ("new", values) => native_bytes_new(values),
1764        ("count", [value]) => byte_count(value),
1765        ("get", [value, index]) => byte_get(value, index, None),
1766        ("get", [value, index, default]) => byte_get(value, index, Some(default.clone())),
1767        ("set", [value, index, item]) => byte_set(value, index, item),
1768        ("copy", [value]) => byte_copy(value),
1769        ("slice", [value, start]) => {
1770            let end = byte_count(value)?;
1771            byte_slice(value, start, &end)
1772        }
1773        ("slice", [value, start, end]) => byte_slice(value, start, end),
1774        ("u8" | "s8", [Value::Number(number)]) if (-128..=255).contains(number) => {
1775            let raw = (*number as i8) as u8;
1776            Ok(Value::Number(if method == "u8" {
1777                raw as i64
1778            } else {
1779                raw as i8 as i64
1780            }))
1781        }
1782        ("u8" | "s8", [_]) => Err(format!(
1783            "bytes/{method} expects a value in the range -128..255"
1784        )),
1785        _ => Err(format!(
1786            "std.native.Bytes/{method} received unsupported arguments"
1787        )),
1788    }
1789}
1790
1791fn native_bytes_new(values: &[Value]) -> Result<Value, String> {
1792    let values = values
1793        .iter()
1794        .map(|value| byte_input(value, "bytes"))
1795        .collect::<Result<Vec<_>, _>>()?;
1796    Ok(Value::ByteBuffer(Rc::new(RefCell::new(values))))
1797}
1798
1799/// Structural evaluator arms that are ordinary callable values.  Rust keeps
1800/// the implementations in `eval`, but exposes the names through real
1801/// `std.foundation` Vars just as the JVM runtime does.  Syntax and namespace
1802/// mutation forms deliberately remain structural and are never interned here.
1803pub(crate) fn syntax_symbol(name: &str) -> bool {
1804    const SYNTAX_FORMS: &[&str] = &[
1805        ".",
1806        "binding",
1807        "comment",
1808        "declare",
1809        "def",
1810        "defmacro",
1811        "defn",
1812        "do",
1813        "field",
1814        "fn",
1815        "if",
1816        "let",
1817        "letfn",
1818        "loop",
1819        "ns",
1820        "ns+",
1821        "quote",
1822        "read-forms",
1823        "recur",
1824        "require",
1825        "set!",
1826        "syntax-quote",
1827        "throw",
1828        "try",
1829        "var",
1830    ];
1831    SYNTAX_FORMS.contains(&name)
1832}
1833
1834pub fn with_macros<R>(
1835    macros: Rc<RefCell<HashMap<(String, String), Rc<Function>>>>,
1836    operation: impl FnOnce() -> R,
1837) -> R {
1838    ACTIVE_MACROS.with(|active| {
1839        let previous = active.replace(Some(macros));
1840        let result = operation();
1841        active.replace(previous);
1842        result
1843    })
1844}
1845
1846fn register_macro(namespace: &str, name: &str, function: Rc<Function>) -> Result<(), String> {
1847    ACTIVE_MACROS.with(|active| {
1848        active
1849            .try_borrow_mut()
1850            .map_err(|_| "macro registry is busy".into())
1851            .and_then(|opt| {
1852                if let Some(macros) = opt.as_ref() {
1853                    macros
1854                        .try_borrow_mut()
1855                        .map_err(|_| "macro registry is busy".into())
1856                        .map(|mut macros| {
1857                            macros.insert((namespace.into(), name.into()), function);
1858                        })
1859                } else {
1860                    Err("macro registry is unavailable".into())
1861                }
1862            })
1863    })
1864}
1865
1866fn resolve_macro_in(namespace: &str, name: &str) -> Option<Rc<Function>> {
1867    ACTIVE_MACROS.with(|active| {
1868        active.borrow().as_ref().and_then(|macros| {
1869            macros
1870                .borrow()
1871                .get(&(namespace.into(), name.into()))
1872                .cloned()
1873        })
1874    })
1875}
1876
1877pub(crate) fn resolve_macro(name: &str) -> Option<Rc<Function>> {
1878    if let Some((namespace, local)) = name.split_once('/') {
1879        let resolved = namespace_registry().ok().and_then(|registry| {
1880            let current = registry.current();
1881            if namespace == "-" {
1882                return Some(current.name().as_str().to_owned());
1883            }
1884            current
1885                .aliases()
1886                .into_iter()
1887                .find(|(alias, _)| alias.as_str() == namespace)
1888                .map(|(_, target)| target.name().as_str().to_owned())
1889        });
1890        return resolve_macro_in(resolved.as_deref().unwrap_or(namespace), local);
1891    }
1892    let current = namespace_registry()
1893        .map(|registry| registry.current().name().as_str().to_owned())
1894        .ok()?;
1895    resolve_macro_in(&current, name).or_else(|| resolve_macro_in("std.foundation", name))
1896}
1897
1898fn gensym(prefix: &str) -> String {
1899    let index = GENSYM_COUNTER.with(|counter| {
1900        let value = counter.get();
1901        counter.set(value + 1);
1902        value
1903    });
1904    format!("{prefix}{index}")
1905}
1906
1907pub(crate) fn form_to_value(form: &Form) -> Result<Value, String> {
1908    literal_value(form)
1909}
1910
1911fn metadata_value_to_form(value: &MetadataValue) -> Form {
1912    match value {
1913        MetadataValue::Nil => Form::Nil,
1914        MetadataValue::Boolean(value) => Form::Bool(*value),
1915        MetadataValue::Number(value) => Form::Number(*value),
1916        MetadataValue::Float(value) => Form::Float(*value),
1917        MetadataValue::BigInteger(value) => Form::BigInteger(value.clone()),
1918        MetadataValue::Character(value) => Form::Character(*value),
1919        MetadataValue::Regex(value) => Form::Regex(value.clone()),
1920        MetadataValue::Tagged(tag, value) => {
1921            Form::Tagged(tag.clone(), Box::new(metadata_value_to_form(value)))
1922        }
1923        MetadataValue::String(value) => Form::String(value.clone()),
1924        MetadataValue::Keyword(value) => Form::Keyword(value.as_str().into()),
1925        MetadataValue::Symbol(value) => Form::Symbol(value.as_str().into()),
1926        MetadataValue::Vector(values) => {
1927            Form::Vector(values.iter().map(metadata_value_to_form).collect())
1928        }
1929        MetadataValue::List(values) => {
1930            Form::List(values.iter().map(metadata_value_to_form).collect())
1931        }
1932        MetadataValue::Set(values) => {
1933            Form::Set(values.iter().map(metadata_value_to_form).collect())
1934        }
1935        MetadataValue::Map(values) => Form::Map(
1936            values
1937                .iter()
1938                .map(|(key, value)| (metadata_value_to_form(key), metadata_value_to_form(value)))
1939                .collect(),
1940        ),
1941    }
1942}
1943
1944pub(crate) fn value_to_form(value: &Value) -> Result<Form, String> {
1945    let form = match value {
1946        Value::Nil => Ok(Form::Nil),
1947        Value::Bool(value) => Ok(Form::Bool(*value)),
1948        Value::Number(value) => Ok(Form::Number(*value)),
1949        Value::Float(value) => Ok(Form::Float(*value)),
1950        Value::BigInteger(value) => Ok(Form::BigInteger(value.clone())),
1951        Value::Character(value) => Ok(Form::Character(*value)),
1952        Value::Regex(value) => Ok(Form::Regex(value.clone())),
1953        Value::String(value) => Ok(Form::String(value.clone())),
1954        Value::Keyword(value) => Ok(Form::Keyword(value.as_str().into())),
1955        Value::Symbol(value) => Ok(Form::Symbol(value.as_str().into())),
1956        Value::Tagged(value) => Ok(Form::Tagged(
1957            value.tag().get_name().into(),
1958            Box::new(value_to_form(value.form())?),
1959        )),
1960        Value::Pointer(value) => Ok(Form::Tagged(
1961            "ptr".into(),
1962            Box::new(value_to_form(&Value::Map(value.descriptor()))?),
1963        )),
1964        Value::List(values) => Ok(Form::List(
1965            values
1966                .iter()
1967                .map(|v| value_to_form(v))
1968                .collect::<Result<_, _>>()?,
1969        )),
1970        Value::Queue(values) => Ok(Form::List(
1971            values
1972                .iter()
1973                .map(|v| value_to_form(v))
1974                .collect::<Result<_, _>>()?,
1975        )),
1976        Value::Deque(values) => Ok(Form::List(
1977            values
1978                .iter()
1979                .map(|v| value_to_form(v))
1980                .collect::<Result<_, _>>()?,
1981        )),
1982        Value::Cons(values) => Ok(Form::List(
1983            values
1984                .iter()
1985                .map(|v| value_to_form(&v))
1986                .collect::<Result<_, _>>()?,
1987        )),
1988        Value::Vector(values) => Ok(Form::Vector(
1989            values
1990                .iter()
1991                .map(|v| value_to_form(v))
1992                .collect::<Result<_, _>>()?,
1993        )),
1994        Value::Tuple(values) => Ok(Form::Vector(
1995            values
1996                .iter()
1997                .map(|v| value_to_form(v))
1998                .collect::<Result<_, _>>()?,
1999        )),
2000        Value::MapEntry(entry) => Ok(Form::Vector(
2001            entry
2002                .iter()
2003                .map(value_to_form)
2004                .collect::<Result<_, _>>()?,
2005        )),
2006        Value::Set(_) | Value::OrderedSet(_) | Value::SortedSet(_) => Ok(Form::Set(
2007            set_items(value)
2008                .unwrap()
2009                .iter()
2010                .copied()
2011                .map(value_to_form)
2012                .collect::<Result<_, _>>()?,
2013        )),
2014        Value::Map(_)
2015        | Value::OrderedMap(_)
2016        | Value::SortedMap(_)
2017        | Value::Trie(_)
2018        | Value::PriorityMap(_) => Ok(Form::Map(
2019            map_entries(value)
2020                .unwrap()
2021                .into_iter()
2022                .map(|(key, value)| -> Result<(Form, Form), String> {
2023                    Ok((value_to_form(&key)?, value_to_form(&value)?))
2024                })
2025                .collect::<Result<_, _>>()?,
2026        )),
2027        value => Err(format!("cannot use {} as code", portable_type_name(value))),
2028    }?;
2029    Ok(match value_metadata(value) {
2030        Some(metadata) => Form::Metadata(
2031            Box::new(metadata_value_to_form(&MetadataValue::Map(
2032                metadata.entries().to_vec(),
2033            ))),
2034            Box::new(form),
2035        ),
2036        None => form,
2037    })
2038}
2039
2040pub(crate) fn bytecode_dynamic_bind(name: &str, value: Value) -> Result<(), String> {
2041    let registry = namespace_registry()?;
2042    let var = registry
2043        .resolve(&crate::lang::data::Symbol::parse(name))
2044        .ok_or_else(|| format!("binding expects a Var: {name}"))?;
2045    if !var.is_dynamic() {
2046        return Err(format!("binding expects a dynamic Var: {name}"));
2047    }
2048    var.bind(value);
2049    Ok(())
2050}
2051
2052pub(crate) fn bytecode_dynamic_unbind(name: &str) -> Result<(), String> {
2053    let registry = namespace_registry()?;
2054    let var = registry
2055        .resolve(&crate::lang::data::Symbol::parse(name))
2056        .ok_or_else(|| format!("binding expects a Var: {name}"))?;
2057    var.unbind().map(|_| ())
2058}
2059
2060fn macro_environment(env: &HashMap<String, Value>) -> Result<Value, String> {
2061    let namespace = namespace_registry()?.current().name().as_str().to_owned();
2062    let locals = env
2063        .iter()
2064        .filter(|(name, value)| !name.contains('/') && !matches!(value, Value::Var(_)))
2065        .map(|(name, _)| (Value::Symbol(Symbol::from(name.clone())), Value::Nil))
2066        .collect::<Vec<_>>();
2067    let entries = vec![
2068        (
2069            Value::Keyword(Keyword::from("ns")),
2070            Value::Symbol(Symbol::from(namespace)),
2071        ),
2072        (
2073            Value::Keyword(Keyword::from("locals")),
2074            Value::OrderedMap(Box::new(POrderedMap::from_iter(locals))),
2075        ),
2076        (
2077            Value::Keyword(Keyword::from("aliases")),
2078            Value::OrderedMap(Box::new(POrderedMap::new())),
2079        ),
2080    ];
2081    Ok(Value::OrderedMap(Box::new(POrderedMap::from_iter(entries))))
2082}
2083
2084fn macroexpand_call(
2085    name: &str,
2086    invocation: &[Form],
2087    env: &mut HashMap<String, Value>,
2088) -> Result<Option<Form>, String> {
2089    let function = match resolve_macro(name) {
2090        Some(function) => function,
2091        None => return Ok(None),
2092    };
2093    let mut arguments = Vec::with_capacity(invocation.len() + 1);
2094    arguments.push(form_to_value(&Form::List(invocation.to_vec()))?);
2095    arguments.push(macro_environment(env)?);
2096    for form in &invocation[1..] {
2097        arguments.push(form_to_value(form)?);
2098    }
2099    let expansion = call_function(&function, arguments)?;
2100    let expansion = value_to_form(&expansion)?;
2101    #[cfg(feature = "evaluation-journal")]
2102    evaluation_journal_macro(name, &Form::List(invocation.to_vec()), &expansion);
2103    Ok(Some(expansion))
2104}
2105
2106pub(crate) fn form_without_metadata(mut form: &Form) -> &Form {
2107    while let Form::Metadata(_, value) = form {
2108        form = value.as_ref();
2109    }
2110    form
2111}
2112
2113fn macro_clause_with_implicit_params(clause: &Form) -> Result<Form, String> {
2114    match form_without_metadata(clause) {
2115        Form::List(parts) if !parts.is_empty() => {
2116            let params = match form_without_metadata(&parts[0]) {
2117                Form::Vector(params) => params,
2118                _ => return Err("macro arity must start with a parameter vector".into()),
2119            };
2120            let mut implicit = vec![Form::Symbol("&form".into()), Form::Symbol("&env".into())];
2121            implicit.extend_from_slice(params);
2122            let mut new_parts = vec![Form::Vector(implicit)];
2123            new_parts.extend_from_slice(&parts[1..]);
2124            Ok(Form::List(new_parts))
2125        }
2126        _ => Err("macro arity must be a list".into()),
2127    }
2128}
2129
2130fn macroexpand_once(form: &Form, env: &mut HashMap<String, Value>) -> Result<Form, String> {
2131    match form {
2132        Form::List(values) if !values.is_empty() => {
2133            if let Form::Symbol(name) = &values[0] {
2134                if let Some(expanded) = macroexpand_call(name, values, env)? {
2135                    return Ok(expanded);
2136                }
2137            }
2138            Ok(form.clone())
2139        }
2140        _ => Ok(form.clone()),
2141    }
2142}
2143
2144pub(crate) fn vm_macroexpand(form: &Form) -> Result<Form, String> {
2145    let mut current = form.clone();
2146    let mut env = HashMap::new();
2147    for _ in 0..1000 {
2148        let expanded = macroexpand_once(&current, &mut env)?;
2149        if expanded == current {
2150            return Ok(current);
2151        }
2152        current = expanded;
2153    }
2154    Err("macro expansion exceeded 1000 steps".into())
2155}
2156
2157thread_local! {
2158    static TRACE_ENABLED: Cell<bool> = const { Cell::new(false) };
2159    static TRACE_STACK: RefCell<Vec<TraceFrame>> = const { RefCell::new(Vec::new()) };
2160    static TRACE_FAILURE_STACK: RefCell<Vec<TraceFrame>> = const { RefCell::new(Vec::new()) };
2161    #[cfg(feature = "evaluation-journal")]
2162    static EVALUATION_JOURNAL: RefCell<Option<crate::journal::JournalCollector>> = const { RefCell::new(None) };
2163    #[cfg(feature = "evaluation-journal")]
2164    static EVALUATION_JOURNAL_STACK: RefCell<Vec<crate::journal::OperationId>> = const { RefCell::new(Vec::new()) };
2165    static ACTIVE_MACROS: RefCell<Option<Rc<RefCell<HashMap<(String, String), Rc<Function>>>>>> =
2166        const { RefCell::new(None) };
2167    static GENSYM_COUNTER: Cell<u64> = const { Cell::new(0) };
2168}
2169
2170pub(crate) fn trace_stack_snapshot() -> Vec<TraceFrame> {
2171    TRACE_STACK.with(|stack| stack.borrow().clone())
2172}
2173
2174pub(crate) fn record_trace_failure() {
2175    if !tracing_enabled() {
2176        return;
2177    }
2178    let trace = trace_stack_snapshot();
2179    if !trace.is_empty() {
2180        TRACE_FAILURE_STACK.with(|failure| *failure.borrow_mut() = trace);
2181    }
2182}
2183
2184fn trace_failure_snapshot() -> Vec<TraceFrame> {
2185    TRACE_FAILURE_STACK.with(|stack| stack.borrow().clone())
2186}
2187
2188pub(crate) fn with_trace_stack<R>(trace: &[TraceFrame], operation: impl FnOnce() -> R) -> R {
2189    let previous = TRACE_STACK.with(|stack| {
2190        std::mem::replace(&mut *stack.borrow_mut(), trace.to_vec())
2191    });
2192    let result = operation();
2193    TRACE_STACK.with(|stack| {
2194        *stack.borrow_mut() = previous;
2195    });
2196    result
2197}
2198
2199pub(crate) fn trace_frame(
2200    name: String,
2201    namespace: Option<String>,
2202    site: Option<ExceptionSite>,
2203) -> TraceFrame {
2204    TraceFrame {
2205        name,
2206        namespace,
2207        site,
2208    }
2209}
2210
2211#[cfg(feature = "evaluation-journal")]
2212fn journal_preview(value: &Value) -> crate::journal::ValuePreview {
2213    EVALUATION_JOURNAL.with(|active| {
2214        active
2215            .borrow()
2216            .as_ref()
2217            .expect("evaluation journal must be active")
2218            .preview_value(portable_type_name(value), value.display())
2219    })
2220}
2221
2222#[cfg(feature = "evaluation-journal")]
2223fn evaluation_journal_enter(
2224    function: &Function,
2225    arguments: &[Value],
2226) -> Option<crate::journal::OperationId> {
2227    if EVALUATION_JOURNAL.with(|active| active.borrow().is_none()) {
2228        return None;
2229    }
2230    let values = arguments.iter().map(journal_preview).collect();
2231    let parent_operation = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().last().copied());
2232    let depth = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().len());
2233    EVALUATION_JOURNAL.with(|active| {
2234        let mut active = active.borrow_mut();
2235        let collector = active.as_mut()?;
2236        let operation = collector.next_operation_id();
2237        let mut event =
2238            crate::journal::JournalEvent::new(crate::journal::JournalEventKind::OperationEnter);
2239        event.operation = Some(operation);
2240        event.parent_operation = parent_operation;
2241        event.depth = depth;
2242        event.function = Some(
2243            function
2244                .name
2245                .clone()
2246                .unwrap_or_else(|| "<anonymous>".into()),
2247        );
2248        event.values = values;
2249        collector.record(event);
2250        EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow_mut().push(operation));
2251        Some(operation)
2252    })
2253}
2254
2255#[cfg(feature = "evaluation-journal")]
2256fn evaluation_journal_exit(
2257    operation: Option<crate::journal::OperationId>,
2258    function: &Function,
2259    result: Option<&Value>,
2260) {
2261    let Some(operation) = operation else { return };
2262    let value = result.map(journal_preview);
2263    EVALUATION_JOURNAL.with(|active| {
2264        if let Some(collector) = active.borrow_mut().as_mut() {
2265            let mut event = crate::journal::JournalEvent::new(
2266                crate::journal::JournalEventKind::OperationReturn,
2267            );
2268            event.operation = Some(operation);
2269            event.function = Some(
2270                function
2271                    .name
2272                    .clone()
2273                    .unwrap_or_else(|| "<anonymous>".into()),
2274            );
2275            event.values = value.into_iter().collect();
2276            collector.record(event);
2277        }
2278    });
2279    EVALUATION_JOURNAL_STACK.with(|stack| {
2280        let popped = stack.borrow_mut().pop();
2281        debug_assert_eq!(popped, Some(operation));
2282    });
2283}
2284
2285#[cfg(feature = "evaluation-journal")]
2286fn evaluation_journal_macro(name: &str, source: &Form, expansion: &Form) {
2287    let parent_operation = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().last().copied());
2288    let depth = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().len());
2289    EVALUATION_JOURNAL.with(|active| {
2290        if let Some(collector) = active.borrow_mut().as_mut() {
2291            let mut event =
2292                crate::journal::JournalEvent::new(crate::journal::JournalEventKind::MacroExpand);
2293            event.parent_operation = parent_operation;
2294            event.depth = depth;
2295            event.function = Some(name.into());
2296            event.values = vec![
2297                collector.preview_value("form", source.to_string()),
2298                collector.preview_value("form", expansion.to_string()),
2299            ];
2300            collector.record(event);
2301        }
2302    });
2303}
2304
2305struct StackTraceGuard {
2306    previous: bool,
2307}
2308
2309impl StackTraceGuard {
2310    fn enable() -> Self {
2311        let previous = TRACE_ENABLED.with(|enabled| {
2312            let previous = enabled.get();
2313            enabled.set(true);
2314            previous
2315        });
2316        TRACE_STACK.with(|stack| stack.borrow_mut().clear());
2317        TRACE_FAILURE_STACK.with(|stack| stack.borrow_mut().clear());
2318        Self { previous }
2319    }
2320}
2321
2322/// Runs an execution boundary with Hara stack collection enabled.
2323///
2324/// Stack collection belongs to callable invocation, not to a second tree
2325/// evaluator. Fiber, bytecode, and other execution targets can share this
2326/// boundary while retaining the same opt-in error contract.
2327pub(crate) fn with_stack_trace<R>(operation: impl FnOnce() -> R) -> R {
2328    let _guard = StackTraceGuard::enable();
2329    operation()
2330}
2331
2332/// Runs an evaluation with trace collection and returns the frames before the
2333/// boundary resets its thread-local state.  The textual error contract remains
2334/// unchanged; embedding hosts can use this companion to build structured
2335/// diagnostics without parsing rendered stack lines.
2336pub fn with_stack_trace_snapshot<R>(operation: impl FnOnce() -> R) -> (R, Vec<TraceFrame>) {
2337    let _guard = StackTraceGuard::enable();
2338    let result = operation();
2339    let trace = {
2340        let failure = trace_failure_snapshot();
2341        if failure.is_empty() {
2342            trace_stack_snapshot()
2343        } else {
2344            failure
2345        }
2346    };
2347    (result, trace)
2348}
2349
2350impl Drop for StackTraceGuard {
2351    fn drop(&mut self) {
2352        TRACE_STACK.with(|stack| stack.borrow_mut().clear());
2353        TRACE_FAILURE_STACK.with(|stack| stack.borrow_mut().clear());
2354        TRACE_ENABLED.with(|enabled| enabled.set(self.previous));
2355    }
2356}
2357
2358fn tracing_enabled() -> bool {
2359    TRACE_ENABLED.with(Cell::get)
2360}
2361
2362pub(crate) fn append_trace(error: String) -> String {
2363    if !tracing_enabled() {
2364        return error;
2365    }
2366    record_trace_failure();
2367    let frames = TRACE_STACK.with(|stack| stack.borrow().iter().rev().cloned().collect::<Vec<_>>());
2368    if frames.is_empty() {
2369        return error;
2370    }
2371    if error.contains("\n[hara stack]") {
2372        return error;
2373    }
2374    format!(
2375        "{error}\n[hara stack]\n{}",
2376        frames
2377            .iter()
2378            .map(|frame| format!("  at {}", frame.label()))
2379            .collect::<Vec<_>>()
2380            .join("\n")
2381    )
2382}
2383
2384#[derive(Debug, Clone)]
2385enum IteratorGenerator {
2386    Seq(PSeq<Result<Value, String>>),
2387    Constant(Value),
2388    Repeated(Value),
2389    Iterate(Value, Value),
2390    Take(Value, usize),
2391    Drop(Value, usize),
2392    Cycle(Value, Vec<Value>, usize, bool),
2393    TakeWhile(Value, Value),
2394    DropWhile(Value, Value, bool),
2395    Map(Value, Value, bool),
2396    Filter(Value, Value),
2397    Mapcat(Value, Value, Option<Value>),
2398    Keep(Value, Value),
2399    Prepend(Option<Value>, Value),
2400    Concat(Vec<Value>, usize),
2401    Zip(Vec<Value>),
2402    Interleave(Vec<Value>, usize),
2403    Interpose(Value, Value, bool, Option<Value>),
2404    Partition(Value, usize, bool),
2405}
2406
2407#[derive(Debug, Clone)]
2408pub struct IteratorState {
2409    values: Vec<Value>,
2410    index: usize,
2411    closed: bool,
2412    cycle: bool,
2413    lookahead: Option<Value>,
2414    generator: Option<IteratorGenerator>,
2415}
2416
2417fn close_iterator_source(value: &Value) {
2418    if let Value::Iterator(iterator) = value {
2419        if let Ok(mut state) = iterator.try_borrow_mut() {
2420            state.close();
2421        }
2422    }
2423}
2424
2425impl IteratorState {
2426    fn new(values: Vec<Value>) -> Self {
2427        Self {
2428            values,
2429            index: 0,
2430            closed: false,
2431            cycle: false,
2432            lookahead: None,
2433            generator: None,
2434        }
2435    }
2436    fn generated(generator: IteratorGenerator) -> Self {
2437        Self {
2438            values: Vec::new(),
2439            index: 0,
2440            closed: false,
2441            cycle: false,
2442            lookahead: None,
2443            generator: Some(generator),
2444        }
2445    }
2446    pub(crate) fn is_finite(&self) -> bool {
2447        if self.closed || self.generator.is_none() {
2448            return true;
2449        }
2450        match self.generator.as_ref().unwrap() {
2451            IteratorGenerator::Seq(_) => false,
2452            IteratorGenerator::Constant(_)
2453            | IteratorGenerator::Repeated(_)
2454            | IteratorGenerator::Iterate(_, _)
2455            | IteratorGenerator::Cycle(_, _, _, _) => false,
2456            IteratorGenerator::Take(_, _) => true,
2457            IteratorGenerator::Drop(source, _)
2458            | IteratorGenerator::TakeWhile(_, source)
2459            | IteratorGenerator::DropWhile(_, source, _)
2460            | IteratorGenerator::Map(_, source, _)
2461            | IteratorGenerator::Filter(_, source)
2462            | IteratorGenerator::Keep(_, source)
2463            | IteratorGenerator::Prepend(_, source)
2464            | IteratorGenerator::Interpose(source, _, _, _)
2465            | IteratorGenerator::Partition(source, _, _) => value_iterator_is_finite(source),
2466            IteratorGenerator::Mapcat(_, _, _) => false,
2467            IteratorGenerator::Concat(sources, _) | IteratorGenerator::Interleave(sources, _) => {
2468                sources.iter().all(value_iterator_is_finite)
2469            }
2470            IteratorGenerator::Zip(sources) => sources.iter().any(value_iterator_is_finite),
2471        }
2472    }
2473    fn has_next(&mut self) -> Result<bool, String> {
2474        if self.lookahead.is_some() {
2475            return Ok(true);
2476        }
2477        match self.pull_next()? {
2478            Some(value) => {
2479                self.lookahead = Some(value);
2480                Ok(true)
2481            }
2482            None => Ok(false),
2483        }
2484    }
2485    fn try_next(&mut self) -> Result<Option<Value>, String> {
2486        if let Some(value) = self.lookahead.take() {
2487            return Ok(Some(value));
2488        }
2489        self.pull_next()
2490    }
2491    fn pull_next(&mut self) -> Result<Option<Value>, String> {
2492        if self.closed {
2493            return Ok(None);
2494        }
2495        if let Some(generator) = &mut self.generator {
2496            return match generator {
2497                IteratorGenerator::Seq(sequence) => match sequence.peek_first() {
2498                    None => {
2499                        self.closed = true;
2500                        Ok(None)
2501                    }
2502                    Some(result) => {
2503                        *sequence = sequence.pop_first();
2504                        result.map(Some)
2505                    }
2506                },
2507                IteratorGenerator::Constant(value) => Ok(Some(value.clone())),
2508                IteratorGenerator::Repeated(function) => {
2509                    call_value(function.clone(), Vec::new()).map(Some)
2510                }
2511                IteratorGenerator::Iterate(function, current) => {
2512                    let output = current.clone();
2513                    *current = call_value(function.clone(), vec![current.clone()])?;
2514                    Ok(Some(output))
2515                }
2516                IteratorGenerator::Take(source, remaining) => {
2517                    if *remaining == 0 {
2518                        close_iterator_source(source);
2519                        self.closed = true;
2520                        Ok(None)
2521                    } else {
2522                        *remaining -= 1;
2523                        let value = iterator_try_next(source)?;
2524                        if value.is_none() {
2525                            close_iterator_source(source);
2526                            self.closed = true;
2527                        }
2528                        Ok(value)
2529                    }
2530                }
2531                IteratorGenerator::Drop(source, remaining) => {
2532                    while *remaining > 0 {
2533                        if iterator_try_next(source)?.is_none() {
2534                            close_iterator_source(source);
2535                            self.closed = true;
2536                            return Ok(None);
2537                        }
2538                        *remaining -= 1;
2539                    }
2540                    let value = iterator_try_next(source)?;
2541                    if value.is_none() {
2542                        close_iterator_source(source);
2543                        self.closed = true;
2544                    }
2545                    Ok(value)
2546                }
2547                IteratorGenerator::Cycle(source, cache, index, exhausted) => {
2548                    if *index < cache.len() {
2549                        let value = cache[*index].clone();
2550                        *index += 1;
2551                        Ok(Some(value))
2552                    } else if *exhausted {
2553                        if cache.is_empty() {
2554                            self.closed = true;
2555                            Ok(None)
2556                        } else {
2557                            *index = 1;
2558                            Ok(Some(cache[0].clone()))
2559                        }
2560                    } else {
2561                        match iterator_try_next(source)? {
2562                            Some(value) => {
2563                                cache.push(value.clone());
2564                                *index += 1;
2565                                Ok(Some(value))
2566                            }
2567                            None => {
2568                                close_iterator_source(source);
2569                                *exhausted = true;
2570                                if cache.is_empty() {
2571                                    self.closed = true;
2572                                    Ok(None)
2573                                } else {
2574                                    *index = 1;
2575                                    Ok(Some(cache[0].clone()))
2576                                }
2577                            }
2578                        }
2579                    }
2580                }
2581                IteratorGenerator::TakeWhile(function, source) => {
2582                    let Some(value) = iterator_try_next(source)? else {
2583                        close_iterator_source(source);
2584                        self.closed = true;
2585                        return Ok(None);
2586                    };
2587                    if call_value(function.clone(), vec![value.clone()])?.truthy() {
2588                        Ok(Some(value))
2589                    } else {
2590                        close_iterator_source(source);
2591                        self.closed = true;
2592                        Ok(None)
2593                    }
2594                }
2595                IteratorGenerator::DropWhile(function, source, started) => loop {
2596                    let Some(value) = iterator_try_next(source)? else {
2597                        close_iterator_source(source);
2598                        self.closed = true;
2599                        break Ok(None);
2600                    };
2601                    if *started || !call_value(function.clone(), vec![value.clone()])?.truthy() {
2602                        *started = true;
2603                        break Ok(Some(value));
2604                    }
2605                },
2606                IteratorGenerator::Map(function, source, spread) => {
2607                    let Some(value) = iterator_try_next(source)? else {
2608                        close_iterator_source(source);
2609                        self.closed = true;
2610                        return Ok(None);
2611                    };
2612                    match value {
2613                        value if !*spread => call_value(function.clone(), vec![value]),
2614                        Value::Tuple(values) => {
2615                            call_value(function.clone(), values.iter().cloned().collect())
2616                        }
2617                        Value::Vector(values) => {
2618                            call_value(function.clone(), values.iter().cloned().collect())
2619                        }
2620                        value => call_value(function.clone(), vec![value]),
2621                    }
2622                    .map(Some)
2623                }
2624                IteratorGenerator::Filter(function, source) => loop {
2625                    let Some(value) = iterator_try_next(source)? else {
2626                        close_iterator_source(source);
2627                        self.closed = true;
2628                        break Ok(None);
2629                    };
2630                    if call_value(function.clone(), vec![value.clone()])?.truthy() {
2631                        break Ok(Some(value));
2632                    }
2633                },
2634                IteratorGenerator::Mapcat(function, source, pending) => loop {
2635                    if let Some(iterator) = pending {
2636                        match iterator_try_next(iterator)? {
2637                            Some(value) => break Ok(Some(value)),
2638                            None => {
2639                                close_iterator_source(iterator);
2640                                *pending = None;
2641                            }
2642                        }
2643                    }
2644                    let Some(value) = iterator_try_next(source)? else {
2645                        close_iterator_source(source);
2646                        self.closed = true;
2647                        break Ok(None);
2648                    };
2649                    *pending = Some(make_iterator(call_value(function.clone(), vec![value])?)?);
2650                },
2651                IteratorGenerator::Keep(function, source) => loop {
2652                    let Some(value) = iterator_try_next(source)? else {
2653                        close_iterator_source(source);
2654                        self.closed = true;
2655                        break Ok(None);
2656                    };
2657                    let mapped = call_value(function.clone(), vec![value])?;
2658                    if !matches!(mapped, Value::Nil) {
2659                        break Ok(Some(mapped));
2660                    }
2661                },
2662                IteratorGenerator::Prepend(head, source) => {
2663                    if let Some(value) = head.take() {
2664                        Ok(Some(value))
2665                    } else {
2666                        let value = iterator_try_next(source)?;
2667                        if value.is_none() {
2668                            close_iterator_source(source);
2669                            self.closed = true;
2670                        }
2671                        Ok(value)
2672                    }
2673                }
2674                IteratorGenerator::Concat(sources, index) => {
2675                    while *index < sources.len() {
2676                        match iterator_try_next(&sources[*index])? {
2677                            Some(value) => return Ok(Some(value)),
2678                            None => {
2679                                close_iterator_source(&sources[*index]);
2680                                *index += 1;
2681                            }
2682                        }
2683                    }
2684                    self.closed = true;
2685                    Ok(None)
2686                }
2687                IteratorGenerator::Zip(sources) => {
2688                    for source in sources.iter() {
2689                        if !matches!(iterator_has_next(source)?, Value::Bool(true)) {
2690                            for source in sources.iter() {
2691                                close_iterator_source(source);
2692                            }
2693                            self.closed = true;
2694                            return Ok(None);
2695                        }
2696                    }
2697                    let mut values = Vec::new();
2698                    for source in sources.iter() {
2699                        let Some(value) = iterator_try_next(source)? else {
2700                            for source in sources.iter() {
2701                                close_iterator_source(source);
2702                            }
2703                            self.closed = true;
2704                            return Ok(None);
2705                        };
2706                        values.push(value);
2707                    }
2708                    Ok(Some(Value::Vector(values.into())))
2709                }
2710                IteratorGenerator::Interleave(sources, index) => {
2711                    if sources.is_empty() {
2712                        self.closed = true;
2713                        return Ok(None);
2714                    }
2715                    if *index == 0 {
2716                        for source in sources.iter() {
2717                            if !matches!(iterator_has_next(source)?, Value::Bool(true)) {
2718                                for source in sources.iter() {
2719                                    close_iterator_source(source);
2720                                }
2721                                self.closed = true;
2722                                return Ok(None);
2723                            }
2724                        }
2725                    }
2726                    let source = &sources[*index];
2727                    let Some(value) = iterator_try_next(source)? else {
2728                        for source in sources.iter() {
2729                            close_iterator_source(source);
2730                        }
2731                        self.closed = true;
2732                        return Ok(None);
2733                    };
2734                    *index = (*index + 1) % sources.len();
2735                    Ok(Some(value))
2736                }
2737                IteratorGenerator::Interpose(source, separator, first, pending) => {
2738                    if let Some(value) = pending.take() {
2739                        return Ok(Some(value));
2740                    }
2741                    match iterator_try_next(source)? {
2742                        None => {
2743                            close_iterator_source(source);
2744                            self.closed = true;
2745                            Ok(None)
2746                        }
2747                        Some(value) if *first => {
2748                            *first = false;
2749                            Ok(Some(value))
2750                        }
2751                        Some(value) => {
2752                            *pending = Some(value);
2753                            Ok(Some(separator.clone()))
2754                        }
2755                    }
2756                }
2757                IteratorGenerator::Partition(source, amount, all) => {
2758                    let mut values = Vec::new();
2759                    for _ in 0..*amount {
2760                        match iterator_try_next(source)? {
2761                            Some(value) => values.push(value),
2762                            None => {
2763                                close_iterator_source(source);
2764                                self.closed = true;
2765                                if values.is_empty() || !*all {
2766                                    return Ok(None);
2767                                }
2768                                break;
2769                            }
2770                        }
2771                    }
2772                    if values.is_empty() {
2773                        self.closed = true;
2774                        Ok(None)
2775                    } else {
2776                        Ok(Some(Value::Vector(values.into())))
2777                    }
2778                }
2779            };
2780        }
2781        if self.values.is_empty() {
2782            self.closed = true;
2783            return Ok(None);
2784        }
2785        if self.cycle && self.index >= self.values.len() {
2786            self.index = 0;
2787        }
2788        if self.index >= self.values.len() {
2789            self.closed = true;
2790            return Ok(None);
2791        }
2792        let value = self.values[self.index].clone();
2793        self.index += 1;
2794        Ok(Some(value))
2795    }
2796    fn close(&mut self) {
2797        if self.closed {
2798            self.lookahead = None;
2799            return;
2800        }
2801        self.closed = true;
2802        self.lookahead = None;
2803        if let Some(generator) = &self.generator {
2804            match generator {
2805                IteratorGenerator::Constant(_)
2806                | IteratorGenerator::Repeated(_)
2807                | IteratorGenerator::Iterate(_, _)
2808                | IteratorGenerator::Seq(_) => {}
2809                IteratorGenerator::Take(source, _)
2810                | IteratorGenerator::Drop(source, _)
2811                | IteratorGenerator::Cycle(source, _, _, _)
2812                | IteratorGenerator::TakeWhile(_, source)
2813                | IteratorGenerator::DropWhile(_, source, _)
2814                | IteratorGenerator::Map(_, source, _)
2815                | IteratorGenerator::Filter(_, source)
2816                | IteratorGenerator::Keep(_, source)
2817                | IteratorGenerator::Prepend(_, source)
2818                | IteratorGenerator::Interpose(source, _, _, _)
2819                | IteratorGenerator::Partition(source, _, _) => close_iterator_source(source),
2820                IteratorGenerator::Mapcat(_, source, pending) => {
2821                    close_iterator_source(source);
2822                    if let Some(pending) = pending {
2823                        close_iterator_source(pending);
2824                    }
2825                }
2826                IteratorGenerator::Concat(sources, _)
2827                | IteratorGenerator::Zip(sources)
2828                | IteratorGenerator::Interleave(sources, _) => {
2829                    for source in sources {
2830                        close_iterator_source(source);
2831                    }
2832                }
2833            }
2834        }
2835    }
2836}
2837
2838fn value_iterator_is_finite(value: &Value) -> bool {
2839    match value {
2840        Value::Iterator(iterator) => iterator.borrow().is_finite(),
2841        Value::Seq(_) => false,
2842        _ => true,
2843    }
2844}
2845
2846#[inline(never)]
2847fn sequential_equality(left: &Value, right: &Value) -> Option<bool> {
2848    fn items(value: &Value) -> Option<Vec<Value>> {
2849        match value {
2850            Value::Seq(values) => values.iter().collect::<Result<Vec<_>, _>>().ok(),
2851            Value::List(values) => Some(values.iter().cloned().collect()),
2852            Value::Cons(values) => Some(values.iter().collect()),
2853            Value::Queue(values) => Some(values.iter().cloned().collect()),
2854            Value::Deque(values) => Some(values.iter().cloned().collect()),
2855            Value::Tuple(values) => Some(values.iter().cloned().collect()),
2856            Value::Vector(values) => Some(values.iter().cloned().collect()),
2857            _ => None,
2858        }
2859    }
2860    Some(items(left)? == items(right)?)
2861}
2862
2863/// Returns cloned entries for every map-like runtime representation.
2864/// Embedding hosts should use this instead of depending on a concrete
2865/// persistent-map implementation.
2866pub fn map_entries(value: &Value) -> Option<Vec<(Value, Value)>> {
2867    match value {
2868        Value::Map(values) => Some(values.iter().map(|(k, v)| (k.clone(), v.clone())).collect()),
2869        Value::OrderedMap(values) => {
2870            Some(values.iter().map(|(k, v)| (k.clone(), v.clone())).collect())
2871        }
2872        Value::SortedMap(values) => {
2873            Some(values.iter().map(|(k, v)| (k.clone(), v.clone())).collect())
2874        }
2875        Value::PriorityMap(values) => Some(values.iter().collect()),
2876        Value::Trie(values) => Some(
2877            values
2878                .entries()
2879                .into_iter()
2880                .map(|(k, v)| (Value::String(k), v.clone()))
2881                .collect(),
2882        ),
2883        _ => None,
2884    }
2885}
2886
2887fn pointer_from_descriptor(descriptor: Value) -> Result<Value, String> {
2888    let entries =
2889        map_entries(&descriptor).ok_or_else(|| "pointer expects one descriptor map".to_string())?;
2890    let context_key = Value::Keyword(Keyword::from("context"));
2891    let mut context = None;
2892    let mut fields = Vec::new();
2893    for (key, value) in entries {
2894        if key == context_key {
2895            if context.is_some() {
2896                return Err("pointer descriptor contains duplicate :context".into());
2897            }
2898            context = match value {
2899                Value::Keyword(context) => Some(context),
2900                _ => return Err("pointer :context must be a keyword".into()),
2901            };
2902        } else {
2903            if !matches!(key, Value::Keyword(_)) {
2904                return Err("pointer descriptor fields must use keyword keys".into());
2905            }
2906            fields.push((key, value));
2907        }
2908    }
2909    let context = context.ok_or_else(|| "pointer descriptor requires :context".to_string())?;
2910    Ok(Value::Pointer(PPointer::new(
2911        context,
2912        fields.into_iter().collect(),
2913    )))
2914}
2915
2916/// Returns whether a value may leave the evaluator session as immutable HAL data.
2917///
2918/// Session transfer is deliberately narrower than displayability. Functions,
2919/// Vars, mutable containers, iterators, asynchronous values, and native handles
2920/// all have printable representations, but those representations must not turn
2921/// a live session-owned value into an apparently successful transfer.
2922pub(crate) fn session_transferable(value: &Value) -> bool {
2923    match value {
2924        Value::Number(_)
2925        | Value::Float(_)
2926        | Value::BigInteger(_)
2927        | Value::Character(_)
2928        | Value::Regex(_)
2929        | Value::Tagged(_)
2930        | Value::Bool(_)
2931        | Value::String(_)
2932        | Value::Keyword(_)
2933        | Value::Bytes(_)
2934        | Value::Symbol(_)
2935        | Value::Nil => true,
2936        value @ (Value::Map(_)
2937        | Value::OrderedMap(_)
2938        | Value::SortedMap(_)
2939        | Value::Trie(_)
2940        | Value::PriorityMap(_)) => map_entries(value).is_some_and(|entries| {
2941            entries
2942                .iter()
2943                .all(|(key, value)| session_transferable(key) && session_transferable(value))
2944        }),
2945        value @ (Value::Set(_) | Value::OrderedSet(_) | Value::SortedSet(_)) => set_items(value)
2946            .is_some_and(|values| values.iter().all(|value| session_transferable(value))),
2947        Value::List(values) => values.iter().all(session_transferable),
2948        Value::Cons(values) => values.iter().all(|value| session_transferable(&value)),
2949        Value::Queue(values) => values.iter().all(session_transferable),
2950        Value::Deque(values) => values.iter().all(session_transferable),
2951        Value::Tuple(values) => values.iter().all(session_transferable),
2952        Value::Vector(values) => values.iter().all(session_transferable),
2953        Value::MapEntry(entry) => {
2954            session_transferable(entry.key()) && session_transferable(entry.value())
2955        }
2956        Value::Struct(value) => value.ordered_values().into_iter().all(session_transferable),
2957        Value::Pointer(value) => value
2958            .fields()
2959            .iter()
2960            .all(|(key, value)| session_transferable(key) && session_transferable(value)),
2961        Value::ExceptionInfo(value) => {
2962            session_transferable(&value.data)
2963                && value.cause.as_deref().map_or(true, session_transferable)
2964        }
2965        Value::ByteBuffer(_)
2966        | Value::Array(_)
2967        | Value::Object(_)
2968        | Value::Promise(_)
2969        | Value::Atom(_)
2970        | Value::Recur(_)
2971        | Value::Function(_)
2972        | Value::Seq(_)
2973        | Value::Iterator(_)
2974        | Value::Var(_)
2975        | Value::Namespace(_)
2976        | Value::Extension(_)
2977        | Value::StructType(_)
2978        | Value::MutableType(_)
2979        | Value::Mutable(_)
2980        | Value::Protocol(_)
2981        | Value::NativeType(_)
2982        | Value::Schema(_)
2983        | Value::Coroutine(_)
2984        | Value::Stream(_)
2985        | Value::Result(_)
2986        | Value::MutableCollection(_) => false,
2987    }
2988}
2989
2990fn map_value<'a>(value: &'a Value, key: &Value) -> Option<&'a Value> {
2991    match value {
2992        Value::Map(values) => values.get(key),
2993        Value::OrderedMap(values) => values.get(key),
2994        Value::SortedMap(values) => values.get(key),
2995        Value::PriorityMap(values) => values.get(key),
2996        Value::Trie(values) => match key {
2997            Value::String(key) => values.get(key),
2998            _ => None,
2999        },
3000        _ => None,
3001    }
3002}
3003
3004fn map_equality(left: &Value, right: &Value) -> Option<bool> {
3005    let left_entries = map_entries(left)?;
3006    let right_entries = map_entries(right)?;
3007    Some(
3008        left_entries.len() == right_entries.len()
3009            && left_entries
3010                .iter()
3011                .all(|(key, value)| map_value(right, key) == Some(value)),
3012    )
3013}
3014
3015fn set_items(value: &Value) -> Option<Vec<&Value>> {
3016    match value {
3017        Value::Set(values) => Some(values.iter().collect()),
3018        Value::OrderedSet(values) => Some(values.iter().collect()),
3019        Value::SortedSet(values) => Some(values.iter().collect()),
3020        _ => None,
3021    }
3022}
3023
3024fn set_equality(left: &Value, right: &Value) -> Option<bool> {
3025    let left_items = set_items(left)?;
3026    let right_items = set_items(right)?;
3027    Some(
3028        left_items.len() == right_items.len()
3029            && left_items.iter().all(|item| right_items.contains(item)),
3030    )
3031}
3032
3033fn map_assoc_value(collection: &Value, key: Value, value: Value) -> Result<Value, String> {
3034    Ok(match collection {
3035        Value::Map(values) => Value::Map(values.assoc_value(key, value)),
3036        Value::OrderedMap(values) => Value::OrderedMap(Box::new(values.assoc_value(key, value))),
3037        Value::SortedMap(values) => Value::SortedMap(Box::new(values.assoc_value(key, value))),
3038        Value::PriorityMap(values) => Value::PriorityMap(Box::new(values.assoc_value(key, value))),
3039        Value::Trie(values) => match key {
3040            Value::String(key) => Value::Trie(Box::new(values.assoc_value(key, value))),
3041            _ => return Err("trie expects string keys".into()),
3042        },
3043        _ => return Err("assoc expects a map".into()),
3044    })
3045}
3046
3047fn map_dissoc_value(collection: &Value, key: &Value) -> Result<Value, String> {
3048    Ok(match collection {
3049        Value::Map(values) => Value::Map(values.dissoc_value(key)),
3050        Value::OrderedMap(values) => Value::OrderedMap(Box::new(values.dissoc_value(key))),
3051        Value::SortedMap(values) => Value::SortedMap(Box::new(values.dissoc_value(key))),
3052        Value::PriorityMap(values) => Value::PriorityMap(Box::new(values.dissoc_value(key))),
3053        Value::Trie(values) => match key {
3054            Value::String(key) => Value::Trie(Box::new(values.dissoc_value(key))),
3055            _ => return Err("trie expects string keys".into()),
3056        },
3057        _ => return Err("dissoc expects a map".into()),
3058    })
3059}
3060
3061fn set_find(collection: &Value, key: &Value) -> Option<Value> {
3062    set_items(collection)?
3063        .into_iter()
3064        .find(|value| *value == key)
3065        .cloned()
3066}
3067
3068fn set_conj_value(collection: &Value, value: Value) -> Result<Value, String> {
3069    Ok(match collection {
3070        Value::Set(values) => Value::Set(values.conj_value(value)),
3071        Value::OrderedSet(values) => Value::OrderedSet(Box::new(values.conj_value(value))),
3072        Value::SortedSet(values) => Value::SortedSet(Box::new(values.conj_value(value))),
3073        _ => return Err("conj expects a set".into()),
3074    })
3075}
3076
3077fn set_dissoc_value(collection: &Value, value: &Value) -> Result<Value, String> {
3078    Ok(match collection {
3079        Value::Set(values) => Value::Set(values.dissoc_value(value)),
3080        Value::OrderedSet(values) => Value::OrderedSet(Box::new(values.dissoc_value(value))),
3081        Value::SortedSet(values) => Value::SortedSet(Box::new(values.dissoc_value(value))),
3082        _ => return Err("dissoc expects a set".into()),
3083    })
3084}
3085
3086fn collection_to_mutable(value: &Value) -> Result<Value, String> {
3087    let mutable = match value {
3088        Value::Map(values) => MutableCollection::Map(values.to_mutable()),
3089        Value::OrderedMap(values) => MutableCollection::OrderedMap(values.to_mutable()),
3090        Value::SortedMap(values) => MutableCollection::SortedMap(values.to_mutable()),
3091        Value::Trie(values) => MutableCollection::Trie(values.to_mutable()),
3092        Value::Set(values) => MutableCollection::Set(values.to_mutable()),
3093        Value::OrderedSet(values) => MutableCollection::OrderedSet(values.to_mutable()),
3094        Value::SortedSet(values) => MutableCollection::SortedSet(values.to_mutable()),
3095        Value::List(values) => MutableCollection::List(values.to_mutable()),
3096        Value::Queue(values) => MutableCollection::Queue(values.to_mutable()),
3097        Value::Vector(values) => MutableCollection::Vector(values.to_mutable()),
3098        Value::MutableCollection(_) => return Err("value is already mutable".into()),
3099        _ => return Err("to-mutable expects a persistent collection".into()),
3100    };
3101    Ok(Value::MutableCollection(Rc::new(RefCell::new(Some(
3102        mutable,
3103    )))))
3104}
3105
3106fn collection_to_persistent(value: &Value) -> Result<Value, String> {
3107    let Value::MutableCollection(collection) = value else {
3108        return Err("to-persistent expects a mutable collection".into());
3109    };
3110    let mut mutable = collection
3111        .borrow_mut()
3112        .take()
3113        .ok_or_else(|| "mutable collection used after to-persistent".to_string())?;
3114    Ok(match &mut mutable {
3115        MutableCollection::Map(values) => Value::Map(values.to_persistent()),
3116        MutableCollection::OrderedMap(values) => {
3117            Value::OrderedMap(Box::new(values.to_persistent()))
3118        }
3119        MutableCollection::SortedMap(values) => Value::SortedMap(Box::new(values.to_persistent())),
3120        MutableCollection::Trie(values) => Value::Trie(Box::new(values.to_persistent())),
3121        MutableCollection::Set(values) => Value::Set(values.to_persistent()),
3122        MutableCollection::OrderedSet(values) => {
3123            Value::OrderedSet(Box::new(values.to_persistent()))
3124        }
3125        MutableCollection::SortedSet(values) => Value::SortedSet(Box::new(values.to_persistent())),
3126        MutableCollection::List(values) => Value::List(values.to_persistent()),
3127        MutableCollection::Queue(values) => Value::Queue(Box::new(values.to_persistent())),
3128        MutableCollection::Vector(values) => Value::Vector(values.to_persistent()),
3129    })
3130}
3131
3132fn protocol_to_mutable(arguments: &[Value]) -> Result<Value, String> {
3133    match arguments {
3134        [Value::Extension(receiver)] => extension_protocol_call(
3135            receiver,
3136            "std.protocol.itomutable.IToMutable",
3137            "to-mutable",
3138            arguments,
3139        ),
3140        [value] => collection_to_mutable(value),
3141        _ => Err("IToMutable/to-mutable expects one value".into()),
3142    }
3143}
3144
3145fn protocol_to_persistent(arguments: &[Value]) -> Result<Value, String> {
3146    match arguments {
3147        [Value::Extension(receiver)] => extension_protocol_call(
3148            receiver,
3149            "std.protocol.itopersistent.IToPersistent",
3150            "to-persistent",
3151            arguments,
3152        ),
3153        [value] => collection_to_persistent(value),
3154        _ => Err("IToPersistent/to-persistent expects one value".into()),
3155    }
3156}
3157
3158impl PartialEq for Value {
3159    fn eq(&self, other: &Self) -> bool {
3160        if let Some(equal) = sequential_equality(self, other) {
3161            return equal;
3162        }
3163        if let Some(equal) = map_equality(self, other) {
3164            return equal;
3165        }
3166        if let Some(equal) = set_equality(self, other) {
3167            return equal;
3168        }
3169        if let Some(equal) = numeric::numeric_equal(self, other) {
3170            return equal;
3171        }
3172        match (self, other) {
3173            (Value::Number(a), Value::Number(b)) => a == b,
3174            (Value::Float(a), Value::Float(b)) => a.to_bits() == b.to_bits(),
3175            (Value::BigInteger(a), Value::BigInteger(b)) => a == b,
3176            (Value::Character(a), Value::Character(b)) => a == b,
3177            (Value::Regex(a), Value::Regex(b)) => a == b,
3178            (Value::Tagged(a), Value::Tagged(b)) => a == b,
3179            (Value::Bool(a), Value::Bool(b)) => a == b,
3180            (Value::String(a), Value::String(b)) => a == b,
3181            (Value::Keyword(a), Value::Keyword(b)) => a == b,
3182            (Value::Bytes(a), Value::Bytes(b)) => a == b,
3183            (Value::ByteBuffer(a), Value::ByteBuffer(b)) => *a.borrow() == *b.borrow(),
3184            (Value::Array(a), Value::Array(b)) => Rc::ptr_eq(a, b),
3185            (Value::Object(a), Value::Object(b)) => Rc::ptr_eq(a, b),
3186            (Value::Promise(a), Value::Promise(b)) => a.same_identity(b),
3187            (Value::Atom(a), Value::Atom(b)) => a.same_identity(b),
3188            (Value::Recur(a), Value::Recur(b)) => a == b,
3189            (Value::Map(a), Value::Map(b)) => a == b,
3190            (Value::Set(a), Value::Set(b)) => a == b,
3191            (Value::List(a), Value::List(b)) => a == b,
3192            (Value::Cons(a), Value::Cons(b)) => a == b,
3193            (Value::Symbol(a), Value::Symbol(b)) => a == b,
3194            (Value::Pointer(a), Value::Pointer(b)) => a == b,
3195            (Value::Function(a), Value::Function(b)) => Rc::ptr_eq(a, b),
3196            (Value::Tuple(a), Value::Tuple(b)) => a == b,
3197            (Value::Vector(a), Value::Vector(b)) => a == b,
3198            (Value::MapEntry(a), Value::MapEntry(b)) => a == b,
3199            (Value::MutableCollection(a), Value::MutableCollection(b)) => Rc::ptr_eq(a, b),
3200            (Value::Iterator(a), Value::Iterator(b)) => Rc::ptr_eq(a, b),
3201            (Value::Var(a), Value::Var(b)) => a.same_identity(b),
3202            (Value::Namespace(a), Value::Namespace(b)) => a.same_identity(b),
3203            (Value::Extension(a), Value::Extension(b)) => a == b,
3204            (Value::StructType(a), Value::StructType(b)) => Rc::ptr_eq(a, b),
3205            (Value::Struct(a), Value::Struct(b)) => {
3206                Rc::ptr_eq(&a.ty, &b.ty) && a.values == b.values
3207            }
3208            (Value::MutableType(a), Value::MutableType(b)) => Rc::ptr_eq(a, b),
3209            (Value::Mutable(a), Value::Mutable(b)) => a.same_identity(b),
3210            (Value::Protocol(a), Value::Protocol(b)) => Rc::ptr_eq(a, b),
3211            (Value::NativeType(a), Value::NativeType(b)) => a.name == b.name,
3212            (Value::Schema(a), Value::Schema(b)) => a.ast == b.ast,
3213            (Value::Coroutine(a), Value::Coroutine(b)) => Rc::ptr_eq(a, b),
3214            (Value::Stream(a), Value::Stream(b)) => Rc::ptr_eq(a, b),
3215            (Value::Result(a), Value::Result(b)) => a == b,
3216            (Value::ExceptionInfo(a), Value::ExceptionInfo(b)) => Rc::ptr_eq(a, b),
3217            (Value::Nil, Value::Nil) => true,
3218            _ => false,
3219        }
3220    }
3221}
3222
3223impl Eq for Value {}
3224impl PartialOrd for Value {
3225    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
3226        Some(self.cmp(other))
3227    }
3228}
3229impl Ord for Value {
3230    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
3231        if let Some(ordering) = numeric::numeric_total_compare(self, other) {
3232            return ordering;
3233        }
3234        if self == other {
3235            return std::cmp::Ordering::Equal;
3236        }
3237        match (self, other) {
3238            (Value::Number(left), Value::Number(right)) => return left.cmp(right),
3239            (Value::Float(left), Value::Float(right)) => return left.total_cmp(right),
3240            (Value::Character(left), Value::Character(right)) => return left.cmp(right),
3241            (Value::Bool(left), Value::Bool(right)) => return left.cmp(right),
3242            (Value::String(left), Value::String(right)) => return left.cmp(right),
3243            (Value::Keyword(left), Value::Keyword(right)) => return left.cmp(right),
3244            (Value::BigInteger(left), Value::BigInteger(right)) => return left.cmp(right),
3245            _ => {}
3246        }
3247        fn rank(value: &Value) -> u8 {
3248            match value {
3249                Value::Nil => 0,
3250                Value::Bool(_) => 1,
3251                Value::Number(_) => 2,
3252                Value::Float(_) => 3,
3253                Value::BigInteger(_) => 4,
3254                Value::Character(_) => 5,
3255                Value::String(_) => 7,
3256                Value::Keyword(_) => 8,
3257                Value::Symbol(_) => 9,
3258                Value::Pointer(_) => 9,
3259                Value::List(_)
3260                | Value::Cons(_)
3261                | Value::Queue(_)
3262                | Value::Deque(_)
3263                | Value::Tuple(_)
3264                | Value::Vector(_)
3265                | Value::MapEntry(_)
3266                | Value::Seq(_) => 10,
3267                Value::Map(_)
3268                | Value::OrderedMap(_)
3269                | Value::SortedMap(_)
3270                | Value::Trie(_)
3271                | Value::PriorityMap(_) => 11,
3272                Value::Set(_) | Value::OrderedSet(_) | Value::SortedSet(_) => 12,
3273                Value::Bytes(_) => 13,
3274                Value::ByteBuffer(_) => 14,
3275                Value::Regex(_) => 15,
3276                Value::Tagged(_) => 16,
3277                Value::Array(_) => 17,
3278                Value::Object(_) => 18,
3279                Value::Promise(_) => 19,
3280                Value::Atom(_) => 26,
3281                Value::Recur(_) => 20,
3282                Value::Function(_) => 21,
3283                Value::Iterator(_) => 22,
3284                Value::Var(_) => 23,
3285                Value::Namespace(_) => 24,
3286                Value::Extension(_) => 25,
3287                Value::StructType(_) => 27,
3288                Value::Struct(_) => 28,
3289                Value::MutableType(_) => 29,
3290                Value::Mutable(_) => 30,
3291                Value::Protocol(_) => 31,
3292                Value::NativeType(_) => 32,
3293                Value::Schema(_) => 33,
3294                Value::Coroutine(_) => 33,
3295                Value::Stream(_) => 34,
3296                Value::Result(_) => 36,
3297                Value::ExceptionInfo(_) => 37,
3298                Value::MutableCollection(_) => 38,
3299            }
3300        }
3301        rank(self)
3302            .cmp(&rank(other))
3303            .then_with(|| self.display().cmp(&other.display()))
3304            .then_with(|| self.stable_hash().cmp(&other.stable_hash()))
3305    }
3306}
3307impl Hash for Value {
3308    fn hash<H: Hasher>(&self, state: &mut H) {
3309        // CHAMP placement needs Java's scale-zero integral layout, while the
3310        // ordinary Hash contract must remain canonical across numeric types.
3311        if crate::lang::data::map::champ_placement_hashing() {
3312            if let Self::Number(value) = self {
3313                state.write_u64(crate::lang::hash::hash_long_placement(*value) as i64 as u64);
3314                return;
3315            }
3316            if let Self::Float(value) = self {
3317                if value.is_finite() && value.fract() == 0.0 {
3318                    if let Ok(integer) = (*value).to_string().parse::<i64>() {
3319                        state.write_u64(
3320                            crate::lang::hash::hash_long_placement(integer) as i64 as u64,
3321                        );
3322                        return;
3323                    }
3324                }
3325            }
3326        }
3327        if let Some(hash) = numeric::numeric_hash(self) {
3328            state.write_u64(hash as i64 as u64);
3329            return;
3330        }
3331        match self {
3332            Value::Bool(value) => state.write_u64(crate::lang::hash::hash_bool(*value) as u64),
3333            Value::Nil => state.write_u64(0),
3334            _ => state.write_u64(self.stable_hash()),
3335        }
3336    }
3337}
3338
3339impl crate::lang::hash::JavaHash for Value {
3340    /// The Java `long` hash of this value under `hash_type`, mirroring
3341    /// `G.hashFn(t).apply(o)`. See the `lang::hash` module docs for the
3342    /// parity rules and the documented deviations where Java hashes by
3343    /// object identity (keywords, pointers, SYSTEM/SIP collection hashes).
3344    fn java_hash(&self, hash_type: crate::lang::protocol::HashType) -> i64 {
3345        use crate::lang::hash as jh;
3346        use crate::lang::protocol::IHash;
3347
3348        // Opaque (non-parity) identity hash for runtime objects whose Java
3349        // counterparts hash by object identity. Follows the previous
3350        // `stable_hash` scheme.
3351        fn opaque(
3352            tag: u64,
3353            write: impl FnOnce(&mut std::collections::hash_map::DefaultHasher),
3354        ) -> i64 {
3355            let mut state = std::collections::hash_map::DefaultHasher::new();
3356            tag.hash(&mut state);
3357            write(&mut state);
3358            state.finish() as i64
3359        }
3360
3361        match self {
3362            Self::Nil => 0,
3363            Self::Bool(v) => jh::hash_bool(*v) as i64,
3364            Self::Character(v) => jh::hash_char(*v) as i64,
3365            Self::String(v) => jh::java_string_hash(v) as i64,
3366            Self::Number(value) => jh::hash_long(*value) as i64,
3367            Self::Float(value) => jh::hash_double(*value) as i64,
3368            Self::BigInteger(value) => jh::canonical_decimal_str_hash(&value.to_string()) as i64,
3369            // Java hashes java.util.regex.Pattern by identity; hash the
3370            // pattern string instead (deterministic deviation).
3371            Self::Regex(v) => jh::java_string_hash(v) as i64,
3372            Self::Keyword(v) => v.java_hash(hash_type),
3373            Self::Symbol(v) => v.java_hash(hash_type),
3374            Self::Pointer(v) => v.java_hash(hash_type),
3375            Self::Bytes(v) => jh::hash_bytes(v) as i64,
3376            Self::ByteBuffer(v) => jh::hash_bytes(v.borrow().as_slice()) as i64,
3377            // Java arrays hash by identity; composed deterministically here.
3378            Self::Array(v) => jh::compose_ordered(
3379                "SEQUENTIAL",
3380                v.borrow().iter().map(|item| item.java_hash(hash_type)),
3381            ),
3382            Self::Object(v) => jh::compose_unordered(
3383                "MAP",
3384                v.borrow().iter().map(|(key, item)| {
3385                    jh::compose_entry(jh::java_string_hash(key) as i64, item.java_hash(hash_type))
3386                }),
3387            ),
3388            Self::Recur(v) => {
3389                jh::compose_ordered("SEQUENTIAL", v.iter().map(|item| item.java_hash(hash_type)))
3390            }
3391            Self::Tagged(v) => jh::compose_ordered(
3392                "SEQUENTIAL",
3393                [v.tag().java_hash(hash_type), v.form().java_hash(hash_type)],
3394            ),
3395            Self::Map(v) => v.hash_calc(hash_type) as i64,
3396            Self::OrderedMap(v) => v.hash_calc(hash_type) as i64,
3397            Self::SortedMap(v) => v.hash_calc(hash_type) as i64,
3398            Self::PriorityMap(v) => v.hash_calc(hash_type) as i64,
3399            Self::Trie(v) => v.hash_calc(hash_type) as i64,
3400            Self::Set(v) => v.hash_calc(hash_type) as i64,
3401            Self::OrderedSet(v) => v.hash_calc(hash_type) as i64,
3402            Self::SortedSet(v) => v.hash_calc(hash_type) as i64,
3403            Self::List(v) => v.hash_calc(hash_type) as i64,
3404            Self::Cons(v) => v.hash_calc(hash_type) as i64,
3405            Self::Deque(v) => v.hash_calc(hash_type) as i64,
3406            Self::Queue(v) => v.hash_calc(hash_type) as i64,
3407            Self::Tuple(v) => v.hash_calc(hash_type) as i64,
3408            Self::Vector(v) => v.hash_calc(hash_type) as i64,
3409            Self::MapEntry(v) => v.hash_calc(hash_type) as i64,
3410            Self::Seq(v) => jh::compose_ordered(
3411                "SEQUENTIAL",
3412                v.iter().map(|item| match item {
3413                    Ok(value) => value.java_hash(hash_type),
3414                    Err(error) => jh::java_string_hash(&error) as i64,
3415                }),
3416            ),
3417            Self::MutableCollection(v) => opaque(32, |s| Rc::as_ptr(v).hash(s)),
3418            Self::Promise(v) => opaque(8, |s| v.identity_address().hash(s)),
3419            Self::Atom(v) => opaque(28, |s| v.identity_address().hash(s)),
3420            Self::Function(v) => opaque(14, |s| Rc::as_ptr(v).hash(s)),
3421            Self::Iterator(v) => opaque(16, |s| Rc::as_ptr(v).hash(s)),
3422            Self::Var(v) => opaque(17, |s| v.identity_address().hash(s)),
3423            Self::Namespace(v) => opaque(27, |s| v.identity_address().hash(s)),
3424            Self::Extension(v) => opaque(18, |s| {
3425                v.provider.hash(s);
3426                v.type_name.hash(s);
3427                v.handle.hash(s);
3428            }),
3429            Self::StructType(v) => opaque(26, |s| Rc::as_ptr(v).hash(s)),
3430            Self::Struct(v) => opaque(27, |s| {
3431                Rc::as_ptr(&v.ty).hash(s);
3432                for value in v.ordered_values() {
3433                    value.hash(s);
3434                }
3435            }),
3436            Self::MutableType(v) => opaque(28, |s| Rc::as_ptr(v).hash(s)),
3437            Self::Mutable(v) => opaque(29, |s| v.identity_address().hash(s)),
3438            Self::Protocol(v) => opaque(30, |s| v.name.hash(s)),
3439            Self::NativeType(v) => opaque(31, |s| v.name.hash(s)),
3440            Self::Schema(v) => opaque(34, |s| v.form.to_string().hash(s)),
3441            Self::Coroutine(v) => opaque(32, |s| Rc::as_ptr(v).hash(s)),
3442            Self::Stream(v) => opaque(35, |s| Rc::as_ptr(v).hash(s)),
3443            Self::Result(v) => v.java_hash(hash_type),
3444            Self::ExceptionInfo(v) => opaque(33, |s| Rc::as_ptr(v).hash(s)),
3445        }
3446    }
3447}
3448
3449impl Value {
3450    pub fn display(&self) -> String {
3451        match self {
3452            Self::Number(v) => v.to_string(),
3453            Self::Float(v) => {
3454                assert!(v.is_finite(), "non-finite number");
3455                format!("(double {v})")
3456            }
3457            Self::BigInteger(v) => v.to_string(),
3458            Self::Character('\n') => "\\newline".into(),
3459            Self::Character(' ') => "\\space".into(),
3460            Self::Character('\t') => "\\tab".into(),
3461            Self::Character('\u{0008}') => "\\backspace".into(),
3462            Self::Character('\u{000c}') => "\\formfeed".into(),
3463            Self::Character('\r') => "\\return".into(),
3464            Self::Character(v) if v.is_control() => format!("\\u{:04X}", *v as u32),
3465            Self::Character(v) => format!("\\{v}"),
3466            Self::Regex(v) => crate::kernel::form::display_regex(v),
3467            Self::Tagged(value) => uuid_text_from_tagged(value).map_or_else(
3468                || format!("#{}{}", value.tag().as_str(), value.form().display()),
3469                |text| format!("#{UUID_TAG} {}", Self::String(text.to_owned()).display()),
3470            ),
3471            Self::Bool(v) => v.to_string(),
3472            Self::String(v) => crate::kernel::form::display_string(v),
3473            Self::Keyword(v) => format!(":{}", v.as_str()),
3474            Self::Bytes(values) => format!(
3475                "#bytes[{}]",
3476                values
3477                    .iter()
3478                    .map(|v| (*v as i8).to_string())
3479                    .collect::<Vec<_>>()
3480                    .join(" ")
3481            ),
3482            Self::ByteBuffer(values) => {
3483                let body = values
3484                    .borrow()
3485                    .iter()
3486                    .map(|v| (*v as i8).to_string())
3487                    .collect::<Vec<_>>()
3488                    .join(" ");
3489                if body.is_empty() {
3490                    "(bytes)".into()
3491                } else {
3492                    format!("(bytes {body})")
3493                }
3494            }
3495            Self::Array(values) => format!(
3496                "#arr[{}]",
3497                values
3498                    .borrow()
3499                    .iter()
3500                    .map(Value::display)
3501                    .collect::<Vec<_>>()
3502                    .join(" ")
3503            ),
3504            Self::Object(values) => format!(
3505                "#obj{{{}}}",
3506                values
3507                    .borrow()
3508                    .iter()
3509                    .map(|(key, value)| format!(
3510                        "{} {}",
3511                        Value::String(key.clone()).display(),
3512                        value.display()
3513                    ))
3514                    .collect::<Vec<_>>()
3515                    .join(" ")
3516            ),
3517            Self::Promise(_) => "<promise>".into(),
3518            Self::Atom(value) => format!("#atom <{}>", value.deref_value().display()),
3519            Self::Recur(values) => format!(
3520                "<recur {}>",
3521                values
3522                    .iter()
3523                    .map(Value::display)
3524                    .collect::<Vec<_>>()
3525                    .join(" ")
3526            ),
3527            value @ (Self::Map(_)
3528            | Self::OrderedMap(_)
3529            | Self::SortedMap(_)
3530            | Self::PriorityMap(_)
3531            | Self::Trie(_)) => {
3532                format!(
3533                    "{{{}}}",
3534                    map_entries(value)
3535                        .unwrap()
3536                        .iter()
3537                        .map(|(k, v)| format!("{} {}", k.display(), v.display()))
3538                        .collect::<Vec<_>>()
3539                        .join(" ")
3540                )
3541            }
3542            value @ (Self::Set(_) | Self::OrderedSet(_) | Self::SortedSet(_)) => format!(
3543                "#{{{}}}",
3544                set_items(value)
3545                    .unwrap()
3546                    .iter()
3547                    .map(|item| item.display())
3548                    .collect::<Vec<_>>()
3549                    .join(" ")
3550            ),
3551            Self::Queue(values) => format!(
3552                "#queue[{}]",
3553                values
3554                    .iter()
3555                    .map(Value::display)
3556                    .collect::<Vec<_>>()
3557                    .join(" ")
3558            ),
3559            Self::Deque(values) => format!(
3560                "#deque[{}]",
3561                values
3562                    .iter()
3563                    .map(Value::display)
3564                    .collect::<Vec<_>>()
3565                    .join(" ")
3566            ),
3567            Self::Cons(values) => format!(
3568                "({})",
3569                values
3570                    .iter()
3571                    .map(|value| value.display())
3572                    .collect::<Vec<_>>()
3573                    .join(" ")
3574            ),
3575            Self::List(values) => format!(
3576                "({})",
3577                values
3578                    .iter()
3579                    .map(Value::display)
3580                    .collect::<Vec<_>>()
3581                    .join(" ")
3582            ),
3583            Self::Symbol(v) => v.as_str().to_owned(),
3584            Self::Pointer(v) => v.display(),
3585            Self::Function(_) => "<fn>".into(),
3586            Self::Tuple(values) => format!(
3587                "[{}]",
3588                values
3589                    .iter()
3590                    .map(Value::display)
3591                    .collect::<Vec<_>>()
3592                    .join(" ")
3593            ),
3594            Self::MapEntry(entry) => entry.display(),
3595            Self::Vector(values) => format!(
3596                "[{}]",
3597                values
3598                    .iter()
3599                    .map(Value::display)
3600                    .collect::<Vec<_>>()
3601                    .join(" ")
3602            ),
3603            Self::MutableCollection(values) => {
3604                let borrowed = values.borrow();
3605                let Some(values) = borrowed.as_ref() else {
3606                    return "#<mutable-frozen>".into();
3607                };
3608                let kind = match values {
3609                    MutableCollection::Map(_) => "map",
3610                    MutableCollection::OrderedMap(_) => "ordered-map",
3611                    MutableCollection::SortedMap(_) => "sorted-map",
3612                    MutableCollection::Trie(_) => "trie",
3613                    MutableCollection::Set(_) => "set",
3614                    MutableCollection::OrderedSet(_) => "ordered-set",
3615                    MutableCollection::SortedSet(_) => "sorted-set",
3616                    MutableCollection::List(_) => "list",
3617                    MutableCollection::Queue(_) => "queue",
3618                    MutableCollection::Vector(_) => "vector",
3619                };
3620                format!("#<mutable-{kind}>")
3621            }
3622            Self::Seq(sequence) => {
3623                let mut values = sequence.iter();
3624                let mut displayed = Vec::new();
3625                for _ in 0..10 {
3626                    match values.next() {
3627                        Some(Ok(value)) => displayed.push(value.display()),
3628                        Some(Err(error)) => {
3629                            displayed.push(format!("#error[{}]", Value::String(error).display()));
3630                            break;
3631                        }
3632                        None => break,
3633                    }
3634                }
3635                if values.next().is_some() {
3636                    displayed.push("...".into());
3637                }
3638                format!("({})", displayed.join(" "))
3639            }
3640            Self::Iterator(_) => "<iterator>".into(),
3641            Self::Var(value) => value.display(),
3642            Self::Namespace(value) => format!("#namespace[{}]", value.name().as_str()),
3643            Self::Extension(value) => format!("#ht[:handle {}]", value.handle),
3644            Self::StructType(value) => value.name.clone(),
3645            Self::Struct(value) => format!(
3646                "#{}{{{}}}",
3647                value.ty.name,
3648                value
3649                    .ty
3650                    .fields
3651                    .iter()
3652                    .filter_map(|field| value.get(field).map(|value| (field, value)))
3653                    .map(|(field, value)| format!(":{field} {}", value.display()))
3654                    .collect::<Vec<_>>()
3655                    .join(" ")
3656            ),
3657            Self::MutableType(value) => value.name.clone(),
3658            Self::Mutable(value) => format!(
3659                "#{}{{{}}}",
3660                value.ty.name,
3661                value
3662                    .ty
3663                    .fields
3664                    .iter()
3665                    .zip(value.ordered_values())
3666                    .map(|(field, value)| format!(":{field} {}", value.display()))
3667                    .collect::<Vec<_>>()
3668                    .join(" ")
3669            ),
3670            Self::Protocol(value) => format!("#protocol[{}]", value.name),
3671            Self::NativeType(value) => format!("#<native-type {}>", value.name),
3672            Self::Schema(value) => format!("(schema {})", value.form),
3673            Self::Coroutine(value) => {
3674                let status = match &*value.state.borrow() {
3675                    CoroutineState::New(_) | CoroutineState::Suspended(_) => "suspended",
3676                    CoroutineState::Running => "running",
3677                    CoroutineState::Dead => "dead",
3678                };
3679                format!("#<coroutine {status}>")
3680            }
3681            Self::Stream(value) => format!(
3682                "#<stream {}>",
3683                if value.closed.get() {
3684                    "closed"
3685                } else {
3686                    "ready"
3687                }
3688            ),
3689            Self::Result(value) => value.display(),
3690            Self::ExceptionInfo(value) => {
3691                format!(
3692                    "#ex[{} {}]",
3693                    Self::String(value.message.clone()).display(),
3694                    value.data.display()
3695                )
3696            }
3697            Self::Nil => "nil".into(),
3698        }
3699    }
3700    pub(crate) fn truthy(&self) -> bool {
3701        !matches!(self, Self::Nil | Self::Bool(false))
3702    }
3703
3704    /// Stable structural hash used by protocol and collection conformance tests.
3705    ///
3706    /// This is the Java-parity RAPID hash: the bit pattern (as `u64`) of the
3707    /// Java `long` produced by `G.hashRapid` / `hashCalc(RAPID)` on the
3708    /// equivalent Java value. Value-level hashes are Java `int` results
3709    /// sign-extended to 64 bits, matching `G.hashValue` returning `long`.
3710    /// Opaque runtime objects (functions, atoms, promises, …) keep the
3711    /// previous identity-based `DefaultHasher` scheme — their Java
3712    /// counterparts hash by object identity, so no parity exists there.
3713    pub fn stable_hash(&self) -> u64 {
3714        self.java_hash(crate::lang::hash::DEFAULT_HASH) as u64
3715    }
3716}