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}