@@ -20,6 +20,12 @@ pub type ArcValue<'arena> = Spanned<Arc<Value<'arena>>>;
20
20
pub type LocalExprs < ' arena > = SharedEnv < LazyValue < ' arena > > ;
21
21
pub type ItemExprs < ' arena > = SliceEnv < LazyValue < ' arena > > ;
22
22
23
+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
24
+ pub enum EvalMode {
25
+ Lazy ,
26
+ Strict ,
27
+ }
28
+
23
29
/// Values in weak-head-normal form, with bindings converted to closures.
24
30
#[ derive( Debug , Clone ) ]
25
31
pub enum Value < ' arena > {
@@ -298,6 +304,7 @@ impl Error {
298
304
/// Like the [`ElimEnv`], this allows for the running of computations, but
299
305
/// also maintains a local environment, allowing for evaluation.
300
306
pub struct EvalEnv < ' arena , ' env > {
307
+ mode : EvalMode ,
301
308
elim_env : ElimEnv < ' arena , ' env > ,
302
309
local_exprs : & ' env mut LocalExprs < ' arena > ,
303
310
}
@@ -308,11 +315,23 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
308
315
local_exprs : & ' env mut LocalExprs < ' arena > ,
309
316
) -> EvalEnv < ' arena , ' env > {
310
317
EvalEnv {
318
+ mode : EvalMode :: Lazy ,
311
319
elim_env,
312
320
local_exprs,
313
321
}
314
322
}
315
323
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
+
316
335
pub fn delay ( & self , term : & ' arena Term < ' arena > ) -> LazyValue < ' arena > {
317
336
LazyValue :: delay ( self . local_exprs . clone ( ) , term)
318
337
}
@@ -362,7 +381,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
362
381
}
363
382
Term :: Ann ( span, expr, _) => Spanned :: merge ( * span, self . eval ( expr) ) ,
364
383
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) ;
366
385
self . local_exprs . push ( def_expr) ;
367
386
let body_expr = self . eval ( body_expr) ;
368
387
self . local_exprs . pop ( ) ;
@@ -376,7 +395,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
376
395
Arc :: new ( Value :: FunType (
377
396
* plicity,
378
397
* param_name,
379
- Arc :: new ( self . delay ( param_type) ) ,
398
+ Arc :: new ( self . delay_or_eval ( param_type) ) ,
380
399
Closure :: new ( self . local_exprs . clone ( ) , body_type) ,
381
400
) ) ,
382
401
) ,
@@ -390,7 +409,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
390
409
) ,
391
410
Term :: FunApp ( span, plicity, head_expr, arg_expr) => {
392
411
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) ;
394
413
Spanned :: merge ( * span, self . elim_env . fun_app ( * plicity, head_expr, & arg_expr) )
395
414
}
396
415
@@ -399,7 +418,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
399
418
Spanned :: new ( * span, Arc :: new ( Value :: RecordType ( labels, types) ) )
400
419
}
401
420
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 ( ) ;
403
422
Spanned :: new ( * span, Arc :: new ( Value :: RecordLit ( labels, exprs) ) )
404
423
}
405
424
Term :: RecordProj ( span, head_expr, label) => {
@@ -408,7 +427,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
408
427
}
409
428
410
429
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 ( ) ;
412
431
Spanned :: new ( * span, Arc :: new ( Value :: ArrayLit ( exprs) ) )
413
432
}
414
433
@@ -417,7 +436,7 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
417
436
Spanned :: new ( * span, Arc :: new ( Value :: FormatRecord ( labels, formats) ) )
418
437
}
419
438
Term :: FormatCond ( span, name, format, cond) => {
420
- let format = Arc :: new ( self . delay ( format) ) ;
439
+ let format = Arc :: new ( self . delay_or_eval ( format) ) ;
421
440
let cond_expr = Closure :: new ( self . local_exprs . clone ( ) , cond) ;
422
441
Spanned :: new ( * span, Arc :: new ( Value :: FormatCond ( * name, format, cond_expr) ) )
423
442
}
0 commit comments