jrincayc / ucblogo-code

Berkeley Logo interpreter
https://people.eecs.berkeley.edu/~bh/logo.html
GNU General Public License v3.0
187 stars 34 forks source link

[STOP] quit the superprocedure when inside [REPEAT] #137

Closed nueropath closed 1 year ago

nueropath commented 2 years ago

I was reading through CSLS and encountered this weird problem

to test.once :thing
print se "Enter word :thing ": 
repeat 1 [if equalp :thing first readlist [print "Right! stop]]
print [Wrong!]
end

to test.twice :thing
test.once :thing
test.once :thing
end

when I run test.twice in ucblogo 6.2(windows) I got

? test.twice 0
Enter 0:
0
Right!
? 

It seems that the [STOP] in test.once also quits test.twice and returns to toplevel. Could you please take a look into this? Thanks!

brianharvey commented 2 years ago

Yup, it fails for me too.

Making it [print "Right! stop foo] (so that the STOP isn't a tail call) doesn't change the result (still fails). Making it REPEAT 2 instead of 1 (so the user's correct answer isn't in the final repetition) also still fails.

Putting PR "FOO after the two test.once lines in test.twice (so test.once isn't a tail call) still fails. Putting a print between the two test.once calls also doesn't change anything.

On the other hand, eliminating the REPEAT, so that the STOP gets directly to the procedure call frame, does fix the problem. It's only if stopping_flag==STOP and you get to a repeat_followup instead of directly to the end of the user procedure call that it fails.

Changing the REPEAT 1 to a RUN makes it work correctly, so there's something specifically wrong with REPEAT.

I swear all the CSLS code used to work... :(

nueropath commented 2 years ago

Yup, it fails for me too.

Making it [print "Right! stop foo] (so that the STOP isn't a tail call) doesn't change the result (still fails). Making it REPEAT 2 instead of 1 (so the user's correct answer isn't in the final repetition) also still fails.

Putting PR "FOO after the two test.once lines in test.twice (so test.once isn't a tail call) still fails. Putting a print between the two test.once calls also doesn't change anything.

On the other hand, eliminating the REPEAT, so that the STOP gets directly to the procedure call frame, does fix the problem. It's only if stopping_flag==STOP and you get to a repeat_followup instead of directly to the end of the user procedure call that it fails.

Changing the REPEAT 1 to a RUN makes it work correctly, so there's something specifically wrong with REPEAT.

I swear all the CSLS code used to work... :(

Appericated for the prompt reply, especially from the author of the book :)

I had also done a few experiments before asking here. Besides eliminating REPEAT like you mentioned, changing STOP to OUTPUT "(and adding IGNORE in test.twice) fixes the problem as well. I also defined a test.quad that calls test.twice twice, the 2nd test.twice does get excuted, just with the same bug.

As long as I know it's not my misunderstanding of STOP I can look over it and continue the book :)

BTW, I really like your CSLS, wish I had read it much earlier.

brianharvey commented 2 years ago

Thanks!

Your test.quad experiment will be helpful. It tells us that the STOP isn't unwinding the stack all the way to toplevel, just that it unwinds once too often.

I hope someone else debugs this; even though I wrote the evaluator, it terrifies me every time I have to look at it. :(

jrincayc commented 2 years ago

I'll gladly take a look at any pull requests to fix this, otherwise it will probably be October before I have time to take a look.

jrincayc commented 2 years ago

Note to future self: Figure out what is happening at eval_sequence_continue in eval.c as test.twice is run.

jrincayc commented 2 years ago

Hm, yes, the evaluator is somewhat terrifying. @brianharvey Can you suggest some sample code I can use for the testing this? Ideally it will return true if it is working and false otherwise so it can be added to the unit tests in the tests directory when we get this working.

I would like to avoid breaking it in a new way. I did check, and Ucblogo 6.1 has the same problem, so it is at least three years old.

jrincayc commented 2 years ago

So if I did my logo code correctly, both of these should output "true but because of this bug, outer2 outputs "false:

to inner1
 make "ret "false
 stop
end

to middle1
 inner1
 make "ret "true
end

to outer1
 make "ret "false
 middle1
 output :ret
end
to inner2
 make "ret "false
 repeat 1 [stop]
end

to middle2
 inner2
 make "ret "true
end

to outer2
 make "ret "false
 middle2
 output :ret
end
jrincayc commented 2 years ago

Two more examples, inner3 is broken, inner4 works:

to inner3
 make "ret "false
 repeat 3 [stop]
end

to middle3
 inner3
 make "ret "true
end

to outer3
 make "ret "false
 middle3
 output :ret
end
to inner4
 make "ret "false
 if "true [stop]
end

to middle4
 inner4
 make "ret "true
end

to outer4
 make "ret "false
 middle4
 output :ret
end
jrincayc commented 1 year ago

FYI, if in #139, I uncomment Tests.Macro.RepeatEarlyStopWorksAsExpected I get this error:

[ Macros ]
----------------------------------------------------------
Tests.Macro.OutputStopWorksAsExpected...     Ok
Tests.Macro.PlainStopErrorsAsExpected...     Ok
Tests.Macro.FunctionStopErrorsAsExpected...  Ok
Tests.Macro.PlainStopInnerWorksAsExpected... Ok
Tests.Macro.RepeatStopWorksAsExpected...            Error
Tests.Macro.RepeatEarlyStopWorksAsExpected... REPEAT doesn't like -1 as input  in PrintTestName
[REPEAT 45 - count :TestName [Type "| |]]
? 

Update: Just a weird error message if the name of the test is too long. Nevermind.

jrincayc commented 1 year ago

Debug prints from outer2:

? outer2
376 PRIM: expresn = [to outer2],  unev = [],  val = nothing,  didnt_get_output = [],  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [to outer2],  unev = [[outer2]],  val = nothing,  didnt_get_output = [],  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1080 PRIM: expresn = [outer2],  unev = [],  val = nothing,  didnt_get_output = [],  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [outer2],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = [outer2],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = outer2,  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

716 PRIM: expresn = [outer2],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

884 PRIM: expresn = [outer2],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [outer2],  unev = [[make "ret "false] [middle2] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1122 PRIM: expresn = [make "ret "false],  unev = [[middle2] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [make "ret "false],  unev = [[middle2] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = [make "ret "false],  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "ret,  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "ret,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "false,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

647 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1146 PRIM: expresn = "false,  unev = [[middle2] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = "false,  unev = [[middle2] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1122 PRIM: expresn = [middle2],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [middle2],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = [middle2],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = middle2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

716 PRIM: expresn = [middle2],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = middle2,  proc = [[[] [inner2] [make "ret "true]] [to middle2  inner2  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

884 PRIM: expresn = [middle2],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = middle2,  proc = [[[] [inner2] [make "ret "true]] [to middle2  inner2  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [middle2],  unev = [[inner2] [make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = middle2,  proc = [[[] [inner2] [make "ret "true]] [to middle2  inner2  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1122 PRIM: expresn = [inner2],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = middle2,  proc = [[[] [inner2] [make "ret "true]] [to middle2  inner2  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [inner2],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = middle2,  proc = [[[] [inner2] [make "ret "true]] [to middle2  inner2  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = [inner2],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [inner2] [make "ret "true]] [to middle2  inner2  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

716 PRIM: expresn = [inner2],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

884 PRIM: expresn = [inner2],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [inner2],  unev = [[make "ret "false] [repeat 1 "[stop]]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1122 PRIM: expresn = [make "ret "false],  unev = [[repeat 1 "[stop]]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [make "ret "false],  unev = [[repeat 1 "[stop]]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = [make "ret "false],  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "ret,  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "ret,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "false,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

647 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = make,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1146 PRIM: expresn = "false,  unev = [[repeat 1 "[stop]]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = "false,  unev = [[repeat 1 "[stop]]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1080 PRIM: expresn = [repeat 1 "[stop]],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [repeat 1 "[stop]],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = inner2,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = [repeat 1 "[stop]],  unev = [1 "[stop]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = 1,  unev = [1 "[stop]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = 1,  unev = ["[stop]],  val = 1,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "[stop],  unev = ["[stop]],  val = 1,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "[stop],  unev = [],  val = [stop],  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = "[stop],  unev = [],  val = [stop],  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = [[[] [make "ret "false] [repeat 1 [stop]]] [to inner2  make "ret "false  repeat 1 [stop] end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

647 PRIM: expresn = "[stop],  unev = [],  val = [stop],  didnt_get_output = [[]],  didnt_output_name = outer2,  fun = repeat,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1196 PRIM: expresn = "[stop],  unev = [],  val = [<CONT> [9 1 stop]],  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

376 PRIM: expresn = "[stop],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = "[stop],  unev = [[stop]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = repeat,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1146 PRIM: expresn = [stop],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = middle2,  proc = [[[] [inner2] [make "ret "true]] [to middle2  inner2  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1146 PRIM: expresn = [stop],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [stop],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer2,  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = :ret,  unev = [],  val = nothing,  didnt_get_output = [output outer2 [output :ret]],  didnt_output_name = [],  fun = outer2,  proc = [[[] [make "ret "false] [middle2] [output :ret]] [to outer2  make "ret "false  middle2  output :ret end] 0 0 0],  Val_status = VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

You don't say what to do with false
jrincayc commented 1 year ago

Debug prints from outer1:

? outer1
376 PRIM: expresn = [to outer1],  unev = [],  val = nothing,  didnt_get_output = [],  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [to outer1],  unev = [[outer1]],  val = nothing,  didnt_get_output = [],  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1080 PRIM: expresn = [outer1],  unev = [],  val = nothing,  didnt_get_output = [],  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [outer1],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = [],  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = [outer1],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = outer1,  proc = [],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

716 PRIM: expresn = [outer1],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

884 PRIM: expresn = [outer1],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = [],  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [outer1],  unev = [[make "ret "false] [middle1] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1122 PRIM: expresn = [make "ret "false],  unev = [[middle1] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [make "ret "false],  unev = [[middle1] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = [make "ret "false],  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "ret,  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "ret,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "false,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

647 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1146 PRIM: expresn = "false,  unev = [[middle1] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = "false,  unev = [[middle1] [output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1122 PRIM: expresn = [middle1],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [middle1],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = [middle1],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

716 PRIM: expresn = [middle1],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

884 PRIM: expresn = [middle1],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [middle1],  unev = [[inner1] [make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1122 PRIM: expresn = [inner1],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [inner1],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = [inner1],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = inner1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

716 PRIM: expresn = [inner1],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = inner1,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

884 PRIM: expresn = [inner1],  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = inner1,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = [inner1],  unev = [[make "ret "false] [stop]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = inner1,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [make "ret "false],  unev = [[stop]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = inner1,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = [make "ret "false],  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "ret,  unev = ["ret "false],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "ret,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "false,  unev = ["false],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [make "ret "false] [stop]] [to inner1  make "ret "false  stop end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

647 PRIM: expresn = "false,  unev = [],  val = false,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1146 PRIM: expresn = "false,  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = "false,  unev = [[make "ret "true]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1080 PRIM: expresn = [make "ret "true],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = [make "ret "true],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = middle1,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = [make "ret "true],  unev = ["ret "true],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "ret,  unev = ["ret "true],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "ret,  unev = ["true],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = "true,  unev = ["true],  val = ret,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

457 PRIM: expresn = "true,  unev = [],  val = true,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

532 PRIM: expresn = "true,  unev = [],  val = true,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = [[[] [inner1] [make "ret "true]] [to middle1  inner1  make "ret "true end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

647 PRIM: expresn = "true,  unev = [],  val = true,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = make,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

1146 PRIM: expresn = "true,  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

902 PRIM: expresn = "true,  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer1,  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

400 PRIM: expresn = :ret,  unev = [],  val = nothing,  didnt_get_output = [output outer1 [output :ret]],  didnt_output_name = [],  fun = outer1,  proc = [[[] [make "ret "false] [middle1] [output :ret]] [to outer1  make "ret "false  middle1  output :ret end] 0 0 0],  Val_status = VALUE_OK, stopping_flag = PRIM
current_unode=0x%x, output_unode=0x%x

You don't say what to do with true
jrincayc commented 1 year ago

I am running this program to test it (in the debug_stop branch):

print "Bad
make "redefp "true
to inner
 make "ret "inner
 repeat 1 [stop]
end

to middle
 inner
 make "ret "middle
end

to outer
 make "ret "outer
 middle
 output :ret
end

and basically, I am seeing this:

...

376 begin_seq:
expresn = "[stop],  unev = [],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer,  fun = repeat,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK, stopping_flag = RUN
current_unode=0xffffffffdc1ca220, output_unode=0x0

902 eval_sequence:
expresn = "[stop],  unev = [[stop]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer,  fun = repeat,  proc = PRIM,  Val_status = NO_VALUE_OK|STOP_OK, stopping_flag = RUN
current_unode=0xffffffffdc1ca220, output_unode=0x0

1146 eval_sequence_continue:
expresn = [stop],  unev = [[make "ret "middle]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer,  fun = middle,  proc = [[[] [inner] [make "ret "middle]] [to middle  inner  make "ret "middle end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = STOP
current_unode=0xffffffffdc1caf60, output_unode=0xffffffffdc1ca220

1146 eval_sequence_continue:
expresn = [stop],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer,  fun = outer,  proc = [[[] [make "ret "outer] [middle] [output :ret]] [to outer  make "ret "outer  middle  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = RUN
current_unode=0xffffffffdc1cc6a0, output_unode=0xffffffffdc1ca220

902 eval_sequence:
expresn = [stop],  unev = [[output :ret]],  val = nothing,  didnt_get_output = nothing,  didnt_output_name = outer,  fun = outer,  proc = [[[] [make "ret "outer] [middle] [output :ret]] [to outer  make "ret "outer  middle  output :ret end] 0 0 0],  Val_status = NO_VALUE_OK|STOP_OK|STOP_TAIL, stopping_flag = RUN
current_unode=0xffffffffdc1cc6a0, output_unode=0xffffffffdc1ca220

976 Newcont = op_want_stop:
expresn = :ret,  unev = [],  val = nothing,  didnt_get_output = [output outer [output :ret]],  didnt_output_name = [],  fun = outer,  proc = [[[] [make "ret "outer] [middle] [output :ret]] [to outer  make "ret "outer  middle  output :ret end] 0 0 0],  Val_status = VALUE_OK, stopping_flag = RUN
current_unode=0xffffffffdc1cc6a0, output_unode=0xffffffffdc1ca220

...

The relevant code is:

eval_sequence_continue:
    reset_args(var);
no_reset_args:  /* allows catch "foo [local ...] to work */
    eval_restore();
    if (dont_fix_ift) {
    ift_iff_flag = dont_fix_ift-1;
    dont_fix_ift = 0;
    }
    debprint("eval_sequence_continue");
    if (stopping_flag == MACRO_RETURN) {
    if (val != NIL && is_list(val) && (isName(car(val), Name_tag)))
        unev = cdr(val);    /* from goto */
    else
        unev = append(val, unev);
    val = UNBOUND;
    stopping_flag = RUN;
    if (unev == NIL) goto fetch_cont;
    } else {
    if (current_unode != output_unode) {
        if (STOPPING || RUNNING) output_node = UNBOUND;
        if (stopping_flag == OUTPUT || STOPPING) {
        stopping_flag = RUN;
        val = output_node;
        goto fetch_cont;
        }
    }
    }

Essentially, eval_restore is getting called twice, and wiping out the middle function's remaining code.

jrincayc commented 1 year ago

Hm, with https://github.com/jrincayc/ucblogo-code/pull/139/commits/5ecb9637f189d5287d0ccbda370cbbe3af120a09 it works:

I do worry that there is some corner case that needs stopping_flag = STOP to be set (that piece of code has been there since the beginning of time (well, since the UCBLogo was first checked into svn)), so before I merge the fix, can @brianharvey and/or @nueropath come up with some test cases for STOP that I can use to check I haven't broken something different?

jrincayc commented 1 year ago

Besides the ones I have already mentioned, here are the test cases I have used:

Should return "d

to inner5
 make "ret "b
 if "false [stop]
 make "ret "c
end

to middle5
 inner5
 make "ret "d
end

to outer5
 make "ret "a
 middle5
 output :ret
end

Should return "c

to inner6
 make "ret "b
 if "false [stop]
 make "ret "c
end

to outer6
 make "ret "a
 inner6
 output :ret
end

Should return "b

to inner7
 make "ret "b
 if "true [stop]
 make "ret "c
end

to outer7
 make "ret "a
 inner7
 output :ret
end
jrincayc commented 1 year ago

Ah, here is a test that fails with my "fix":

to notforever
local "count
make "count 10
forever [
  make "count :count - 1
  if equalp :count 0 [stop]
  pr :count
]
end
jrincayc commented 1 year ago

I have fixed the fix, but I still am not sure it is fixed: https://github.com/jrincayc/ucblogo-code/pull/139/commits/2e15631128a38bdcfb05483b26a4093689eb8b2b

If anyone has suggestions for more logo code to test with, that would be good.

brianharvey commented 1 year ago

One hairy case that might go wrong involves FOR:

to test for [i 1 10] [if :i=5 [stop] print :i] end

jrincayc commented 1 year ago

One hairy case that might go wrong involves FOR:

to test for [i 1 10] [if :i=5 [stop] print :i] end

Yes, this works, and I added it to the tests in the branch :)