ReviewOS

also looking at this

home-lang/home

fix(interpreter): keep the return value across deferred user calls

#929
Open mkantautas wants to merge fix/interpreter-defer-return-value into main
2 files +203 -84
packages/interpreter/src/interpreter.zigmodified+30-84
Changes to packages/interpreter/src/interpreter.zig
@@ -316,12 +316,7 @@ pub const Interpreter = struct {
316316 }
317317
318318 // Execute defers at end of then block
319 const defers = then_env.getDefers();
320 var i: usize = defers.len;
321 while (i > 0) {
322 i -= 1;
323 _ = self.evaluateExpression(defers[i], &then_env) catch {};
324 }
319 self.runDefers(&then_env, then_err);
325320
326321 if (then_err) |err| return err;
327322 } else if (if_stmt.else_block) |else_block| {
@@ -338,12 +333,7 @@ pub const Interpreter = struct {
338333 }
339334
340335 // Execute defers at end of else block
341 const defers = else_env.getDefers();
342 var i: usize = defers.len;
343 while (i > 0) {
344 i -= 1;
345 _ = self.evaluateExpression(defers[i], &else_env) catch {};
346 }
336 self.runDefers(&else_env, else_err);
347337
348338 if (else_err) |err| return err;
349339 }
@@ -372,12 +362,7 @@ pub const Interpreter = struct {
372362 }
373363
374364 // Execute defers at end of iteration
375 const defers = iter_env.getDefers();
376 var i: usize = defers.len;
377 while (i > 0) {
378 i -= 1;
379 _ = self.evaluateExpression(defers[i], &iter_env) catch {};
380 }
365 self.runDefers(&iter_env, iter_err);
381366
382367 // Handle errors after defers
383368 if (iter_err) |err| {
@@ -438,12 +423,7 @@ pub const Interpreter = struct {
438423 }
439424
440425 // Execute defers at end of iteration
441 const defers = iter_env.getDefers();
442 var di: usize = defers.len;
443 while (di > 0) {
444 di -= 1;
445 _ = self.evaluateExpression(defers[di], &iter_env) catch {};
446 }
426 self.runDefers(&iter_env, iter_err);
447427
448428 if (iter_err) |err| {
449429 if (err == error.Return) return err;
@@ -484,12 +464,7 @@ pub const Interpreter = struct {
484464 };
485465 }
486466
487 const defers = iter_env.getDefers();
488 var di: usize = defers.len;
489 while (di > 0) {
490 di -= 1;
491 _ = self.evaluateExpression(defers[di], &iter_env) catch {};
492 }
467 self.runDefers(&iter_env, iter_err);
493468
494469 if (iter_err) |err| {
495470 if (err == error.Return) return err;
@@ -539,12 +514,7 @@ pub const Interpreter = struct {
539514 };
540515 }
541516
542 const defers = iter_env.getDefers();
543 var di: usize = defers.len;
544 while (di > 0) {
545 di -= 1;
546 _ = self.evaluateExpression(defers[di], &iter_env) catch {};
547 }
517 self.runDefers(&iter_env, iter_err);
548518
549519 if (iter_err) |err| {
550520 if (err == error.Return) return err;
@@ -587,12 +557,7 @@ pub const Interpreter = struct {
587557 };
588558 }
589559
590 const defers = iter_env.getDefers();
591 var di: usize = defers.len;
592 while (di > 0) {
593 di -= 1;
594 _ = self.evaluateExpression(defers[di], &iter_env) catch {};
595 }
560 self.runDefers(&iter_env, iter_err);
596561
597562 if (iter_err) |err| {
598563 if (err == error.Return) return err;
@@ -800,12 +765,7 @@ pub const Interpreter = struct {
800765 }
801766
802767 // Execute defers in reverse order (LIFO)
803 const defers = block_env.getDefers();
804 var i: usize = defers.len;
805 while (i > 0) {
806 i -= 1;
807 _ = self.evaluateExpression(defers[i], &block_env) catch {};
808 }
768 self.runDefers(&block_env, block_err);
809769
810770 // Propagate any error that occurred
811771 if (block_err) |err| {
@@ -9072,12 +9032,7 @@ pub const Interpreter = struct {
90729032 }
90739033
90749034 // Execute defers in reverse order before returning
9075 const defers = closure_env.getDefers();
9076 var i: usize = defers.len;
9077 while (i > 0) {
9078 i -= 1;
9079 _ = self.evaluateExpression(defers[i], closure_env) catch {};
9080 }
9035 self.runDefers(closure_env, closure_err);
90819036
90829037 // Handle return or error
90839038 if (closure_err) |err| {
@@ -9132,12 +9087,7 @@ pub const Interpreter = struct {
91329087 }
91339088
91349089 // Execute defers in reverse order before returning
9135 const defers = closure_env.getDefers();
9136 var i: usize = defers.len;
9137 while (i > 0) {
9138 i -= 1;
9139 _ = self.evaluateExpression(defers[i], &closure_env) catch {};
9140 }
9090 self.runDefers(&closure_env, closure_err);
91419091
91429092 // Handle return or error
91439093 if (closure_err) |err| {
@@ -9229,12 +9179,7 @@ pub const Interpreter = struct {
92299179 };
92309180 }
92319181
9232 const defers = closure_env.getDefers();
9233 var i: usize = defers.len;
9234 while (i > 0) {
9235 i -= 1;
9236 _ = self.evaluateExpression(defers[i], &closure_env) catch {};
9237 }
9182 self.runDefers(&closure_env, closure_err);
92389183
92399184 if (closure_err) |err| {
92409185 if (err == error.Return) {
@@ -10948,6 +10893,22 @@ pub const Interpreter = struct {
1094810893 return error.UndefinedFunction;
1094910894 }
1095010895
10896 /// Run `env`'s deferred expressions in reverse order. `scope_err` is the
10897 /// error the scope is exiting with. A deferred call to a user function
10898 /// clears `return_value`, so when the scope is unwinding a `return` and the
10899 /// defers leave the slot empty, the pending value is put back.
10900 fn runDefers(self: *Interpreter, env: *Environment, scope_err: ?InterpreterError) void {
10901 const pending_return = self.return_value;
10902 const defers = env.getDefers();
10903 var i: usize = defers.len;
10904 while (i > 0) {
10905 i -= 1;
10906 _ = self.evaluateExpression(defers[i], env) catch {};
10907 }
10908 const returning = if (scope_err) |err| err == error.Return else false;
10909 if (returning and self.return_value == null) self.return_value = pending_return;
10910 }
10911
1095110912 fn calculateRangeLength(range: .RangeValue) i64 {
1095210913 if (range.step == 0) return 0;
1095310914 const diff = range.end - range.start;
@@ -11041,12 +11002,7 @@ pub const Interpreter = struct {
1104111002 }
1104211003
1104311004 // Execute defers in reverse order before returning
11044 const defers = func_env.getDefers();
11045 var i: usize = defers.len;
11046 while (i > 0) {
11047 i -= 1;
11048 _ = self.evaluateExpression(defers[i], &func_env) catch {};
11049 }
11005 self.runDefers(&func_env, func_err);
1105011006
1105111007 // Handle return or error
1105211008 if (func_err) |err| {
@@ -11122,12 +11078,7 @@ pub const Interpreter = struct {
1112211078 }
1112311079
1112411080 // Execute defers in reverse order before returning
11125 const defers = method_env.getDefers();
11126 var i: usize = defers.len;
11127 while (i > 0) {
11128 i -= 1;
11129 _ = self.evaluateExpression(defers[i], &method_env) catch {};
11130 }
11081 self.runDefers(&method_env, method_err);
1113111082
1113211083 // Handle return or error
1113311084 if (method_err) |err| {
@@ -11178,12 +11129,7 @@ pub const Interpreter = struct {
1117811129 }
1117911130
1118011131 // Execute defers in reverse order before returning
11181 const defers = method_env.getDefers();
11182 var i: usize = defers.len;
11183 while (i > 0) {
11184 i -= 1;
11185 _ = self.evaluateExpression(defers[i], &method_env) catch {};
11186 }
11132 self.runDefers(&method_env, method_err);
1118711133
1118811134 // Handle return or error
1118911135 if (method_err) |err| {