1use crate::{
53 gc::{Gc, GcInner, Trace},
54 lists::slice_to_list,
55 ports::{IoError, IoReadError, IoWriteError},
56 proc::{Application, DynStackElem, DynamicState, FuncPtr, Procedure, pop_dyn_stack},
57 records::{Record, RecordTypeDescriptor, SchemeCompatible, rtd},
58 registry::{bridge, cps_bridge},
59 runtime::{Runtime, RuntimeInner},
60 symbols::Symbol,
61 syntax::{Identifier, Syntax, parse::ParseSyntaxError},
62 value::{UnpackedValue, Value},
63 vectors::Vector,
64};
65use parking_lot::RwLock;
66use scheme_rs_macros::runtime_fn;
67use std::{convert::Infallible, fmt, ops::Range, sync::Arc};
68
69pub use scheme_rs_macros::define_condition_type;
71
72impl fmt::Display for Exception {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 <Value as fmt::Debug>::fmt(&self.0, f)
75 }
76}
77
78#[derive(Debug, Clone)]
80pub struct Exception(pub Value);
81
82impl Exception {
83 pub fn error(message: impl fmt::Display) -> Self {
84 Self(Value::from(Record::from_rust_type(
85 CompoundCondition::from((Assertion::new(), Message::new(message.to_string()))),
86 )))
87 }
88
89 pub fn syntax(form: Syntax, subform: Option<Syntax>) -> Self {
90 Self(Value::from(Record::from_rust_type(SyntaxViolation::new(
91 form, subform,
92 ))))
93 }
94
95 pub fn undefined(ident: Identifier) -> Self {
96 Self(Value::from(Record::from_rust_type(
97 CompoundCondition::from((
98 Undefined::new(),
99 Message::new(format!("Undefined variable {}", ident.sym)),
100 )),
101 )))
102 }
103
104 pub fn type_error(expected: &str, provided: &str) -> Self {
105 Self(Value::from(Record::from_rust_type(
106 CompoundCondition::from((
107 Assertion::new(),
108 Message::new(format!(
109 "Expected value of type {expected}, provided {provided}"
110 )),
111 )),
112 )))
113 }
114
115 pub fn invalid_operator(provided: &str) -> Self {
116 Self(Value::from(Record::from_rust_type(
117 CompoundCondition::from((
118 Assertion::new(),
119 Message::new(format!(
120 "Invalid operator, expected procedure, provided {provided}"
121 )),
122 )),
123 )))
124 }
125
126 pub fn invalid_index(index: usize, len: usize) -> Self {
127 Self(Value::from(Record::from_rust_type(
128 CompoundCondition::from((
129 Assertion::new(),
130 Message::new(format!(
131 "Invalid index of {index} into collection of size {len}"
132 )),
133 )),
134 )))
135 }
136
137 pub fn invalid_range(range: Range<usize>, len: usize) -> Self {
138 Self(Value::from(Record::from_rust_type(
139 CompoundCondition::from((
140 Assertion::new(),
141 Message::new(format!(
142 "Invalid range of {range:?} into collection of size {len}"
143 )),
144 )),
145 )))
146 }
147
148 pub fn wrong_num_of_unicode_chars(expected: usize, provided: usize) -> Self {
149 Self(Value::from(Record::from_rust_type(
150 CompoundCondition::from((
151 Assertion::new(),
152 Message::new(format!(
153 "Expected to receive {expected} unicode characters from transform, received {provided}"
154 )),
155 )),
156 )))
157 }
158
159 pub fn wrong_num_of_args(expected: usize, provided: usize) -> Self {
160 Self(Value::from(Record::from_rust_type(
161 CompoundCondition::from((
162 Assertion::new(),
163 Message::new(format!(
164 "Expected {expected} arguments, provided {provided}"
165 )),
166 )),
167 )))
168 }
169
170 pub fn wrong_num_of_var_args(expected: Range<usize>, provided: usize) -> Self {
171 Self(Value::from(Record::from_rust_type(
172 CompoundCondition::from((
173 Assertion::new(),
174 Message::new(format!(
175 "Expected {} to {} arguments, provided {provided}",
176 expected.start, expected.end
177 )),
178 )),
179 )))
180 }
181
182 pub fn implementation_restriction(msg: impl fmt::Display) -> Self {
183 Self(Value::from_rust_type(CompoundCondition::from((
184 Assertion::new(),
185 ImplementationRestriction::new(),
186 Message::new(msg),
187 ))))
188 }
189
190 pub fn conversion_error(expected: &str, provided: &str) -> Self {
194 Self(Value::from(Record::from_rust_type(
195 CompoundCondition::from((
196 Assertion::new(),
197 Message::new(format!("Could not convert {provided} into {expected}")),
198 )),
199 )))
200 }
201
202 pub fn not_representable(value: &str, r#type: &str) -> Self {
206 Self(Value::from(Record::from_rust_type(
207 CompoundCondition::from((
208 Assertion::new(),
209 Message::new(format!("Could not represent '{value}' in {type} type")),
210 )),
211 )))
212 }
213
214 pub fn io_error(message: impl fmt::Display) -> Self {
215 Self(Value::from(Record::from_rust_type(
216 CompoundCondition::from((IoError::new(), Assertion::new(), Message::new(message))),
217 )))
218 }
219
220 pub fn io_read_error(message: impl fmt::Display) -> Self {
221 Self(Value::from(Record::from_rust_type(
222 CompoundCondition::from((IoReadError::new(), Assertion::new(), Message::new(message))),
223 )))
224 }
225
226 pub fn io_write_error(message: impl fmt::Display) -> Self {
227 Self(Value::from(Record::from_rust_type(
228 CompoundCondition::from((IoWriteError::new(), Assertion::new(), Message::new(message))),
229 )))
230 }
231
232 pub fn invalid_record_index(k: usize) -> Self {
233 Self::error(format!("invalid record index: {k}"))
234 }
235
236 pub fn add_condition(self, condition: impl SchemeCompatible) -> Self {
237 let mut conditions = if let Some(compound) = self.0.cast_to_rust_type::<CompoundCondition>()
238 {
239 compound.0.clone()
240 } else {
241 vec![self.0]
242 };
243
244 conditions.push(Value::from(Record::from_rust_type(condition)));
245
246 Self(Value::from(Record::from_rust_type(CompoundCondition(
247 conditions,
248 ))))
249 }
250
251 pub fn simple_conditions(&self) -> Result<Vec<Value>, Exception> {
252 if self.0.cast_to_rust_type::<SimpleCondition>().is_some() {
253 Ok(vec![self.0.clone()])
254 } else if let Some(compound_condition) = self.0.cast_to_rust_type::<CompoundCondition>() {
255 Ok(compound_condition.0.clone())
256 } else {
257 Err(Exception::error("not a simple or compound condition"))
258 }
259 }
260
261 pub fn condition<T: SchemeCompatible>(&self) -> Result<Option<Gc<T>>, Exception> {
262 for condition in self.simple_conditions()?.into_iter() {
263 if let Some(condition) = condition.cast_to_rust_type::<T>() {
264 return Ok(Some(condition));
265 }
266 }
267 Ok(None)
268 }
269}
270
271impl From<&'_ Value> for Option<Exception> {
272 fn from(value: &'_ Value) -> Self {
273 if let UnpackedValue::Record(record) = &*value.unpacked_ref()
274 && let rtd = record.rtd()
275 && (RecordTypeDescriptor::is_subtype_of(&rtd, &SimpleCondition::rtd())
276 || RecordTypeDescriptor::is_subtype_of(&rtd, &CompoundCondition::rtd()))
277 {
278 Some(Exception(value.clone()))
279 } else {
280 None
281 }
282 }
283}
284
285impl From<std::io::Error> for Exception {
286 fn from(value: std::io::Error) -> Self {
287 Self::from((IoError::new(), Message::new(format!("{value:?}"))))
288 }
289}
290
291impl From<SimpleCondition> for Exception {
292 fn from(simple: SimpleCondition) -> Self {
293 Self(Value::from(Record::from_rust_type(simple)))
294 }
295}
296
297impl From<Warning> for Exception {
298 fn from(warning: Warning) -> Self {
299 Self(Value::from(Record::from_rust_type(warning)))
300 }
301}
302
303impl From<Serious> for Exception {
304 fn from(serious: Serious) -> Self {
305 Self(Value::from(Record::from_rust_type(serious)))
306 }
307}
308
309impl From<Message> for Exception {
310 fn from(message: Message) -> Self {
311 Self(Value::from(Record::from_rust_type(message)))
312 }
313}
314
315impl From<Infallible> for Exception {
316 fn from(infallible: Infallible) -> Self {
317 match infallible {}
318 }
319}
320
321impl From<ParseSyntaxError> for Exception {
322 fn from(error: ParseSyntaxError) -> Self {
323 Self::from((Lexical::new(), Message::new(error)))
324 }
325}
326
327macro_rules! impl_into_condition_for {
328 ($for:ty) => {
329 impl From<$for> for Exception {
330 fn from(e: $for) -> Self {
331 Self::error(e.to_string())
332 }
333 }
334 };
335}
336
337impl_into_condition_for!(std::num::TryFromIntError);
338
339#[derive(Copy, Clone, Default, Trace)]
340pub struct SimpleCondition;
341
342impl SimpleCondition {
343 pub fn new() -> Self {
344 Self
345 }
346}
347
348impl SchemeCompatible for SimpleCondition {
349 fn rtd() -> Arc<RecordTypeDescriptor> {
350 rtd!(
351 lib: "(rnrs conditions (6))",
352 name: "&condition",
353 constructor: || Ok(SimpleCondition)
354 )
355 }
356}
357
358impl fmt::Debug for SimpleCondition {
359 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 Ok(())
361 }
362}
363
364#[bridge(name = "condition?", lib = "(rnrs conditions (6))")]
365pub fn condition_pred(obj: &Value) -> Result<Vec<Value>, Exception> {
366 let is_condition = obj.cast_to_rust_type::<SimpleCondition>().is_some()
367 || obj.cast_to_rust_type::<CompoundCondition>().is_some();
368 Ok(vec![Value::from(is_condition)])
369}
370
371define_condition_type!(
372 lib: "(rnrs conditions (6))",
373 rust_name: Message,
374 scheme_name: "&message",
375 parent: SimpleCondition,
376 fields: {
377 message: String,
378 },
379 constructor: |message| {
380 Ok(Message { parent: Gc::new(SimpleCondition::new()), message: message.to_string() })
381 },
382 debug: |this, f| {
383 write!(f, " ")?;
384 this.message.fmt(f)
385 }
386);
387
388impl Message {
389 pub fn new(message: impl fmt::Display) -> Self {
390 Self {
391 parent: Gc::new(SimpleCondition::new()),
392 message: message.to_string(),
393 }
394 }
395}
396
397define_condition_type!(
398 lib: "(rnrs conditions (6))",
399 rust_name: Warning,
400 scheme_name: "&warning",
401 parent: SimpleCondition,
402);
403
404impl Warning {
405 pub fn new() -> Self {
406 Self {
407 parent: Gc::new(SimpleCondition::new()),
408 }
409 }
410}
411
412impl Default for Warning {
413 fn default() -> Self {
414 Self::new()
415 }
416}
417
418define_condition_type!(
419 lib: "(rnrs conditions (6))",
420 rust_name: Serious,
421 scheme_name: "&serious",
422 parent: SimpleCondition,
423);
424
425impl Serious {
426 pub fn new() -> Self {
427 Self {
428 parent: Gc::new(SimpleCondition::new()),
429 }
430 }
431}
432
433impl Default for Serious {
434 fn default() -> Self {
435 Self::new()
436 }
437}
438
439define_condition_type!(
440 lib: "(rnrs conditions (6))",
441 rust_name: StackTrace,
442 scheme_name: "&trace",
443 parent: SimpleCondition,
444 fields: {
445 trace: Vector,
446 },
447 constructor: |trace| {
448 Ok(StackTrace {
449 parent: Gc::new(SimpleCondition::new()),
450 trace: trace.clone().try_into()?,
451 })
452 },
453 debug: |this, f| {
454 for trace in &*this.trace.0.vec.read() {
455 write!(f, " {trace}")?;
456 }
457 Ok(())
458 }
459);
460
461impl StackTrace {
462 pub fn new(trace: Vec<Value>) -> Self {
463 Self {
464 parent: Gc::new(SimpleCondition::new()),
465 trace: Vector::from(trace),
466 }
467 }
468
469 pub fn trace(&self) -> Vec<Syntax> {
470 todo!()
471 }
472}
473
474define_condition_type!(
475 lib: "(rnrs conditions (6))",
476 rust_name: Error,
477 scheme_name: "&error",
478 parent: Serious,
479);
480
481impl Error {
482 pub fn new() -> Self {
483 Self {
484 parent: Gc::new(Serious::new()),
485 }
486 }
487}
488
489impl Default for Error {
490 fn default() -> Self {
491 Self::new()
492 }
493}
494
495define_condition_type!(
496 lib: "(rnrs conditions (6))",
497 rust_name: ImportError,
498 scheme_name: "&import",
499 parent: Error,
500 fields: {
501 library: String,
502 },
503 constructor: |lib| {
504 Ok(ImportError { parent: Gc::new(Error::new()), library: lib.to_string() })
505 },
506 debug: |this, f| {
507 write!(f, " library: {}", this.library)
508 }
509);
510
511impl ImportError {
512 pub fn new(library: String) -> Self {
513 Self {
514 parent: Gc::new(Error::new()),
515 library,
516 }
517 }
518}
519
520define_condition_type!(
521 lib: "(rnrs conditions (6))",
522 rust_name: Violation,
523 scheme_name: "&violation",
524 parent: Serious,
525);
526
527impl Violation {
528 pub fn new() -> Self {
529 Self {
530 parent: Gc::new(Serious::new()),
531 }
532 }
533}
534
535impl Default for Violation {
536 fn default() -> Self {
537 Self::new()
538 }
539}
540
541define_condition_type!(
542 lib: "(rnrs conditions (6))",
543 rust_name: Assertion,
544 scheme_name: "&assertion",
545 parent: Violation
546);
547
548impl Assertion {
549 pub fn new() -> Self {
550 Self {
551 parent: Gc::new(Violation::new()),
552 }
553 }
554}
555
556impl Default for Assertion {
557 fn default() -> Self {
558 Self::new()
559 }
560}
561
562define_condition_type!(
563 lib: "(rnrs conditions (6))",
564 rust_name: Irritants,
565 scheme_name: "&irritants",
566 parent: SimpleCondition,
567 fields: {
568 irritants: Value,
569 },
570 constructor: |irritants| {
571 Ok(Irritants { parent: Gc::new(SimpleCondition::new()), irritants })
572 },
573 debug: |this, f| {
574 write!(f, " irritants: {:?}", this.irritants)
575 }
576);
577
578impl Irritants {
579 pub fn new(irritants: Value) -> Self {
580 Irritants {
581 parent: Gc::new(SimpleCondition::new()),
582 irritants,
583 }
584 }
585}
586
587define_condition_type!(
588 lib: "(rnrs conditions (6))",
589 rust_name: Who,
590 scheme_name: "&who",
591 parent: SimpleCondition,
592 fields: {
593 who: Value,
594 },
595 constructor: |who| {
596 Ok(Who { parent: Gc::new(SimpleCondition::new()), who, })
597 },
598 debug: |this, f| {
599 write!(f, " who: {:?}", this.who)
600 }
601);
602
603impl Who {
604 pub fn new(who: Value) -> Self {
605 Who {
606 parent: Gc::new(SimpleCondition::new()),
607 who,
608 }
609 }
610}
611
612define_condition_type!(
613 lib: "(rnrs conditions (6))",
614 rust_name: NonContinuable,
615 scheme_name: "&non-continuable",
616 parent: Violation,
617);
618
619impl Default for NonContinuable {
620 fn default() -> Self {
621 Self {
622 parent: Gc::new(Violation::new()),
623 }
624 }
625}
626define_condition_type!(
627 lib: "(rnrs conditions (6))",
628 rust_name: ImplementationRestriction,
629 scheme_name: "&implementation-restriction",
630 parent: Violation,
631);
632
633impl ImplementationRestriction {
634 pub fn new() -> Self {
635 Self::default()
636 }
637}
638
639impl Default for ImplementationRestriction {
640 fn default() -> Self {
641 Self {
642 parent: Gc::new(Violation::new()),
643 }
644 }
645}
646
647define_condition_type!(
648 lib: "(rnrs conditions (6))",
649 rust_name: Lexical,
650 scheme_name: "&lexical",
651 parent: Violation,
652);
653
654impl Lexical {
655 pub fn new() -> Self {
656 Self {
657 parent: Gc::new(Violation::new()),
658 }
659 }
660}
661
662impl Default for Lexical {
663 fn default() -> Self {
664 Self::new()
665 }
666}
667
668define_condition_type!(
669 lib: "(rnrs conditions (6))",
670 rust_name: SyntaxViolation,
671 scheme_name: "&syntax",
672 parent: Violation,
673 fields: {
674 form: Value,
675 subform: Option<Value>,
676 },
677 constructor: |form, subform| {
678 let subform = if subform.is_true() { Some(subform) } else { None };
679 Ok(SyntaxViolation { parent: Gc::new(Violation::new()), form, subform })
680 },
681 debug: |this, f| {
682 write!(f, " form: {:?} subform: {:?}", this.form, this.subform)
683 }
684);
685
686impl SyntaxViolation {
687 pub fn new(form: Syntax, subform: Option<Syntax>) -> Self {
688 Self {
689 parent: Gc::new(Violation::new()),
690 form: Value::from(form),
691 subform: subform.map(Value::from),
692 }
693 }
694
695 pub fn new_from_values(form: Value, subform: Option<Value>) -> Self {
696 Self {
697 parent: Gc::new(Violation::new()),
698 form,
699 subform,
700 }
701 }
702}
703
704define_condition_type!(
705 lib: "(rnrs conditions (6))",
706 rust_name: Undefined,
707 scheme_name: "&undefined",
708 parent: Violation
709);
710
711impl Undefined {
712 pub fn new() -> Self {
713 Self {
714 parent: Gc::new(Violation::new()),
715 }
716 }
717}
718
719impl Default for Undefined {
720 fn default() -> Self {
721 Self::new()
722 }
723}
724
725#[derive(Clone, Trace)]
726pub struct CompoundCondition(pub(crate) Vec<Value>);
727
728impl SchemeCompatible for CompoundCondition {
729 fn rtd() -> Arc<RecordTypeDescriptor> {
730 rtd!(
731 lib: "(rnrs conditions (6))",
732 name: "compound-condition",
733 sealed: true,
734 opaque: true
735 )
736 }
737}
738
739impl fmt::Debug for CompoundCondition {
740 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
741 for cond in self.0.iter() {
742 write!(f, " ")?;
743 cond.fmt(f)?;
744 }
745 Ok(())
746 }
747}
748
749impl<T> From<T> for Exception
750where
751 CompoundCondition: From<T>,
752{
753 fn from(value: T) -> Self {
754 Self(Value::from(Record::from_rust_type(
755 CompoundCondition::from(value),
756 )))
757 }
758}
759
760impl<A, B> From<(A, B)> for CompoundCondition
761where
762 A: SchemeCompatible,
763 B: SchemeCompatible,
764{
765 fn from(value: (A, B)) -> Self {
766 Self(vec![
767 Value::from(Record::from_rust_type(value.0)),
768 Value::from(Record::from_rust_type(value.1)),
769 ])
770 }
771}
772
773impl<A, B, C> From<(A, B, C)> for CompoundCondition
774where
775 A: SchemeCompatible,
776 B: SchemeCompatible,
777 C: SchemeCompatible,
778{
779 fn from(value: (A, B, C)) -> Self {
780 Self(vec![
781 Value::from(Record::from_rust_type(value.0)),
782 Value::from(Record::from_rust_type(value.1)),
783 Value::from(Record::from_rust_type(value.2)),
784 ])
785 }
786}
787
788#[bridge(name = "condition", lib = "(rnrs conditions (6))")]
789pub fn condition(conditions: &[Value]) -> Result<Vec<Value>, Exception> {
790 match conditions {
791 [simple_condition] => Ok(vec![simple_condition.clone()]),
793 conditions => Ok(vec![Value::from(Record::from_rust_type(
794 CompoundCondition(conditions.to_vec()),
795 ))]),
796 }
797}
798
799#[bridge(name = "simple-conditions", lib = "(rnrs conditions (6))")]
800pub fn simple_conditions(condition: &Value) -> Result<Vec<Value>, Exception> {
801 Ok(vec![slice_to_list(
802 &Exception(condition.clone()).simple_conditions()?,
803 )])
804}
805
806#[doc(hidden)]
807#[cps_bridge(
808 def = "with-exception-handler handler thunk",
809 lib = "(rnrs exceptions (6))"
810)]
811pub fn with_exception_handler(
812 runtime: &Runtime,
813 _env: &[Value],
814 args: &[Value],
815 _rest_args: &[Value],
816 dyn_state: &mut DynamicState,
817 k: Value,
818) -> Result<Application, Exception> {
819 let [handler, thunk] = args else {
820 unreachable!();
821 };
822
823 let handler: Procedure = handler.clone().try_into()?;
824 let thunk: Procedure = thunk.clone().try_into()?;
825
826 dyn_state.push_dyn_stack(DynStackElem::ExceptionHandler(handler));
827
828 let k_proc: Procedure = k.clone().try_into().unwrap();
829 let (req_args, var) = k_proc.get_formals();
830
831 let k = dyn_state.new_k(
832 runtime.clone(),
833 vec![k.clone()],
834 pop_dyn_stack,
835 req_args,
836 var,
837 );
838
839 Ok(Application::new(thunk, vec![Value::from(k)]))
840}
841
842#[doc(hidden)]
843#[cps_bridge(def = "raise obj", lib = "(rnrs exceptions (6))")]
844pub fn raise_builtin(
845 runtime: &Runtime,
846 _env: &[Value],
847 args: &[Value],
848 _rest_args: &[Value],
849 dyn_state: &mut DynamicState,
850 _k: Value,
851) -> Result<Application, Exception> {
852 Ok(raise(runtime.clone(), args[0].clone(), dyn_state))
853}
854
855pub fn raise(runtime: Runtime, raised: Value, dyn_state: &mut DynamicState) -> Application {
857 let raised = if let Some(condition) = raised.cast_to_scheme_type::<Exception>() {
858 let trace = dyn_state.current_marks(Symbol::intern("trace"));
859 Value::from(condition.add_condition(StackTrace::new(trace)))
860 } else {
861 raised
862 };
863
864 Application::new(
865 dyn_state.new_k(runtime, vec![raised], unwind_to_exception_handler, 0, false),
866 Vec::new(),
867 )
868}
869
870#[runtime_fn]
871unsafe extern "C" fn raise_rt(
872 runtime: *mut GcInner<RwLock<RuntimeInner>>,
873 raised: *const (),
874 dyn_state: *mut DynamicState,
875) -> *mut Application {
876 unsafe {
877 let runtime = Runtime::from_raw_inc_rc(runtime);
878 let raised = Value::from_raw(raised);
879 Box::into_raw(Box::new(raise(
880 runtime,
881 raised,
882 dyn_state.as_mut().unwrap_unchecked(),
883 )))
884 }
885}
886
887unsafe extern "C" fn unwind_to_exception_handler(
888 runtime: *mut GcInner<RwLock<RuntimeInner>>,
889 env: *const Value,
890 _args: *const Value,
891 dyn_state: *mut DynamicState,
892) -> *mut Application {
893 unsafe {
894 let raised = env.as_ref().unwrap().clone();
896
897 let dyn_state = dyn_state.as_mut().unwrap_unchecked();
898
899 loop {
900 let app = match dyn_state.pop_dyn_stack() {
901 None => {
902 Application::halt_err(raised)
904 }
905 Some(DynStackElem::Winder(winder)) => {
906 Application::new(
908 winder.out_thunk,
909 vec![Value::from(dyn_state.new_k(
910 Runtime::from_raw_inc_rc(runtime),
911 vec![raised],
912 unwind_to_exception_handler,
913 0,
914 false,
915 ))],
916 )
917 }
918 Some(DynStackElem::ExceptionHandler(handler)) => Application::new(
919 handler,
920 vec![
921 raised.clone(),
922 Value::from(dyn_state.new_k(
923 Runtime::from_raw_inc_rc(runtime),
924 vec![raised],
925 reraise_exception,
926 0,
927 true,
928 )),
929 ],
930 ),
931 _ => continue,
932 };
933 return Box::into_raw(Box::new(app));
934 }
935 }
936}
937
938unsafe extern "C" fn reraise_exception(
939 runtime: *mut GcInner<RwLock<RuntimeInner>>,
940 env: *const Value,
941 _args: *const Value,
942 _dyn_state: *mut DynamicState,
943) -> *mut Application {
944 unsafe {
945 let runtime = Runtime(Gc::from_raw_inc_rc(runtime));
946
947 let exception = env.as_ref().unwrap().clone();
949
950 Box::into_raw(Box::new(Application::new(
951 Procedure::new(
952 runtime,
953 Vec::new(),
954 FuncPtr::Bridge(raise_builtin),
955 1,
956 false,
957 ),
958 vec![exception, Value::undefined()],
959 )))
960 }
961}
962
963#[doc(hidden)]
966#[cps_bridge(def = "raise-continuable obj", lib = "(rnrs exceptions (6))")]
967pub fn raise_continuable(
968 _runtime: &Runtime,
969 _env: &[Value],
970 args: &[Value],
971 _rest_args: &[Value],
972 dyn_state: &mut DynamicState,
973 k: Value,
974) -> Result<Application, Exception> {
975 let [condition] = args else {
976 unreachable!();
977 };
978
979 let Some(handler) = dyn_state.current_exception_handler() else {
980 return Ok(Application::halt_err(condition.clone()));
981 };
982
983 Ok(Application::new(handler, vec![condition.clone(), k]))
984}
985
986#[bridge(name = "error", lib = "(rnrs base builtins (6))")]
987pub fn error(who: &Value, message: &Value, irritants: &[Value]) -> Result<Vec<Value>, Exception> {
988 let mut conditions = Vec::new();
989 if who.is_true() {
990 conditions.push(Value::from_rust_type(Who::new(who.clone())));
991 }
992 conditions.push(Value::from_rust_type(Message::new(message)));
993 conditions.push(Value::from_rust_type(Irritants::new(slice_to_list(
994 irritants,
995 ))));
996 Err(Exception(Value::from(Exception::from(CompoundCondition(
997 conditions,
998 )))))
999}
1000
1001#[bridge(name = "assertion-violation", lib = "(rnrs base builtins (6))")]
1002pub fn assertion_violation(
1003 who: &Value,
1004 message: &Value,
1005 irritants: &[Value],
1006) -> Result<Vec<Value>, Exception> {
1007 let mut conditions = Vec::new();
1008 conditions.push(Value::from_rust_type(Assertion::new()));
1009 if who.is_true() {
1010 conditions.push(Value::from_rust_type(Who::new(who.clone())));
1011 }
1012 conditions.push(Value::from_rust_type(Message::new(message)));
1013 conditions.push(Value::from_rust_type(Irritants::new(slice_to_list(
1014 irritants,
1015 ))));
1016 Err(Exception(Value::from(Exception::from(CompoundCondition(
1017 conditions,
1018 )))))
1019}