Skip to content

Commit e8cd4d3

Browse files
committed
Use strict evaluation in fathom norm and fathom data
1 parent 3e519e2 commit e8cd4d3

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

fathom/src/core/binary.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::fmt::Debug;
77
use std::slice::SliceIndex;
88
use std::sync::Arc;
99

10-
use super::semantics::LocalExprs;
10+
use super::semantics::{EvalMode, LocalExprs};
1111
use crate::core::semantics::{self, ArcValue, Elim, Head, LazyValue, Value};
1212
use crate::core::{Const, Item, Module, Prim, Term, UIntStyle};
1313
use crate::env::{EnvLen, SharedEnv, UniqueEnv};
@@ -284,7 +284,7 @@ impl<'arena, 'data> Context<'arena, 'data> {
284284

285285
fn eval_env(&mut self) -> semantics::EvalEnv<'arena, '_> {
286286
let elim_env = semantics::ElimEnv::new(&self.item_exprs, [][..].into());
287-
semantics::EvalEnv::new(elim_env, &mut self.local_exprs)
287+
semantics::EvalEnv::new(elim_env, &mut self.local_exprs).with_mode(EvalMode::Strict)
288288
}
289289

290290
fn elim_env(&self) -> semantics::ElimEnv<'arena, '_> {
@@ -296,7 +296,7 @@ impl<'arena, 'data> Context<'arena, 'data> {
296296
for item in module.items {
297297
match item {
298298
Item::Def { expr, .. } => {
299-
let expr = self.eval_env().delay(expr);
299+
let expr = self.eval_env().delay_or_eval(expr);
300300
self.item_exprs.push(expr);
301301
}
302302
}

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
}

fathom/src/driver.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use codespan_reporting::files::SimpleFiles;
77
use codespan_reporting::term::termcolor::{BufferedStandardStream, ColorChoice, WriteColor};
88

99
use crate::core::binary::{self, BufferError, ReadError};
10+
use crate::core::semantics::EvalMode;
1011
use crate::files::{FileId, Files};
1112
use crate::source::{ByteRange, ProgramSource, SourceTooBig, Span, StringInterner, MAX_SOURCE_LEN};
1213
use crate::surface::elaboration::ItemEnv;
@@ -269,8 +270,14 @@ impl<'surface, 'core> Driver<'surface, 'core> {
269270
return Status::Error;
270271
}
271272

272-
let term = context.eval_env().normalize(&self.core_scope, &term);
273-
let r#type = context.eval_env().normalize(&self.core_scope, &r#type);
273+
let term = context
274+
.eval_env()
275+
.with_mode(EvalMode::Strict)
276+
.normalize(&self.core_scope, &term);
277+
let r#type = context
278+
.eval_env()
279+
.with_mode(EvalMode::Strict)
280+
.normalize(&self.core_scope, &r#type);
274281

275282
self.surface_scope.reset(); // Reuse the surface scope for distillation
276283
let mut context = context.distillation_context(&self.surface_scope);

0 commit comments

Comments
 (0)