@@ -20,6 +20,12 @@ pub type ArcValue<'arena> = Spanned<Arc<Value<'arena>>>;
2020pub type LocalExprs < ' arena > = SharedEnv < LazyValue < ' arena > > ;
2121pub 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 ) ]
2531pub 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.
300306pub 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