@@ -459,6 +459,7 @@ they don't actually take the context as an argument even at the source level.
459459-- | Implicit parameter for the builtin runtime.
460460type GivenCekRuntime uni fun ann = (? cekRuntime :: BuiltinsRuntime fun (CekValue uni fun ann ))
461461type GivenCekCaserBuiltin uni = (? cekCaserBuiltin :: CaserBuiltin uni )
462+ type GivenCekLeterBuiltin uni = (? cekLeterBuiltin :: LeterBuiltin uni )
462463-- | Implicit parameter for the log emitter reference.
463464type GivenCekEmitter uni fun s = (? cekEmitter :: CekEmitter uni fun s )
464465-- | Implicit parameter for budget spender.
@@ -471,6 +472,7 @@ type GivenCekCosts = (?cekCosts :: CekMachineCosts)
471472type GivenCekReqs uni fun ann s =
472473 ( GivenCekRuntime uni fun ann
473474 , GivenCekCaserBuiltin uni
475+ , GivenCekLeterBuiltin uni
474476 , GivenCekEmitter uni fun s
475477 , GivenCekSpender uni fun s
476478 , GivenCekSlippage
@@ -713,8 +715,8 @@ data Context uni fun ann
713715 -- ^ @(constr i V0 ... Vj-1 _ Nj ... Nn)@
714716 | FrameCases ! (CekValEnv uni fun ann ) ! (V. Vector (NTerm uni fun ann )) ! (Context uni fun ann )
715717 -- ^ @(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- | FrameAwaitLet ! [ CekValue uni fun ann ] ! (Context uni fun ann )
718+ | FrameAwaitLetBinds ! (CekValEnv uni fun ann ) {- # UNPACK # -} ! Word64 ! (NTerm uni fun ann ) ! [NTerm uni fun ann ] ! ( ArgStack uni fun ann ) ! (Context uni fun ann )
719+ | FrameAwaitLet {- # UNPACK # -} ! Word64 ! ( ArgStack uni fun ann ) ! (Context uni fun ann )
718720 | NoFrame
719721
720722deriving stock instance (GShow uni , Everywhere uni Show , Show fun , Show ann , Closed uni )
@@ -754,7 +756,7 @@ runCekM
754756 -> (forall s . GivenCekReqs uni fun ann s => CekM uni fun s (DischargeResult uni fun ))
755757 -> CekReport cost NamedDeBruijn uni fun
756758runCekM
757- (MachineParameters caser (MachineVariantParameters costs runtime))
759+ (MachineParameters caser leter (MachineVariantParameters costs runtime))
758760 (ExBudgetMode getExBudgetInfo)
759761 (EmitterMode getEmitterMode)
760762 a = runST $ do
@@ -763,6 +765,7 @@ runCekM
763765 ctr <- newCounter (Proxy @ CounterSize )
764766 let ? cekRuntime = runtime
765767 ? cekCaserBuiltin = caser
768+ ? cekLeterBuiltin = leter
766769 ? cekEmitter = _cekEmitterInfoEmit
767770 ? cekBudgetSpender = _exBudgetModeSpender
768771 ? cekCosts = costs
@@ -851,7 +854,7 @@ enterComputeCek = computeCek
851854 -- stepAndMaybeSpend BApply
852855 -- computeCek (FrameAwaitLetBinds env t bs ctx) env t
853856 case bs of
854- (t : rest) -> computeCek (FrameAwaitLetBinds env body rest [] ctx) env t
857+ (t : rest) -> computeCek (FrameAwaitLetBinds env 0 body rest NilStack ctx) env t
855858 [] -> computeCek ctx env body
856859
857860 {- | The returning phase of the CEK machine.
@@ -892,11 +895,16 @@ enterComputeCek = computeCek
892895 SpineLast arg -> applyEvaluate ctx fun (VCon arg)
893896 SpineCons arg rest -> applyEvaluate (FrameAwaitFunConN rest ctx) fun (VCon arg)
894897 -- s , [_ V1 .. Vn] ◅ lam x (M,ρ) ↦ s , [_ V2 .. Vn]; ρ [ x ↦ V1 ] ▻ M
895- returnCek (FrameAwaitLet args ctx) l =
896- case l of
897- VLet names body env
898- | length names == length args -> computeCek ctx (foldr Env. cons env args) body
899- _ -> error " no"
898+ returnCek (FrameAwaitLet cnt args ctx) l =
899+ let
900+ -- this can probably be done in FrameAwaitLetBinds for better performance.
901+ go acc NilStack = acc
902+ go acc (ConsStack x xs) = Env. cons x (go acc xs)
903+ in case l of
904+ VLet names body env
905+ | length names == fromIntegral cnt -> computeCek ctx (go env args) body
906+ | otherwise -> error $ show (length names) <> " " <> show cnt
907+ _ -> error " no"
900908
901909 returnCek (FrameAwaitFunValueN args ctx) fun =
902910 case args of
@@ -930,16 +938,20 @@ enterComputeCek = computeCek
930938 VCon val -> case unCaserBuiltin ? cekCaserBuiltin val cs of
931939 Left err -> throwErrorDischarged (OperationalError $ CekCaseBuiltinError err) e
932940 Right (HeadOnly fX) -> computeCek ctx env fX
933- Right (HeadSpine f xs) -> computeCek (FrameAwaitFunConN xs ctx) env f
941+ Right (HeadSpine f xs) ->
942+ let
943+ -- we reverse and reverse again, this is bad, just POC
944+ go acc (SpineLast x) = (ConsStack (VCon x) acc, 1 )
945+ go acc (SpineCons x rest) = (+ 1 ) <$> go (ConsStack (VCon x) acc) rest
946+
947+ (xs', cnt) = go NilStack xs
948+ in computeCek (FrameAwaitLet cnt xs' ctx) env f
934949 _ -> throwErrorDischarged (StructuralError NonConstrScrutinizedMachineError ) e
935- -- returnCek (FrameAwaitLetTerm env bs ctx) e =
936- -- case bs of
937- -- (next : todo) -> computeCek (FrameAwaitLetBinds env e todo [] ctx) env next
938- -- [] -> returnCek ctx e -- no bindings
939- returnCek (FrameAwaitLetBinds env l todo done ctx) e =
950+ returnCek (FrameAwaitLetBinds env cnt l todo done ctx) e =
940951 case todo of
941- (next : todo') -> computeCek (FrameAwaitLetBinds env l todo' (e : done) ctx) env next
942- [] -> computeCek (FrameAwaitLet (e : done) ctx) env l
952+ (next : todo') ->
953+ computeCek (FrameAwaitLetBinds env (cnt + 1 ) l todo' (ConsStack e done) ctx) env next
954+ [] -> computeCek (FrameAwaitLet (cnt + 1 ) (ConsStack e done) ctx) env l
943955
944956 -- | @force@ a term and proceed.
945957 -- If v is a delay then compute the body of v;
@@ -996,6 +1008,15 @@ enterComputeCek = computeCek
9961008 evalBuiltinApp ctx fun term' $ f arg
9971009 _ ->
9981010 throwErrorWithCause (StructuralError UnexpectedBuiltinTermArgumentMachineError ) term'
1011+ applyEvaluate ! ctx (VLet names body env) (VCon v) =
1012+ case unLeterBuiltin ? cekLeterBuiltin v of
1013+ Right binds
1014+ | length binds == length names ->
1015+ computeCek ctx (foldl (flip (Env. cons . VCon )) env binds) body
1016+ | otherwise -> error " aa"
1017+ Left e -> error $ show e
1018+
1019+ -- computeCek (FrameAwaitLet cnt xs' ctx) env body
9991020 applyEvaluate ! _ val _ =
10001021 throwErrorDischarged (StructuralError NonFunctionalApplicationMachineError ) val
10011022
0 commit comments