@@ -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