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}
396
397#[derive(Debug, Clone)]
401pub struct CljxFn {
402 pub name: Option<Arc<str>>,
403 pub arities: Vec<CljxFnArity>,
404 pub closed_over_names: Vec<Arc<str>>,
406 pub closed_over_vals: Vec<Value>,
408 pub is_macro: bool,
410 pub defining_ns: Arc<str>,
412}
413
414impl CljxFn {
415 pub fn new(
416 name: Option<Arc<str>>,
417 arities: Vec<CljxFnArity>,
418 closed_over_names: Vec<Arc<str>>,
419 closed_over_vals: Vec<Value>,
420 is_macro: bool,
421 defining_ns: Arc<str>,
422 ) -> Self {
423 Self {
424 name,
425 arities,
426 closed_over_names,
427 closed_over_vals,
428 is_macro,
429 defining_ns,
430 }
431 }
432}
433
434impl cljrs_gc::Trace for CljxFn {
435 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
436 for v in &self.closed_over_vals {
437 v.trace(visitor);
438 }
439 }
440}
441
442#[derive(Debug)]
449pub struct BoundFn {
450 pub wrapped: Value,
452 pub captured_bindings: HashMap<usize, Value>,
454}
455
456impl cljrs_gc::Trace for BoundFn {
457 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
458 self.wrapped.trace(visitor);
459 for val in self.captured_bindings.values() {
460 val.trace(visitor);
461 }
462 }
463}
464
465pub trait Thunk: Send + Sync + std::fmt::Debug + cljrs_gc::Trace {
469 fn force(&self) -> Result<Value, String>;
470}
471
472pub enum LazySeqState {
474 Pending(Box<dyn Thunk>),
476 Forced(Value),
478 Error(String),
480}
481
482pub struct LazySeq {
484 pub state: Mutex<LazySeqState>,
485}
486
487impl LazySeq {
488 pub fn new(thunk: Box<dyn Thunk>) -> Self {
489 Self {
490 state: Mutex::new(LazySeqState::Pending(thunk)),
491 }
492 }
493
494 pub fn realize(&self) -> Value {
497 let thunk = {
498 let mut guard = self.state.lock().unwrap();
499 match &*guard {
500 LazySeqState::Forced(v) => return v.clone(),
501 LazySeqState::Error(_) => return Value::Nil,
502 LazySeqState::Pending(_) => {}
503 }
504 let prev = mem::replace(&mut *guard, LazySeqState::Forced(Value::Nil));
506 let LazySeqState::Pending(thunk) = prev else {
507 unreachable!("state was not Pending")
508 };
509 thunk
510 };
512 match thunk.force() {
515 Ok(result) => {
516 *self.state.lock().unwrap() = LazySeqState::Forced(result.clone());
517 result
518 }
519 Err(msg) => {
520 *self.state.lock().unwrap() = LazySeqState::Error(msg);
521 Value::Nil
522 }
523 }
524 }
525
526 pub fn error(&self) -> Option<String> {
528 let guard = self.state.lock().unwrap();
529 if let LazySeqState::Error(e) = &*guard {
530 Some(e.clone())
531 } else {
532 None
533 }
534 }
535}
536
537impl std::fmt::Debug for LazySeq {
538 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
539 write!(f, "LazySeq(...)")
540 }
541}
542
543impl cljrs_gc::Trace for LazySeq {
544 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
545 {
548 let state = self.state.lock().unwrap();
549 match &*state {
550 LazySeqState::Pending(thunk) => thunk.trace(visitor),
551 LazySeqState::Forced(v) => v.trace(visitor),
552 LazySeqState::Error(_) => {}
553 }
554 }
555 }
556}
557
558#[derive(Debug, Clone)]
565pub struct CljxCons {
566 pub head: Value,
567 pub tail: Value,
568}
569
570impl cljrs_gc::Trace for CljxCons {
571 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
572 self.head.trace(visitor);
573 self.tail.trace(visitor);
574 }
575}
576
577pub struct Volatile {
581 pub value: Mutex<Value>,
582}
583
584impl Volatile {
585 pub fn new(v: Value) -> Self {
586 Self {
587 value: Mutex::new(v),
588 }
589 }
590
591 pub fn deref(&self) -> Value {
592 self.value.lock().unwrap().clone()
593 }
594
595 pub fn reset(&self, v: Value) -> Value {
596 *self.value.lock().unwrap() = v.clone();
597 v
598 }
599}
600
601impl std::fmt::Debug for Volatile {
602 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
603 write!(f, "Volatile")
604 }
605}
606
607impl cljrs_gc::Trace for Volatile {
608 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
609 {
610 let value = self.value.lock().unwrap();
611 value.trace(visitor);
612 }
613 }
614}
615
616pub enum DelayState {
620 Pending(Box<dyn Thunk>),
621 Forced(Value),
622}
623
624pub struct Delay {
626 pub state: Mutex<DelayState>,
627}
628
629impl Delay {
630 pub fn new(thunk: Box<dyn Thunk>) -> Self {
631 Self {
632 state: Mutex::new(DelayState::Pending(thunk)),
633 }
634 }
635
636 pub fn force(&self) -> Result<Value, String> {
639 let thunk = {
640 let mut guard = self.state.lock().unwrap();
641 if let DelayState::Forced(v) = &*guard {
642 return Ok(v.clone());
643 }
644 let prev = mem::replace(&mut *guard, DelayState::Forced(Value::Nil));
645 let DelayState::Pending(thunk) = prev else {
646 unreachable!("state was not Pending")
647 };
648 thunk
649 };
651 let result = thunk.force()?;
654 *self.state.lock().unwrap() = DelayState::Forced(result.clone());
655 Ok(result)
656 }
657
658 pub fn is_realized(&self) -> bool {
660 matches!(&*self.state.lock().unwrap(), DelayState::Forced(_))
661 }
662}
663
664impl std::fmt::Debug for Delay {
665 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
666 write!(f, "Delay")
667 }
668}
669
670impl cljrs_gc::Trace for Delay {
671 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
672 {
675 let state = self.state.lock().unwrap();
676 match &*state {
677 DelayState::Pending(thunk) => thunk.trace(visitor),
678 DelayState::Forced(v) => v.trace(visitor),
679 }
680 }
681 }
682}
683
684pub struct CljxPromise {
688 pub value: Mutex<Option<Value>>,
689 pub cond: Condvar,
690}
691
692impl CljxPromise {
693 pub fn new() -> Self {
694 Self {
695 value: Mutex::new(None),
696 cond: Condvar::new(),
697 }
698 }
699
700 pub fn deliver(&self, v: Value) {
702 let mut guard = self.value.lock().unwrap();
703 if guard.is_none() {
704 *guard = Some(v);
705 self.cond.notify_all();
706 }
707 }
708
709 pub fn deref_blocking(&self) -> Value {
711 let mut guard = self.value.lock().unwrap();
712 while guard.is_none() {
713 guard = self.cond.wait(guard).unwrap();
714 }
715 guard.as_ref().unwrap().clone()
716 }
717
718 pub fn is_realized(&self) -> bool {
720 self.value.lock().unwrap().is_some()
721 }
722}
723
724impl Default for CljxPromise {
725 fn default() -> Self {
726 Self::new()
727 }
728}
729
730impl std::fmt::Debug for CljxPromise {
731 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
732 write!(f, "Promise")
733 }
734}
735
736impl cljrs_gc::Trace for CljxPromise {
737 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
738 {
739 let value = self.value.lock().unwrap();
740 if let Some(v) = value.as_ref() {
741 v.trace(visitor);
742 }
743 }
744 }
745}
746
747pub enum FutureState {
751 Running,
752 Done(Value),
753 Failed(String),
754 Cancelled,
755}
756
757pub struct CljxFuture {
759 pub state: Mutex<FutureState>,
760 pub cond: Condvar,
761}
762
763impl CljxFuture {
764 pub fn new() -> Self {
765 Self {
766 state: Mutex::new(FutureState::Running),
767 cond: Condvar::new(),
768 }
769 }
770
771 pub fn is_done(&self) -> bool {
773 !matches!(&*self.state.lock().unwrap(), FutureState::Running)
774 }
775
776 pub fn is_cancelled(&self) -> bool {
778 matches!(&*self.state.lock().unwrap(), FutureState::Cancelled)
779 }
780}
781
782impl Default for CljxFuture {
783 fn default() -> Self {
784 Self::new()
785 }
786}
787
788impl std::fmt::Debug for CljxFuture {
789 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
790 write!(f, "Future")
791 }
792}
793
794impl cljrs_gc::Trace for CljxFuture {
795 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
796 {
797 let state = self.state.lock().unwrap();
798 if let FutureState::Done(v) = &*state {
799 v.trace(visitor);
800 }
801 }
802 }
803}
804
805pub type AgentFn = Box<dyn FnOnce(Value) -> Result<Value, Value> + Send>;
809
810pub enum AgentMsg {
812 Update(AgentFn),
813 Shutdown,
814}
815
816pub struct Agent {
818 pub state: Arc<Mutex<Value>>,
820 pub error: Arc<Mutex<Option<Value>>>,
822 pub sender: Mutex<std::sync::mpsc::SyncSender<AgentMsg>>,
824 pub watches: Mutex<Vec<(Value, Value)>>,
825}
826
827impl Agent {
828 pub fn get_state(&self) -> Value {
829 self.state.lock().unwrap().clone()
830 }
831
832 pub fn get_error(&self) -> Option<Value> {
833 self.error.lock().unwrap().clone()
834 }
835
836 pub fn clear_error(&self) {
837 *self.error.lock().unwrap() = None;
838 }
839}
840
841impl std::fmt::Debug for Agent {
842 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
843 write!(f, "Agent")
844 }
845}
846
847impl cljrs_gc::Trace for Agent {
848 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
849 {
850 let state = self.state.lock().unwrap();
851 state.trace(visitor);
852 }
853 {
854 let error = self.error.lock().unwrap();
855 if let Some(e) = error.as_ref() {
856 e.trace(visitor);
857 }
858 }
859 {
860 let watches = self.watches.lock().unwrap();
861 for (key, f) in watches.iter() {
862 key.trace(visitor);
863 f.trace(visitor);
864 }
865 }
866 }
867}