@@ -22,7 +22,7 @@ pub type Context {
2222 FrameAwaitFunTerm (Env , TermHash , ContextHash )
2323 FrameAwaitFunValue (Value , ContextHash )
2424 FrameForce (ContextHash )
25- FrameConstr (Env , Int , List < TermHash > , List < Value > , ContextHash )
25+ FrameConstr (Env , Int , List < TermHash > , List < ValueHash > , ContextHash )
2626 FrameCases (Env , List < TermHash > , ContextHash )
2727 NoFrame
2828}
@@ -184,3 +184,152 @@ pub fn compute(
184184 _ -> fail
185185 }
186186}
187+
188+ pub fn return (
189+ ctx: Context ,
190+ value_hash: ValueHash ,
191+ value: Value ,
192+ inner_context: Option < Context > ,
193+ ) -> MachineState {
194+ expect value_hash == ( value |> builtin.serialise_data |> hashing_algo )
195+
196+ when ctx is {
197+ FrameAwaitArg (function, ctx_hash) ->
198+ apply_eval (ctx_hash, function, value_hash, inner_context)
199+ FrameAwaitFunTerm (arg_env, arg_hash, ctx_hash) -> {
200+ let frame = FrameAwaitArg (value, ctx_hash)
201+ Compute (frame, arg_env, arg_hash)
202+ }
203+ FrameAwaitFunValue (arg, ctx_hash) -> {
204+ let arg_hash = arg |> builtin.serialise_data |> hashing_algo
205+ apply_eval (ctx_hash, value, arg_hash, inner_context)
206+ }
207+ FrameForce (ctx_hash) ->
208+ force_eval (ctx_hash, value_hash, value, inner_context)
209+ NoFrame ->
210+ Done (discharge_value (value) |> builtin.serialise_data |> hashing_algo)
211+ FrameConstr (env, tag, fields, eval_fields, ctx_hash) -> {
212+ // FrameConstr(Env, Int, List<TermHash>, List<Value>, ContextHash)
213+ let done = [value_hash, .. eval_fields]
214+
215+ when fields is {
216+ [] -> {
217+ expect Some (inner_context) = inner_context
218+ let constr_value = VConstr { tag, fields: done }
219+ let constr_hash =
220+ constr_value |> builtin.serialise_data |> hashing_algo
221+ Return (inner_context, constr_hash)
222+ }
223+ [next_hash, .. rest] ->
224+ Compute (FrameConstr (env, tag, rest, done, ctx_hash), env, next_hash)
225+ }
226+ }
227+ FrameCases (env, cs, ctx_hash) ->
228+ when value is {
229+ VConstr { tag, fields } -> {
230+ let branch_hash = cs |> list_at (tag)
231+ // Use the new iterative approach instead of recursive transfer_fields
232+ expect Some (ctx) = inner_context
233+ expect ctx_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
234+ // Can we use a Return instead of IteratingFields?
235+ if builtin.null_list (fields) {
236+ // No fields to transfer
237+ Compute (ctx, env, branch_hash)
238+ } else {
239+ todo
240+ }
241+ }
242+ _ -> ErrorState ("Not a constr" )
243+ }
244+ }
245+ }
246+
247+ fn force_eval (
248+ ctx_hash: ContextHash ,
249+ value_hash: ValueHash ,
250+ value: Value ,
251+ ctx: Option < Context > ,
252+ ) -> MachineState {
253+ expect Some (ctx) = ctx
254+ expect ctx_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
255+ expect value_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
256+ when value is {
257+ VDelay (body_hash, env) -> Compute (ctx, env, body_hash)
258+ VBuiltin { fun, force_count, args_count, args } ->
259+ if force_count > 0 {
260+ let new_value =
261+ VBuiltin { fun, force_count: force_count - 1 , args_count, args }
262+ let new_hash = new_value |> builtin.serialise_data |> hashing_algo
263+ Return (ctx, new_hash)
264+ } else {
265+ ErrorState ("builtin term argument expected" )
266+ }
267+ _ -> ErrorState ("nonpolymorphic instantiation" )
268+ }
269+ }
270+
271+ fn apply_eval (
272+ ctx_hash: ContextHash ,
273+ function: Value ,
274+ argument: ValueHash ,
275+ ctx: Option < Context > ,
276+ ) -> MachineState {
277+ expect Some (ctx) = ctx
278+ expect ctx_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
279+ when function is {
280+ VLambda { body: body_hash, env } -> {
281+ let new_env =
282+ Node {
283+ value: argument,
284+ next: env |> builtin.serialise_data |> hashing_algo,
285+ }
286+ Compute (ctx, new_env, body_hash)
287+ }
288+ VBuiltin { fun, force_count, args_count, args } ->
289+ if force_count == 0 {
290+ let result = eval_builtin (fun, args_count, args, argument)
291+ Return (ctx, result)
292+ } else {
293+ ErrorState ("Unexpected Builtin Term Argument" )
294+ }
295+ _ -> ErrorState ("Not a function" )
296+ }
297+ }
298+
299+ fn eval_builtin (
300+ fun: Int ,
301+ args_count: Int ,
302+ args: List < ValueHash > ,
303+ next_arg: ValueHash ,
304+ ) -> ValueHash {
305+ if args_count == 0 {
306+ fail @"Impossible"
307+ } else if args_count == 1 {
308+ // TODO: Implement call_builtin for the tweaked machine
309+ // This is a placeholder - actual implementation would need to handle builtins
310+ fail @"call_builtin not implemented"
311+ } else {
312+ VBuiltin {
313+ fun,
314+ force_count: 0 ,
315+ args_count: args_count - 1 ,
316+ args: [next_arg, .. args],
317+ }
318+ |> builtin.serialise_data
319+ |> hashing_algo
320+ }
321+ }
322+
323+ fn list_at (list: List < a> , index: Int ) -> a {
324+ if index == 0 {
325+ list |> builtin.head_list
326+ } else {
327+ list |> builtin.tail_list |> list_at (index - 1 )
328+ }
329+ }
330+
331+ fn discharge_value (value: Value ) -> Term {
332+ // This is a placeholder - actual implementation would need to convert Value to Term
333+ // Similar to the implementation in machine.ak but adapted for the tweaked machine
334+ fail @"discharge_value not implemented"
335+ }
0 commit comments