menu: Insert iferr-then-else correctly from menu

In order to correctly insert the `iferr` statements, we need them to
be put outside of the range of immediates.

The rendering was also broken because `IfErrThenElse` is a two byte
opcode and the rendering code was using `payload(o)` (which optimizes
for the 1-byte opcodes) instead of `o->payload()` (which works for all
opcode sizes).

Added some tests, that triggered #1015 and #1016, to be dealt with.

Fixes: #1014

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
Christophe de Dinechin 2024-07-10 01:12:08 +02:00
parent f43baebf15
commit 2c3e2df0fd
3 changed files with 61 additions and 5 deletions

View file

@ -122,7 +122,7 @@ RENDER_BODY(IfThenElse)
// ----------------------------------------------------------------------------
{
// Source objects
byte_p p = payload(o);
byte_p p = o->payload();
// Isolate condition, true and false part
object_g cond = object_p(p);

View file

@ -1287,12 +1287,12 @@ CMD(MenuFirstPage)
//
// ============================================================================
CMD(IfErrThen) // Special tests
CMD(IfErrThenElse) // Last programmable command
CMD(ReplaceChar)
CMD(SelfInsert) // Last immediate command
CMD(IfErrThen) // Special tests
CMD(IfErrThenElse) // Last programmable command
// ============================================================================

View file

@ -162,7 +162,7 @@ void tests::run(bool onlyCurrent)
if (onlyCurrent)
{
here().begin("Current");
complex_types();
conditionals();
}
else
{
@ -1682,6 +1682,62 @@ void tests::conditionals()
.expect("#0₁₆")
.test(BSP)
.expect("\"\"");
// Same thing with menus
step("Menu if-Then (true)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
"PASS", LSHIFT, F1, "0 0", F3, RSHIFT, DOWN, F3, " FAIL", ENTER,
RUNSTOP)
.expect("'PASS'");
step("Menu if-Then (false)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
"FAIL", LSHIFT, F1, "0 0", F2, RSHIFT, DOWN, F3, " PASS", ENTER,
RUNSTOP)
.expect("'PASS'");
step("If-Then-Else (true)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
LSHIFT, F2, "1 0", F3,
RSHIFT, DOWN, F3, " PASS",
RSHIFT, DOWN, F3, " FAIL", ENTER,
RUNSTOP)
.expect("'PASS'");
step("Menu If-Then-Else (false)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
LSHIFT, F2, "1 0", F2,
RSHIFT, DOWN, F3, " FAIL",
RSHIFT, DOWN, F3, " PASS", ENTER,
RUNSTOP)
.expect("'PASS'");
step("Menu IFT command (true)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
"FAIL 1 0", F3, " PASS", LSHIFT, F5, ENTER,
RUNSTOP)
.expect("'PASS'");
step("Menu IFT command (false)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
"PASS 0 FAIL", LSHIFT, F5, ENTER,
RUNSTOP)
.expect("'PASS'");
step("Menu IFTE command (true)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
"1 0", F2, " FAIL PASS", LSHIFT, F6, ENTER,
RUNSTOP)
.expect("'PASS'");
step("Menu IFTE command (false)");
test(CLEAR,
LSHIFT, KEY3, LSHIFT, F2, LSHIFT, RUNSTOP,
"0 FAIL PASS", LSHIFT, F6, ENTER,
RUNSTOP)
.expect("'PASS'");
}