Skip to main content

sim_lib_control/
model.rs

1use sim_kernel::{Cx, Expr, Object, ObjectCompat, Ref, Result, Symbol};
2
3#[sim_citizen_derive::non_citizen(
4    reason = "live continuation capture handle; descriptor data is the continuation and capture refs",
5    kind = "handle",
6    descriptor = "core/Ref"
7)]
8/// A runtime object wrapping a captured continuation and its capture result.
9///
10/// Returned when a control capture succeeds; carries the continuation [`Ref`]
11/// to resume, the result the capture produced, and whether the continuation may
12/// be resumed more than once.
13#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct ContinuationValue {
15    continuation: Ref,
16    capture_result: Ref,
17    multishot: bool,
18}
19
20impl ContinuationValue {
21    /// Wraps a captured `continuation`, its `capture_result`, and whether it is
22    /// `multishot` (resumable more than once).
23    pub fn new(continuation: Ref, capture_result: Ref, multishot: bool) -> Self {
24        Self {
25            continuation,
26            capture_result,
27            multishot,
28        }
29    }
30
31    /// Returns the continuation reference to resume.
32    pub fn continuation(&self) -> &Ref {
33        &self.continuation
34    }
35
36    /// Returns the result produced when the continuation was captured.
37    pub fn capture_result(&self) -> &Ref {
38        &self.capture_result
39    }
40
41    /// Returns whether this continuation may be resumed more than once.
42    pub fn multishot(&self) -> bool {
43        self.multishot
44    }
45}
46
47impl Object for ContinuationValue {
48    fn display(&self, _cx: &mut Cx) -> Result<String> {
49        Ok(format!("#<control-continuation {:?}>", self.continuation))
50    }
51
52    fn as_any(&self) -> &dyn std::any::Any {
53        self
54    }
55}
56
57impl ObjectCompat for ContinuationValue {
58    fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
59        Ok(Expr::Call {
60            operator: Box::new(Expr::Symbol(Symbol::qualified("control", "continuation"))),
61            args: vec![ref_expr(&self.continuation)],
62        })
63    }
64}
65
66#[sim_citizen_derive::non_citizen(
67    reason = "control result ref wrapper; canonical data is the referenced value",
68    kind = "marker"
69)]
70/// A runtime object wrapping the result reference of a control operation.
71///
72/// Produced by prompt, abort, and resume operations; its canonical data is the
73/// referenced value it carries.
74#[derive(Clone, Debug, PartialEq, Eq)]
75pub struct ControlResultValue {
76    reference: Ref,
77}
78
79impl ControlResultValue {
80    /// Wraps the `reference` produced by a control operation.
81    pub fn new(reference: Ref) -> Self {
82        Self { reference }
83    }
84
85    /// Returns the wrapped result reference.
86    pub fn reference(&self) -> &Ref {
87        &self.reference
88    }
89}
90
91impl Object for ControlResultValue {
92    fn display(&self, _cx: &mut Cx) -> Result<String> {
93        Ok(format!("#<control-result {:?}>", self.reference))
94    }
95
96    fn as_any(&self) -> &dyn std::any::Any {
97        self
98    }
99}
100
101impl ObjectCompat for ControlResultValue {
102    fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
103        Ok(ref_expr(&self.reference))
104    }
105}
106
107pub(crate) fn ref_expr(reference: &Ref) -> Expr {
108    match reference {
109        Ref::Symbol(symbol) => Expr::Symbol(symbol.clone()),
110        other => Expr::String(format!("{other:?}")),
111    }
112}