Skip to main content

sim_kernel/eval/
demand.rs

1use crate::{
2    env::Cx,
3    expr::Expr,
4    id::{ClassId, ShapeId},
5    value::Value,
6};
7
8/// How strongly an argument position demands its value be forced.
9///
10/// A [`Demand`] is the contract an [`EvalPolicy`](crate::EvalPolicy) consults
11/// when preparing call arguments: it states how far a value must be driven
12/// before the callable sees it, from "leave it as an unevaluated expression"
13/// to "force it to a value of a specific class or shape". The kernel only
14/// defines the demand vocabulary; libraries decide how to satisfy each variant.
15///
16/// # Examples
17///
18/// ```
19/// use sim_kernel::eval::Demand;
20///
21/// // The vocabulary is plain, copyable data.
22/// let demand = Demand::Value;
23/// assert_eq!(demand, Demand::Value);
24/// assert_ne!(Demand::Value, Demand::Expr);
25/// ```
26#[derive(Clone, Copy, Debug, PartialEq, Eq)]
27pub enum Demand {
28    /// Never force; the argument is passed through untouched.
29    Never,
30    /// Force to an expression form (leave it quoted, do not evaluate).
31    Expr,
32    /// Force to a fully evaluated value.
33    Value,
34    /// Force to a value and coerce to its boolean truth.
35    Bool,
36    /// Force to a value required to be of the given class.
37    Class(ClassId),
38    /// Force to a value required to match the given shape.
39    Shape(ShapeId),
40}
41
42/// A positional tuple of prepared call arguments.
43///
44/// Produced by [`EvalPolicy::prepare_call_args`](crate::EvalPolicy::prepare_call_args),
45/// it carries the values (eager, thunked, or quoted, per the policy and the
46/// per-position [`Demand`]) that a callable receives.
47///
48/// # Examples
49///
50/// ```
51/// use sim_kernel::eval::PreparedArgs;
52///
53/// let args = PreparedArgs::new(Vec::new());
54/// assert!(args.is_empty());
55/// assert_eq!(args.len(), 0);
56/// assert!(args.get(0).is_none());
57/// ```
58#[derive(Clone)]
59pub struct PreparedArgs {
60    values: Vec<Value>,
61}
62
63impl PreparedArgs {
64    /// Wraps an ordered list of prepared argument values.
65    pub fn new(values: Vec<Value>) -> Self {
66        Self { values }
67    }
68
69    /// Returns the prepared values in positional order.
70    pub fn values(&self) -> &[Value] {
71        &self.values
72    }
73
74    /// Returns the value at `index`, or `None` if out of range.
75    pub fn get(&self, index: usize) -> Option<&Value> {
76        self.values.get(index)
77    }
78
79    /// Returns the number of prepared arguments.
80    pub fn len(&self) -> usize {
81        self.values.len()
82    }
83
84    /// Returns `true` when there are no prepared arguments.
85    pub fn is_empty(&self) -> bool {
86        self.values.is_empty()
87    }
88
89    /// Reconstructs the arguments as a single list [`Expr`] of their forms.
90    pub fn as_expr_tuple(&self, cx: &mut Cx) -> crate::error::Result<Expr> {
91        Ok(Expr::List(
92            self.values
93                .iter()
94                .map(|value| value.object().as_expr(cx))
95                .collect::<crate::error::Result<Vec<_>>>()?,
96        ))
97    }
98}