@@ -308,7 +308,7 @@ data CekValue uni fun ann =
308308 -- Check the docs of 'BuiltinRuntime' for details.
309309 -- | A constructor value, including fully computed arguments and the tag.
310310 | VConstr {- # UNPACK #-} !Word64 ! (EmptyOrMultiStack uni fun ann )
311- | VBinds ! ( ArgStackNonEmpty uni fun ann )
311+ | VLet ! [ NamedDeBruijn ] ! ( NTerm uni fun ann ) ! ( CekValEnv uni fun ann )
312312
313313deriving stock instance (GShow uni , Everywhere uni Show , Show fun , Show ann , Closed uni )
314314 => Show (CekValue uni fun ann )
@@ -640,6 +640,11 @@ dischargeCekValue value0 = DischargeNonConstant $ goValue value0 where
640640 -- @term@ is fully discharged, so we can return it directly without any further discharging.
641641 VBuiltin _ term _ -> term
642642 VConstr ind args -> Constr () ind . map goValue $ argStackToList args
643+ VLet names body env ->
644+ Let
645+ ()
646+ ((\ (NamedDeBruijn n _ix) -> NamedDeBruijn n deBruijnInitIndex) <$> names)
647+ (goValEnv env 1 body)
643648
644649 -- Instantiate all the free variables of a term by looking them up in an environment.
645650 -- Mutually recursive with @goValue@.
@@ -670,6 +675,8 @@ dischargeCekValue value0 = DischargeNonConstant $ goValue value0 where
670675 Error _ -> Error ()
671676 Constr _ ind args -> Constr () ind $ map (go shift) args
672677 Case _ scrut alts -> Case () (go shift scrut) $ fmap (go shift) alts
678+ Let _ names body -> Let () names (go (shift + fromIntegral (length names)) body)
679+ Bind _ t bs -> Bind () (go shift t) (fmap (go shift) bs)
673680
674681instance (PrettyUni uni , Pretty fun ) => PrettyBy PrettyConfigPlc (CekValue uni fun ann ) where
675682 prettyBy cfg = prettyBy cfg . dischargeResultToTerm . dischargeCekValue
@@ -706,6 +713,8 @@ data Context uni fun ann
706713 -- ^ @(constr i V0 ... Vj-1 _ Nj ... Nn)@
707714 | FrameCases ! (CekValEnv uni fun ann ) ! (V. Vector (NTerm uni fun ann )) ! (Context uni fun ann )
708715 -- ^ @(case _ C0 .. Cn)@
716+ | FrameAwaitLetBinds ! (CekValEnv uni fun ann ) ! (NTerm uni fun ann ) ! [NTerm uni fun ann ] ! [CekValue uni fun ann ] ! (Context uni fun ann )
717+ | FrameMine ! [CekValue uni fun ann ] ! (Context uni fun ann )
709718 | NoFrame
710719
711720deriving stock instance (GShow uni , Everywhere uni Show , Show fun , Show ann , Closed uni )
@@ -719,6 +728,7 @@ instance (Closed uni, uni `Everywhere` ExMemoryUsage) => ExMemoryUsage (CekValue
719728 VLamAbs {} -> singletonRose 1
720729 VBuiltin {} -> singletonRose 1
721730 VConstr {} -> singletonRose 1
731+ VLet {} -> singletonRose 1
722732 {-# INLINE memoryUsage #-}
723733
724734{- Note [ArgStack vs Spine]
@@ -833,6 +843,16 @@ enterComputeCek = computeCek
833843 -- s ; ρ ▻ error ↦ <> A
834844 computeCek ! _ ! _ (Error _) =
835845 throwErrorWithCause (OperationalError CekEvaluationFailure ) (Error () )
846+ -- ???
847+ computeCek ! ctx ! env (Let _ names body) = do
848+ stepAndMaybeSpend BLamAbs
849+ returnCek ctx (VLet names body env)
850+ computeCek ! ctx ! env (Bind _ body bs) = do
851+ -- stepAndMaybeSpend BApply
852+ -- computeCek (FrameAwaitLetBinds env t bs ctx) env t
853+ case bs of
854+ (t : rest) -> computeCek (FrameAwaitLetBinds env body rest [] ctx) env t
855+ [] -> computeCek ctx env body
836856
837857 {- | The returning phase of the CEK machine.
838858 Returns 'EvaluationSuccess' in case the context is empty, otherwise pops up one frame
@@ -872,6 +892,11 @@ enterComputeCek = computeCek
872892 SpineLast arg -> applyEvaluate ctx fun (VCon arg)
873893 SpineCons arg rest -> applyEvaluate (FrameAwaitFunConN rest ctx) fun (VCon arg)
874894 -- s , [_ V1 .. Vn] ◅ lam x (M,ρ) ↦ s , [_ V2 .. Vn]; ρ [ x ↦ V1 ] ▻ M
895+ returnCek (FrameMine args ctx) l =
896+ case l of
897+ VLet _ body env -> computeCek ctx (foldr Env. cons env args) body
898+ _ -> error " no"
899+
875900 returnCek (FrameAwaitFunValueN args ctx) fun =
876901 case args of
877902 LastStackNonEmpty arg ->
@@ -906,6 +931,14 @@ enterComputeCek = computeCek
906931 Right (HeadOnly fX) -> computeCek ctx env fX
907932 Right (HeadSpine f xs) -> computeCek (FrameAwaitFunConN xs ctx) env f
908933 _ -> throwErrorDischarged (StructuralError NonConstrScrutinizedMachineError ) e
934+ -- returnCek (FrameAwaitLetTerm env bs ctx) e =
935+ -- case bs of
936+ -- (next : todo) -> computeCek (FrameAwaitLetBinds env e todo [] ctx) env next
937+ -- [] -> returnCek ctx e -- no bindings
938+ returnCek (FrameAwaitLetBinds env l todo done ctx) e =
939+ case todo of
940+ (next : todo') -> computeCek (FrameAwaitLetBinds env l todo' (e : done) ctx) env next
941+ [] -> computeCek (FrameMine (e : done) ctx) env l
909942
910943 -- | @force@ a term and proceed.
911944 -- If v is a delay then compute the body of v;
0 commit comments