1#![allow(unused)]
4
5use std::collections::HashMap;
6use std::mem;
7use std::sync::{Arc, Condvar, Mutex};
8
9use cljrs_gc::GcPtr;
10use cljrs_reader::Form;
11
12use crate::Value;
13
14pub type MethodMap = HashMap<Arc<str>, Value>;
18
19#[derive(Debug)]
21pub struct Protocol {
22 pub name: Arc<str>,
23 pub ns: Arc<str>,
24 pub methods: Vec<ProtocolMethod>,
25 pub impls: Mutex<HashMap<Arc<str>, MethodMap>>,
27}
28
29impl Protocol {
30 pub fn new(name: Arc<str>, ns: Arc<str>, methods: Vec<ProtocolMethod>) -> Self {
31 Self {
32 name,
33 ns,
34 methods,
35 impls: Mutex::new(HashMap::new()),
36 }
37 }
38}
39
40impl cljrs_gc::Trace for Protocol {
41 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
42 {
43 let impls = self.impls.lock().unwrap();
44 for method_map in impls.values() {
45 for v in method_map.values() {
46 v.trace(visitor);
47 }
48 }
49 }
50 }
51}
52
53#[derive(Debug, Clone)]
55pub struct ProtocolMethod {
56 pub name: Arc<str>,
57 pub min_arity: usize,
58 pub variadic: bool,
59}
60
61impl cljrs_gc::Trace for ProtocolMethod {
62 fn trace(&self, _: &mut cljrs_gc::MarkVisitor) {}
63}
64
65#[derive(Debug)]
69pub struct ProtocolFn {
70 pub protocol: GcPtr<Protocol>,
71 pub method_name: Arc<str>,
72 pub min_arity: usize,
73 pub variadic: bool,
74}
75
76impl cljrs_gc::Trace for ProtocolFn {
77 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
78 use cljrs_gc::GcVisitor as _;
79 visitor.visit(&self.protocol);
80 }
81}
82
83#[derive(Debug)]
87pub struct MultiFn {
88 pub name: Arc<str>,
89 pub dispatch_fn: Value,
90 pub methods: Mutex<HashMap<String, Value>>,
92 pub prefers: Mutex<HashMap<String, Vec<String>>>,
94 pub default_dispatch: String,
96}
97
98impl MultiFn {
99 pub fn new(name: Arc<str>, dispatch_fn: Value, default_dispatch: String) -> Self {
100 Self {
101 name,
102 dispatch_fn,
103 methods: Mutex::new(HashMap::new()),
104 prefers: Mutex::new(HashMap::new()),
105 default_dispatch,
106 }
107 }
108}
109
110impl cljrs_gc::Trace for MultiFn {
111 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
112 self.dispatch_fn.trace(visitor);
113 {
114 let methods = self.methods.lock().unwrap();
115 for v in methods.values() {
116 v.trace(visitor);
117 }
118 }
119 }
120}
121
122#[derive(Debug)]
126pub struct Var {
127 pub namespace: Arc<str>,
128 pub name: Arc<str>,
129 pub value: Mutex<Option<Value>>,
130 pub is_macro: bool,
131 pub meta: Mutex<Option<Value>>,
133 pub watches: Mutex<Vec<(Value, Value)>>,
134}
135
136impl Var {
137 pub fn new(namespace: impl Into<Arc<str>>, name: impl Into<Arc<str>>) -> Self {
138 Self {
139 namespace: namespace.into(),
140 name: name.into(),
141 value: Mutex::new(None),
142 is_macro: false,
143 meta: Mutex::new(None),
144 watches: Mutex::new(Vec::new()),
145 }
146 }
147
148 pub fn is_bound(&self) -> bool {
149 self.value.lock().unwrap().is_some()
150 }
151
152 pub fn deref(&self) -> Option<Value> {
153 self.value.lock().unwrap().clone()
154 }
155
156 pub fn bind(&self, v: Value) {
157 *self.value.lock().unwrap() = Some(v);
158 }
159
160 pub fn get_meta(&self) -> Option<Value> {
161 self.meta.lock().unwrap().clone()
162 }
163
164 pub fn set_meta(&self, m: Value) {
165 *self.meta.lock().unwrap() = Some(m);
166 }
167
168 pub fn full_name(&self) -> String {
169 format!("{}/{}", self.namespace, self.name)
170 }
171}
172
173impl cljrs_gc::Trace for Var {
174 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
175 {
176 let value = self.value.lock().unwrap();
177 if let Some(v) = value.as_ref() {
178 v.trace(visitor);
179 }
180 }
181 {
182 let meta = self.meta.lock().unwrap();
183 if let Some(m) = meta.as_ref() {
184 m.trace(visitor);
185 }
186 }
187 {
188 let watches = self.watches.lock().unwrap();
189 for (key, f) in watches.iter() {
190 key.trace(visitor);
191 f.trace(visitor);
192 }
193 }
194 }
195}
196
197#[derive(Debug)]
201pub struct Atom {
202 pub value: Mutex<Value>,
203 pub meta: Mutex<Option<Value>>,
204 pub validator: Mutex<Option<Value>>,
205 pub watches: Mutex<Vec<(Value, Value)>>,
206}
207
208impl Atom {
209 pub fn new(v: Value) -> Self {
210 Self {
211 value: Mutex::new(v),
212 meta: Mutex::new(None),
213 validator: Mutex::new(None),
214 watches: Mutex::new(Vec::new()),
215 }
216 }
217
218 pub fn deref(&self) -> Value {
219 self.value.lock().unwrap().clone()
220 }
221
222 pub fn reset(&self, v: Value) -> Value {
223 let mut guard = self.value.lock().unwrap();
224 *guard = v.clone();
225 v
226 }
227
228 pub fn get_meta(&self) -> Option<Value> {
229 self.meta.lock().unwrap().clone()
230 }
231
232 pub fn set_meta(&self, m: Option<Value>) {
233 *self.meta.lock().unwrap() = m;
234 }
235
236 pub fn get_validator(&self) -> Option<Value> {
237 self.validator.lock().unwrap().clone()
238 }
239
240 pub fn set_validator(&self, vf: Option<Value>) {
241 *self.validator.lock().unwrap() = vf;
242 }
243}
244
245impl cljrs_gc::Trace for Atom {
246 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
247 {
248 let value = self.value.lock().unwrap();
249 value.trace(visitor);
250 }
251 {
252 let meta = self.meta.lock().unwrap();
253 if let Some(m) = meta.as_ref() {
254 m.trace(visitor);
255 }
256 }
257 {
258 let validator = self.validator.lock().unwrap();
259 if let Some(vf) = validator.as_ref() {
260 vf.trace(visitor);
261 }
262 }
263 {
264 let watches = self.watches.lock().unwrap();
265 for (key, f) in watches.iter() {
266 key.trace(visitor);
267 f.trace(visitor);
268 }
269 }
270 }
271}
272
273#[derive(Debug)]
277pub struct Namespace {
278 pub name: Arc<str>,
279 pub interns: Mutex<HashMap<Arc<str>, GcPtr<Var>>>,
281 pub refers: Mutex<HashMap<Arc<str>, GcPtr<Var>>>,
283 pub aliases: Mutex<HashMap<Arc<str>, Arc<str>>>,
285}
286
287impl Namespace {
288 pub fn new(name: impl Into<Arc<str>>) -> Self {
289 Self {
290 name: name.into(),
291 interns: Mutex::new(HashMap::new()),
292 refers: Mutex::new(HashMap::new()),
293 aliases: Mutex::new(HashMap::new()),
294 }
295 }
296}
297
298impl cljrs_gc::Trace for Namespace {
299 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
300 use cljrs_gc::GcVisitor as _;
301 {
302 let interns = self.interns.lock().unwrap();
303 for var in interns.values() {
304 visitor.visit(var);
305 }
306 }
307 {
308 let refers = self.refers.lock().unwrap();
309 for var in refers.values() {
310 visitor.visit(var);
311 }
312 }
313 }
314}
315
316pub type NativeFnPtr = fn(&[Value]) -> crate::error::ValueResult<Value>;
322
323pub type NativeFnFunc = Arc<dyn Fn(&[Value]) -> crate::error::ValueResult<Value> + Send + Sync>;
326
327#[derive(Clone, Debug)]
328pub enum Arity {
329 Fixed(usize),
330 Variadic { min: usize },
331}
332
333pub struct NativeFn {
334 pub name: Arc<str>,
335 pub arity: Arity,
336 pub func: NativeFnFunc,
337}
338
339impl NativeFn {
340 pub fn new(name: impl Into<Arc<str>>, arity: Arity, func: NativeFnPtr) -> Self {
342 Self {
343 name: name.into(),
344 arity,
345 func: Arc::new(func),
346 }
347 }
348
349 pub fn with_closure(
351 name: impl Into<Arc<str>>,
352 arity: Arity,
353 func: impl Fn(&[Value]) -> crate::error::ValueResult<Value> + Send + Sync + 'static,
354 ) -> Self {
355 Self {
356 name: name.into(),
357 arity,
358 func: Arc::new(func),
359 }
360 }
361}
362
363impl std::fmt::Debug for NativeFn {
364 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
365 f.debug_struct("NativeFn")
366 .field("name", &self.name)
367 .field("arity", &self.arity)
368 .field("func", &"<fn>")
369 .finish()
370 }
371}
372
373impl cljrs_gc::Trace for NativeFn {
374 fn trace(&self, _: &mut cljrs_gc::MarkVisitor) {}
375}
376
377#[derive(Debug, Clone)]
381pub struct CljxFnArity {
382 pub params: Vec<Arc<str>>,
385 pub rest_param: Option<Arc<str>>,
387 pub body: Vec<Form>,
389 pub destructure_params: Vec<(usize, Form)>,
393 pub destructure_rest: Option<Form>,
395 pub ir_arity_id: u64,
397}
398
399#[derive(Debug, Clone)]
403pub struct CljxFn {
404 pub name: Option<Arc<str>>,
405 pub arities: Vec<CljxFnArity>,
406 pub closed_over_names: Vec<Arc<str>>,
408 pub closed_over_vals: Vec<Value>,
410 pub is_macro: bool,
412 pub defining_ns: Arc<str>,
414}
415
416impl CljxFn {
417 pub fn new(
418 name: Option<Arc<str>>,
419 arities: Vec<CljxFnArity>,
420 closed_over_names: Vec<Arc<str>>,
421 closed_over_vals: Vec<Value>,
422 is_macro: bool,
423 defining_ns: Arc<str>,
424 ) -> Self {
425 Self {
426 name,
427 arities,
428 closed_over_names,
429 closed_over_vals,
430 is_macro,
431 defining_ns,
432 }
433 }
434}
435
436impl cljrs_gc::Trace for CljxFn {
437 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
438 for v in &self.closed_over_vals {
439 v.trace(visitor);
440 }
441 }
442}
443
444#[derive(Debug)]
451pub struct BoundFn {
452 pub wrapped: Value,
454 pub captured_bindings: HashMap<usize, Value>,
456}
457
458impl cljrs_gc::Trace for BoundFn {
459 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
460 self.wrapped.trace(visitor);
461 for val in self.captured_bindings.values() {
462 val.trace(visitor);
463 }
464 }
465}
466
467pub trait Thunk: Send + Sync + std::fmt::Debug + cljrs_gc::Trace {
471 fn force(&self) -> Result<Value, String>;
472}
473
474pub enum LazySeqState {
476 Pending(Box<dyn Thunk>),
478 Forced(Value),
480 Error(String),
482}
483
484pub struct LazySeq {
486 pub state: Mutex<LazySeqState>,
487}
488
489impl LazySeq {
490 pub fn new(thunk: Box<dyn Thunk>) -> Self {
491 Self {
492 state: Mutex::new(LazySeqState::Pending(thunk)),
493 }
494 }
495
496 pub fn realize(&self) -> Value {
499 let thunk = {
500 let mut guard = self.state.lock().unwrap();
501 match &*guard {
502 LazySeqState::Forced(v) => return v.clone(),
503 LazySeqState::Error(_) => return Value::Nil,
504 LazySeqState::Pending(_) => {}
505 }
506 let prev = mem::replace(&mut *guard, LazySeqState::Forced(Value::Nil));
508 let LazySeqState::Pending(thunk) = prev else {
509 unreachable!("state was not Pending")
510 };
511 thunk
512 };
514 match thunk.force() {
517 Ok(result) => {
518 *self.state.lock().unwrap() = LazySeqState::Forced(result.clone());
519 result
520 }
521 Err(msg) => {
522 *self.state.lock().unwrap() = LazySeqState::Error(msg);
523 Value::Nil
524 }
525 }
526 }
527
528 pub fn error(&self) -> Option<String> {
530 let guard = self.state.lock().unwrap();
531 if let LazySeqState::Error(e) = &*guard {
532 Some(e.clone())
533 } else {
534 None
535 }
536 }
537}
538
539impl std::fmt::Debug for LazySeq {
540 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
541 write!(f, "LazySeq(...)")
542 }
543}
544
545impl cljrs_gc::Trace for LazySeq {
546 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
547 {
550 let state = self.state.lock().unwrap();
551 match &*state {
552 LazySeqState::Pending(thunk) => thunk.trace(visitor),
553 LazySeqState::Forced(v) => v.trace(visitor),
554 LazySeqState::Error(_) => {}
555 }
556 }
557 }
558}
559
560#[derive(Debug, Clone)]
567pub struct CljxCons {
568 pub head: Value,
569 pub tail: Value,
570}
571
572impl cljrs_gc::Trace for CljxCons {
573 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
574 self.head.trace(visitor);
575 self.tail.trace(visitor);
576 }
577}
578
579pub struct Volatile {
583 pub value: Mutex<Value>,
584}
585
586impl Volatile {
587 pub fn new(v: Value) -> Self {
588 Self {
589 value: Mutex::new(v),
590 }
591 }
592
593 pub fn deref(&self) -> Value {
594 self.value.lock().unwrap().clone()
595 }
596
597 pub fn reset(&self, v: Value) -> Value {
598 *self.value.lock().unwrap() = v.clone();
599 v
600 }
601}
602
603impl std::fmt::Debug for Volatile {
604 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
605 write!(f, "Volatile")
606 }
607}
608
609impl cljrs_gc::Trace for Volatile {
610 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
611 {
612 let value = self.value.lock().unwrap();
613 value.trace(visitor);
614 }
615 }
616}
617
618pub enum DelayState {
622 Pending(Box<dyn Thunk>),
623 Forced(Value),
624}
625
626pub struct Delay {
628 pub state: Mutex<DelayState>,
629}
630
631impl Delay {
632 pub fn new(thunk: Box<dyn Thunk>) -> Self {
633 Self {
634 state: Mutex::new(DelayState::Pending(thunk)),
635 }
636 }
637
638 pub fn force(&self) -> Result<Value, String> {
641 let thunk = {
642 let mut guard = self.state.lock().unwrap();
643 if let DelayState::Forced(v) = &*guard {
644 return Ok(v.clone());
645 }
646 let prev = mem::replace(&mut *guard, DelayState::Forced(Value::Nil));
647 let DelayState::Pending(thunk) = prev else {
648 unreachable!("state was not Pending")
649 };
650 thunk
651 };
653 let result = thunk.force()?;
656 *self.state.lock().unwrap() = DelayState::Forced(result.clone());
657 Ok(result)
658 }
659
660 pub fn is_realized(&self) -> bool {
662 matches!(&*self.state.lock().unwrap(), DelayState::Forced(_))
663 }
664}
665
666impl std::fmt::Debug for Delay {
667 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
668 write!(f, "Delay")
669 }
670}
671
672impl cljrs_gc::Trace for Delay {
673 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
674 {
677 let state = self.state.lock().unwrap();
678 match &*state {
679 DelayState::Pending(thunk) => thunk.trace(visitor),
680 DelayState::Forced(v) => v.trace(visitor),
681 }
682 }
683 }
684}
685
686pub struct CljxPromise {
690 pub value: Mutex<Option<Value>>,
691 pub cond: Condvar,
692}
693
694impl CljxPromise {
695 pub fn new() -> Self {
696 Self {
697 value: Mutex::new(None),
698 cond: Condvar::new(),
699 }
700 }
701
702 pub fn deliver(&self, v: Value) {
704 let mut guard = self.value.lock().unwrap();
705 if guard.is_none() {
706 *guard = Some(v);
707 self.cond.notify_all();
708 }
709 }
710
711 pub fn deref_blocking(&self) -> Value {
713 let mut guard = self.value.lock().unwrap();
714 while guard.is_none() {
715 guard = self.cond.wait(guard).unwrap();
716 }
717 guard.as_ref().unwrap().clone()
718 }
719
720 pub fn is_realized(&self) -> bool {
722 self.value.lock().unwrap().is_some()
723 }
724}
725
726impl Default for CljxPromise {
727 fn default() -> Self {
728 Self::new()
729 }
730}
731
732impl std::fmt::Debug for CljxPromise {
733 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
734 write!(f, "Promise")
735 }
736}
737
738impl cljrs_gc::Trace for CljxPromise {
739 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
740 {
741 let value = self.value.lock().unwrap();
742 if let Some(v) = value.as_ref() {
743 v.trace(visitor);
744 }
745 }
746 }
747}
748
749pub enum FutureState {
753 Running,
754 Done(Value),
755 Failed(String),
756 Cancelled,
757}
758
759pub struct CljxFuture {
761 pub state: Mutex<FutureState>,
762 pub cond: Condvar,
763}
764
765impl CljxFuture {
766 pub fn new() -> Self {
767 Self {
768 state: Mutex::new(FutureState::Running),
769 cond: Condvar::new(),
770 }
771 }
772
773 pub fn is_done(&self) -> bool {
775 !matches!(&*self.state.lock().unwrap(), FutureState::Running)
776 }
777
778 pub fn is_cancelled(&self) -> bool {
780 matches!(&*self.state.lock().unwrap(), FutureState::Cancelled)
781 }
782}
783
784impl Default for CljxFuture {
785 fn default() -> Self {
786 Self::new()
787 }
788}
789
790impl std::fmt::Debug for CljxFuture {
791 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
792 write!(f, "Future")
793 }
794}
795
796impl cljrs_gc::Trace for CljxFuture {
797 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
798 {
799 let state = self.state.lock().unwrap();
800 if let FutureState::Done(v) = &*state {
801 v.trace(visitor);
802 }
803 }
804 }
805}
806
807pub type AgentFn = Box<dyn FnOnce(Value) -> Result<Value, Value> + Send>;
811
812pub enum AgentMsg {
814 Update(AgentFn),
815 Shutdown,
816}
817
818pub struct Agent {
820 pub state: Arc<Mutex<Value>>,
822 pub error: Arc<Mutex<Option<Value>>>,
824 pub sender: Mutex<std::sync::mpsc::SyncSender<AgentMsg>>,
826 pub watches: Mutex<Vec<(Value, Value)>>,
827}
828
829impl Agent {
830 pub fn get_state(&self) -> Value {
831 self.state.lock().unwrap().clone()
832 }
833
834 pub fn get_error(&self) -> Option<Value> {
835 self.error.lock().unwrap().clone()
836 }
837
838 pub fn clear_error(&self) {
839 *self.error.lock().unwrap() = None;
840 }
841}
842
843impl std::fmt::Debug for Agent {
844 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
845 write!(f, "Agent")
846 }
847}
848
849impl cljrs_gc::Trace for Agent {
850 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
851 {
852 let state = self.state.lock().unwrap();
853 state.trace(visitor);
854 }
855 {
856 let error = self.error.lock().unwrap();
857 if let Some(e) = error.as_ref() {
858 e.trace(visitor);
859 }
860 }
861 {
862 let watches = self.watches.lock().unwrap();
863 for (key, f) in watches.iter() {
864 key.trace(visitor);
865 f.trace(visitor);
866 }
867 }
868 }
869}