Skip to main content

sim_kernel/eval/
strict.rs

1use crate::{
2    Symbol,
3    env::Cx,
4    error::{Error, Result},
5    eval::{Demand, EvalPolicy, PreparedArgs},
6    expr::Expr,
7    object::RawArgs,
8    value::Value,
9};
10
11use super::protocol::Phase;
12
13/// Wraps any [`EvalPolicy`] so unbound names fail with precise errors.
14///
15/// The wrapped policy still controls argument strategy, forcing, macro
16/// expansion, and expression evaluation. `StrictNames` changes only unbound
17/// symbol and unbound call resolution.
18pub struct StrictNames<P>(
19    /// Policy that supplies all behavior except unbound-name resolution.
20    pub P,
21);
22
23impl<P: EvalPolicy> EvalPolicy for StrictNames<P> {
24    fn name(&self) -> &'static str {
25        "strict-names"
26    }
27
28    fn allow_macro_expansion(&self, phase: Phase) -> bool {
29        self.0.allow_macro_expansion(phase)
30    }
31
32    fn prepare_call_args(
33        &self,
34        cx: &mut Cx,
35        raw: RawArgs,
36        demands: &[Demand],
37    ) -> Result<PreparedArgs> {
38        self.0.prepare_call_args(cx, raw, demands)
39    }
40
41    fn force(&self, cx: &mut Cx, value: Value, demand: Demand) -> Result<Value> {
42        self.0.force(cx, value, demand)
43    }
44
45    fn eval_expr(&self, cx: &mut Cx, expr: Expr) -> Result<Value> {
46        self.0.eval_expr(cx, expr)
47    }
48
49    fn resolve_unbound_symbol(&self, _cx: &mut Cx, symbol: Symbol) -> Result<Value> {
50        Err(Error::UnknownSymbol { symbol })
51    }
52
53    fn resolve_unbound_call(
54        &self,
55        _cx: &mut Cx,
56        operator: Symbol,
57        _args: Vec<Expr>,
58    ) -> Result<Value> {
59        Err(Error::UnknownFunction { function: operator })
60    }
61}