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