@@ -7,8 +7,8 @@ use std::sync::Arc;
7
7
use scoped_arena:: Scope ;
8
8
9
9
use crate :: alloc:: SliceVec ;
10
- use crate :: core:: { prim , Const , LocalInfo , Plicity , Prim , Term } ;
11
- use crate :: env:: { EnvLen , Index , Level , SharedEnv , SliceEnv } ;
10
+ use crate :: core:: * ;
11
+ use crate :: env:: { self , EnvLen , Index , Level , SharedEnv , SliceEnv } ;
12
12
use crate :: source:: { Span , Spanned , StringId } ;
13
13
14
14
/// Atomically reference counted values. We use reference counting to increase
@@ -53,6 +53,8 @@ pub enum Value<'arena> {
53
53
}
54
54
55
55
impl < ' arena > Value < ' arena > {
56
+ pub const ERROR : Self = Self :: Stuck ( Head :: Prim ( Prim :: ReportedError ) , Vec :: new ( ) ) ;
57
+
56
58
pub fn prim ( prim : Prim , params : impl IntoIterator < Item = ArcValue < ' arena > > ) -> Value < ' arena > {
57
59
let params = params
58
60
. into_iter ( )
@@ -299,13 +301,29 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
299
301
self . apply_local_infos ( head_expr, local_infos)
300
302
}
301
303
Term :: Ann ( span, expr, _) => Spanned :: merge ( * span, self . eval ( expr) ) ,
302
- Term :: Let ( span, _ , _ , def_expr , body_expr) => {
303
- let def_expr = self . eval ( def_expr ) ;
304
+ Term :: Let ( span, def , body_expr) => {
305
+ let def_expr = self . eval ( & def . expr ) ;
304
306
self . local_exprs . push ( def_expr) ;
305
307
let body_expr = self . eval ( body_expr) ;
306
308
self . local_exprs . pop ( ) ;
307
309
Spanned :: merge ( * span, body_expr)
308
310
}
311
+ Term :: Letrec ( span, defs, body_expr) => {
312
+ let initial_len = self . local_exprs . len ( ) ;
313
+
314
+ for _def in defs. iter ( ) {
315
+ // TODO: lazy evaluation?
316
+ ( self . local_exprs ) . push ( Spanned :: empty ( Arc :: new ( Value :: ERROR ) ) ) ;
317
+ }
318
+ for ( level, def) in Iterator :: zip ( env:: levels ( ) , defs. iter ( ) ) {
319
+ let def_expr = self . eval ( & def. expr ) ;
320
+ self . local_exprs . set_level ( level, def_expr) ;
321
+ }
322
+
323
+ let body_expr = self . eval ( body_expr) ;
324
+ self . local_exprs . truncate ( initial_len) ;
325
+ Spanned :: merge ( * span, body_expr)
326
+ }
309
327
310
328
Term :: Universe ( span) => Spanned :: new ( * span, Arc :: new ( Value :: Universe ) ) ,
311
329
@@ -879,13 +897,35 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
879
897
scope. to_scope ( self . unfold_metas ( scope, expr) ) ,
880
898
scope. to_scope ( self . unfold_metas ( scope, r#type) ) ,
881
899
) ,
882
- Term :: Let ( span, def_name , def_type , def_expr , body_expr) => Term :: Let (
900
+ Term :: Let ( span, def , body_expr) => Term :: Let (
883
901
* span,
884
- * def_name,
885
- scope. to_scope ( self . unfold_metas ( scope, def_type) ) ,
886
- scope. to_scope ( self . unfold_metas ( scope, def_expr) ) ,
902
+ scope. to_scope ( LetDef {
903
+ name : def. name ,
904
+ r#type : self . unfold_metas ( scope, & def. r#type ) ,
905
+ expr : self . unfold_metas ( scope, & def. expr ) ,
906
+ } ) ,
887
907
self . unfold_bound_metas ( scope, body_expr) ,
888
908
) ,
909
+ Term :: Letrec ( span, defs, body_expr) => {
910
+ let initial_len = self . local_exprs . len ( ) ;
911
+
912
+ for _def in defs. iter ( ) {
913
+ let var = Arc :: new ( Value :: local_var ( self . local_exprs . len ( ) . next_level ( ) ) ) ;
914
+ self . local_exprs . push ( Spanned :: empty ( var) ) ;
915
+ }
916
+
917
+ let defs = scope. to_scope_from_iter ( defs. iter ( ) . map ( |def| {
918
+ let name = def. name ;
919
+ let r#type = self . unfold_metas ( scope, & def. r#type ) ;
920
+ let expr = self . unfold_metas ( scope, & def. expr ) ;
921
+ LetDef { name, r#type, expr }
922
+ } ) ) ;
923
+
924
+ let body_expr = self . unfold_metas ( scope, body_expr) ;
925
+ self . local_exprs . truncate ( initial_len) ;
926
+
927
+ Term :: Letrec ( * span, defs, scope. to_scope ( body_expr) )
928
+ }
889
929
890
930
Term :: Universe ( span) => Term :: Universe ( * span) ,
891
931
0 commit comments