@@ -7,8 +7,8 @@ use std::sync::Arc;
77use scoped_arena:: Scope ;
88
99use 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 } ;
1212use crate :: source:: { Span , Spanned , StringId } ;
1313
1414/// Atomically reference counted values. We use reference counting to increase
@@ -53,6 +53,8 @@ pub enum Value<'arena> {
5353}
5454
5555impl < ' arena > Value < ' arena > {
56+ pub const ERROR : Self = Self :: Stuck ( Head :: Prim ( Prim :: ReportedError ) , Vec :: new ( ) ) ;
57+
5658 pub fn prim ( prim : Prim , params : impl IntoIterator < Item = ArcValue < ' arena > > ) -> Value < ' arena > {
5759 let params = params
5860 . into_iter ( )
@@ -299,13 +301,29 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
299301 self . apply_local_infos ( head_expr, local_infos)
300302 }
301303 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 ) ;
304306 self . local_exprs . push ( def_expr) ;
305307 let body_expr = self . eval ( body_expr) ;
306308 self . local_exprs . pop ( ) ;
307309 Spanned :: merge ( * span, body_expr)
308310 }
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+ }
309327
310328 Term :: Universe ( span) => Spanned :: new ( * span, Arc :: new ( Value :: Universe ) ) ,
311329
@@ -879,13 +897,35 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
879897 scope. to_scope ( self . unfold_metas ( scope, expr) ) ,
880898 scope. to_scope ( self . unfold_metas ( scope, r#type) ) ,
881899 ) ,
882- Term :: Let ( span, def_name , def_type , def_expr , body_expr) => Term :: Let (
900+ Term :: Let ( span, def , body_expr) => Term :: Let (
883901 * 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+ } ) ,
887907 self . unfold_bound_metas ( scope, body_expr) ,
888908 ) ,
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+ }
889929
890930 Term :: Universe ( span) => Term :: Universe ( * span) ,
891931
0 commit comments