Skip to content

Commit 7a11837

Browse files
committed
Add EvalMode to control evaluation strategy
1 parent 2c39035 commit 7a11837

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

fathom/src/core/semantics.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ pub type ArcValue<'arena> = Spanned<Arc<Value<'arena>>>;
2020
pub type LocalExprs<'arena> = SharedEnv<LazyValue<'arena>>;
2121
pub type ItemExprs<'arena> = SliceEnv<LazyValue<'arena>>;
2222

23+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
24+
pub enum EvalMode {
25+
Lazy,
26+
Strict,
27+
}
28+
2329
/// Values in weak-head-normal form, with bindings converted to closures.
2430
#[derive(Debug, Clone)]
2531
pub enum Value<'arena> {
@@ -298,6 +304,7 @@ impl Error {
298304
/// Like the [`ElimEnv`], this allows for the running of computations, but
299305
/// also maintains a local environment, allowing for evaluation.
300306
pub struct EvalEnv<'arena, 'env> {
307+
mode: EvalMode,
301308
elim_env: ElimEnv<'arena, 'env>,
302309
local_exprs: &'env mut LocalExprs<'arena>,
303310
}
@@ -308,11 +315,23 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
308315
local_exprs: &'env mut LocalExprs<'arena>,
309316
) -> EvalEnv<'arena, 'env> {
310317
EvalEnv {
318+
mode: EvalMode::Lazy,
311319
elim_env,
312320
local_exprs,
313321
}
314322
}
315323

324+
pub fn with_mode(self, mode: EvalMode) -> Self {
325+
Self { mode, ..self }
326+
}
327+
328+
pub fn delay_or_eval(&mut self, term: &'arena Term<'arena>) -> LazyValue<'arena> {
329+
match self.mode {
330+
EvalMode::Lazy => self.delay(term),
331+
EvalMode::Strict => LazyValue::eager(self.eval(term)),
332+
}
333+
}
334+
316335
pub fn delay(&self, term: &'arena Term<'arena>) -> LazyValue<'arena> {
317336
LazyValue::delay(self.local_exprs.clone(), term)
318337
}
@@ -362,7 +381,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
362381
}
363382
Term::Ann(span, expr, _) => Spanned::merge(*span, self.eval(expr)),
364383
Term::Let(span, _, _, def_expr, body_expr) => {
365-
let def_expr = self.delay(def_expr);
384+
let def_expr = self.delay_or_eval(def_expr);
366385
self.local_exprs.push(def_expr);
367386
let body_expr = self.eval(body_expr);
368387
self.local_exprs.pop();
@@ -376,7 +395,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
376395
Arc::new(Value::FunType(
377396
*plicity,
378397
*param_name,
379-
Arc::new(self.delay(param_type)),
398+
Arc::new(self.delay_or_eval(param_type)),
380399
Closure::new(self.local_exprs.clone(), body_type),
381400
)),
382401
),
@@ -390,7 +409,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
390409
),
391410
Term::FunApp(span, plicity, head_expr, arg_expr) => {
392411
let head_expr = self.eval(head_expr);
393-
let arg_expr = self.delay(arg_expr);
412+
let arg_expr = self.delay_or_eval(arg_expr);
394413
Spanned::merge(*span, self.elim_env.fun_app(*plicity, head_expr, &arg_expr))
395414
}
396415

@@ -399,7 +418,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
399418
Spanned::new(*span, Arc::new(Value::RecordType(labels, types)))
400419
}
401420
Term::RecordLit(span, labels, exprs) => {
402-
let exprs = exprs.iter().map(|expr| self.delay(expr)).collect();
421+
let exprs = exprs.iter().map(|expr| self.delay_or_eval(expr)).collect();
403422
Spanned::new(*span, Arc::new(Value::RecordLit(labels, exprs)))
404423
}
405424
Term::RecordProj(span, head_expr, label) => {
@@ -408,7 +427,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
408427
}
409428

410429
Term::ArrayLit(span, exprs) => {
411-
let exprs = exprs.iter().map(|expr| self.delay(expr)).collect();
430+
let exprs = exprs.iter().map(|expr| self.delay_or_eval(expr)).collect();
412431
Spanned::new(*span, Arc::new(Value::ArrayLit(exprs)))
413432
}
414433

@@ -417,7 +436,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
417436
Spanned::new(*span, Arc::new(Value::FormatRecord(labels, formats)))
418437
}
419438
Term::FormatCond(span, name, format, cond) => {
420-
let format = Arc::new(self.delay(format));
439+
let format = Arc::new(self.delay_or_eval(format));
421440
let cond_expr = Closure::new(self.local_exprs.clone(), cond);
422441
Spanned::new(*span, Arc::new(Value::FormatCond(*name, format, cond_expr)))
423442
}

0 commit comments

Comments
 (0)