@@ -22,7 +22,7 @@ pub type Context {
22
22
FrameAwaitFunTerm(Env, TermHash, ContextHash)
23
23
FrameAwaitFunValue(Value, ContextHash)
24
24
FrameForce(ContextHash)
25
- FrameConstr(Env, Int, List<TermHash>, List<Value >, ContextHash)
25
+ FrameConstr(Env, Int, List<TermHash>, List<ValueHash >, ContextHash)
26
26
FrameCases(Env, List<TermHash>, ContextHash)
27
27
NoFrame
28
28
}
@@ -52,6 +52,7 @@ pub type MachineState {
52
52
// ReturnAwaitValue(Context, ValueHash)
53
53
Done(TermHash)
54
54
IteratingEnv(Context, Env, Int)
55
+ // IteratingFields(Context, List<ValueHash>, Env, TermHash)
55
56
ErrorState(ByteArray)
56
57
}
57
58
@@ -134,3 +135,157 @@ pub fn compute(
134
135
_ -> fail
135
136
}
136
137
}
138
+
139
+ pub fn return(ctx: Context, value_hash: ValueHash, value: Value, inner_context: Option<Context>) -> MachineState {
140
+ expect value_hash == ( value |> builtin.serialise_data |> hashing_algo )
141
+
142
+ when ctx is {
143
+ FrameAwaitArg(function, ctx_hash) ->
144
+ apply_eval(ctx_hash, function, value_hash, inner_context)
145
+
146
+ FrameAwaitFunTerm(arg_env, arg_hash, ctx_hash) -> {
147
+ let frame = FrameAwaitArg(value, ctx_hash)
148
+
149
+ Compute(frame, arg_env, arg_hash)
150
+ }
151
+
152
+ FrameAwaitFunValue(arg, ctx_hash) -> {
153
+ let arg_hash = ( arg |> builtin.serialise_data |> hashing_algo )
154
+ apply_eval(ctx_hash, value, arg_hash, inner_context)
155
+ }
156
+
157
+ FrameForce(ctx_hash) ->
158
+ force_eval(ctx_hash, value_hash, value, inner_context)
159
+
160
+ NoFrame ->
161
+ Done(discharge_value(value) |> builtin.serialise_data |> hashing_algo)
162
+
163
+ FrameConstr(env, tag, fields, eval_fields, ctx_hash) -> {
164
+ // FrameConstr(Env, Int, List<TermHash>, List<Value>, ContextHash)
165
+ let done = [value_hash, ..eval_fields]
166
+
167
+ when fields is {
168
+ [] -> {
169
+ expect Some(inner_context) = inner_context
170
+ let constr_value = VConstr { tag, fields: done }
171
+ let constr_hash = constr_value |> builtin.serialise_data |> hashing_algo
172
+ Return(inner_context, constr_hash)
173
+ }
174
+ [next_hash, ..rest] ->
175
+ Compute(
176
+ FrameConstr(env, tag, rest, done, ctx_hash),
177
+ env,
178
+ next_hash
179
+ )
180
+ }
181
+ }
182
+
183
+ FrameCases(env, cs, ctx_hash) ->
184
+ when value is {
185
+ VConstr { tag, fields } -> {
186
+ let branch_hash = cs |> list_at(tag)
187
+
188
+ // Use the new iterative approach instead of recursive transfer_fields
189
+ expect Some(ctx) = inner_context
190
+ expect ctx_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
191
+ // Can we use a Return instead of IteratingFields?
192
+ if builtin.null_list(fields) {
193
+ // No fields to transfer
194
+ Compute(ctx, env, branch_hash)
195
+ } else {
196
+ todo
197
+ }
198
+ }
199
+ _ -> ErrorState("Not a constr")
200
+ }
201
+ }
202
+ }
203
+
204
+ fn force_eval(ctx_hash: ContextHash, value_hash: ValueHash, value: Value, ctx: Option<Context>) -> MachineState {
205
+ expect Some(ctx) = ctx
206
+ expect ctx_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
207
+ expect value_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
208
+ when value is {
209
+ VDelay(body_hash, env) ->
210
+ Compute(ctx, env, body_hash)
211
+
212
+ VBuiltin { fun, force_count, args_count, args } ->
213
+ if force_count > 0 {
214
+ let new_value =
215
+ VBuiltin {
216
+ fun,
217
+ force_count: force_count - 1,
218
+ args_count,
219
+ args
220
+ }
221
+ let new_hash = new_value |> builtin.serialise_data |> hashing_algo
222
+
223
+ Return(ctx, new_hash)
224
+ } else {
225
+ ErrorState("builtin term argument expected")
226
+ }
227
+
228
+ _ -> ErrorState("nonpolymorphic instantiation")
229
+ }
230
+ }
231
+
232
+ fn apply_eval(ctx_hash: ContextHash, function: Value, argument: ValueHash, ctx: Option<Context>) -> MachineState {
233
+ expect Some(ctx) = ctx
234
+ expect ctx_hash == ( ctx |> builtin.serialise_data |> hashing_algo )
235
+ when function is {
236
+ VLambda { body: body_hash, env } -> {
237
+ let new_env = Env {
238
+ value: argument,
239
+ next: env |> builtin.serialise_data |> hashing_algo,
240
+ }
241
+
242
+ Compute(ctx, new_env, body_hash)
243
+ }
244
+
245
+ VBuiltin { fun, force_count, args_count, args } ->
246
+ if force_count == 0 {
247
+ let result = eval_builtin(fun, args_count, args, argument)
248
+ Return(ctx, result)
249
+ } else {
250
+ ErrorState("Unexpected Builtin Term Argument")
251
+ }
252
+
253
+ _ -> ErrorState("Not a function")
254
+ }
255
+ }
256
+
257
+ fn eval_builtin(
258
+ fun: Int,
259
+ args_count: Int,
260
+ args: List<ValueHash>,
261
+ next_arg: ValueHash,
262
+ ) -> ValueHash {
263
+ if args_count == 0 {
264
+ fail @"Impossible"
265
+ } else if args_count == 1 {
266
+ // TODO: Implement call_builtin for the tweaked machine
267
+ // This is a placeholder - actual implementation would need to handle builtins
268
+ fail @"call_builtin not implemented"
269
+ } else {
270
+ VBuiltin {
271
+ fun,
272
+ force_count: 0,
273
+ args_count: args_count - 1,
274
+ args: [next_arg, ..args],
275
+ } |> builtin.serialise_data |> hashing_algo
276
+ }
277
+ }
278
+
279
+ fn list_at(list: List<a>, index: Int) -> a {
280
+ if index == 0 {
281
+ list |> builtin.head_list
282
+ } else {
283
+ list |> builtin.tail_list |> list_at(index - 1)
284
+ }
285
+ }
286
+
287
+ fn discharge_value(value: Value) -> Term {
288
+ // This is a placeholder - actual implementation would need to convert Value to Term
289
+ // Similar to the implementation in machine.ak but adapted for the tweaked machine
290
+ fail @"discharge_value not implemented"
291
+ }
0 commit comments