/* Pcode-mode wider-coverage sweep. Every function below is compiled to pcode via FrbCompile (in-process) and called via FrbDo, so any pcode interpreter regression that escaped the focused fixtures surfaces here. Failures are accumulated and printed at the end. */ PROCEDURE Main() LOCAL pMod, src, pass := 0, fail := 0, label, expect, got src := ; 'FUNCTION StringOps(s)' + Chr(10) + ; ' RETURN Upper(s) + "_" + Lower(s)' + Chr(10) + ; 'FUNCTION ArithMix(a, b)' + Chr(10) + ; ' RETURN (a + b) * 2 - a / 2' + Chr(10) + ; 'FUNCTION CmpChain(n)' + Chr(10) + ; ' IF n > 0 .AND. n < 100' + Chr(10) + ; ' RETURN "in"' + Chr(10) + ; ' ELSEIF n == 0' + Chr(10) + ; ' RETURN "zero"' + Chr(10) + ; ' ENDIF' + Chr(10) + ; ' RETURN "out"' + Chr(10) + ; 'FUNCTION ArrSum(arr)' + Chr(10) + ; ' LOCAL n := 0, i' + Chr(10) + ; ' FOR i := 1 TO Len(arr)' + Chr(10) + ; ' n += arr[i]' + Chr(10) + ; ' NEXT' + Chr(10) + ; ' RETURN n' + Chr(10) + ; 'FUNCTION DoWhileTest(n)' + Chr(10) + ; ' LOCAL r := 0' + Chr(10) + ; ' DO WHILE n > 0' + Chr(10) + ; ' r += n' + Chr(10) + ; ' n--' + Chr(10) + ; ' ENDDO' + Chr(10) + ; ' RETURN r' + Chr(10) + ; 'FUNCTION NestedIf(a, b)' + Chr(10) + ; ' IF a > 0' + Chr(10) + ; ' IF b > 0' + Chr(10) + ; ' RETURN "++"' + Chr(10) + ; ' ENDIF' + Chr(10) + ; ' RETURN "+0"' + Chr(10) + ; ' ENDIF' + Chr(10) + ; ' RETURN "00"' + Chr(10) + ; 'FUNCTION IIfTest(n)' + Chr(10) + ; ' RETURN iif(n > 5, "big", "small")' + Chr(10) + ; 'FUNCTION HashLit()' + Chr(10) + ; ' LOCAL h := { "a" => 1, "b" => 2 }' + Chr(10) + ; ' RETURN h["a"] + h["b"]' + Chr(10) + ; 'FUNCTION BlockEval(n)' + Chr(10) + ; ' LOCAL b := {|x| x * x }' + Chr(10) + ; ' RETURN Eval(b, n)' + Chr(10) + ; 'FUNCTION CountChars(s, c)' + Chr(10) + ; ' LOCAL i, n := 0' + Chr(10) + ; ' FOR i := 1 TO Len(s)' + Chr(10) + ; ' IF SubStr(s, i, 1) == c' + Chr(10) + ; ' n++' + Chr(10) + ; ' ENDIF' + Chr(10) + ; ' NEXT' + Chr(10) + ; ' RETURN n' + Chr(10) + ; 'FUNCTION Grade(n)' + Chr(10) + ; ' IF n >= 90' + Chr(10) + ; ' RETURN "A"' + Chr(10) + ; ' ELSEIF n >= 80' + Chr(10) + ; ' RETURN "B"' + Chr(10) + ; ' ELSEIF n >= 70' + Chr(10) + ; ' RETURN "C"' + Chr(10) + ; ' ELSEIF n >= 60' + Chr(10) + ; ' RETURN "D"' + Chr(10) + ; ' ELSE' + Chr(10) + ; ' RETURN "F"' + Chr(10) + ; ' ENDIF' + Chr(10) + ; ' RETURN "?"' + Chr(10) pMod := FrbCompile(src) IF pMod == NIL ? "FAIL: compile returned NIL" RETURN ENDIF /* Each row: label, expected, FrbDo call (deferred via codeblock) */ ? "--- pcode sweep ---" label := "1. StringOps('Hi')" expect := "HI_hi" got := FrbDo(pMod, "STRINGOPS", "Hi") IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "2. ArithMix(10, 4)" expect := 23 /* (10+4)*2 - 10/2 = 28 - 5 = 23 */ got := FrbDo(pMod, "ARITHMIX", 10, 4) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "3a. CmpChain(50)" expect := "in" got := FrbDo(pMod, "CMPCHAIN", 50) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "3b. CmpChain(0)" expect := "zero" got := FrbDo(pMod, "CMPCHAIN", 0) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "3c. CmpChain(200)" expect := "out" got := FrbDo(pMod, "CMPCHAIN", 200) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "4. ArrSum({1,2,3,4,5})" expect := 15 got := FrbDo(pMod, "ARRSUM", { 1, 2, 3, 4, 5 }) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "5. DoWhileTest(5)" expect := 15 /* 5+4+3+2+1 */ got := FrbDo(pMod, "DOWHILETEST", 5) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "6a. NestedIf(1,1)" expect := "++" got := FrbDo(pMod, "NESTEDIF", 1, 1) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "6b. NestedIf(1,0)" expect := "+0" got := FrbDo(pMod, "NESTEDIF", 1, 0) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "6c. NestedIf(-1,0)" expect := "00" got := FrbDo(pMod, "NESTEDIF", -1, 0) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "7. IIfTest(10)" expect := "big" got := FrbDo(pMod, "IIFTEST", 10) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "8. HashLit()" expect := 3 got := FrbDo(pMod, "HASHLIT") IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "9. BlockEval(7)" expect := 49 got := FrbDo(pMod, "BLOCKEVAL", 7) IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF label := "10. CountChars('mississippi', 's')" expect := 4 got := FrbDo(pMod, "COUNTCHARS", "mississippi", "s") IF got == expect ? "PASS", label, "=", got pass++ ELSE ? "FAIL", label, "expect", expect, "got", got fail++ ENDIF /* 11a-e. Multi-ELSEIF chain — regression test for genpc jumpEnd patching (every taken branch needs to jump past the rest of the IF, not fall through into the next ELSEIF's bytecode). */ label := "11a. Grade(95)" expect := "A" got := FrbDo(pMod, "GRADE", 95) IF got == expect ; ? "PASS", label, "=", got ; pass++ ; ELSE ; ? "FAIL", label, "expect", expect, "got", got ; fail++ ; ENDIF label := "11b. Grade(85)" expect := "B" got := FrbDo(pMod, "GRADE", 85) IF got == expect ; ? "PASS", label, "=", got ; pass++ ; ELSE ; ? "FAIL", label, "expect", expect, "got", got ; fail++ ; ENDIF label := "11c. Grade(75)" expect := "C" got := FrbDo(pMod, "GRADE", 75) IF got == expect ; ? "PASS", label, "=", got ; pass++ ; ELSE ; ? "FAIL", label, "expect", expect, "got", got ; fail++ ; ENDIF label := "11d. Grade(65)" expect := "D" got := FrbDo(pMod, "GRADE", 65) IF got == expect ; ? "PASS", label, "=", got ; pass++ ; ELSE ; ? "FAIL", label, "expect", expect, "got", got ; fail++ ; ENDIF label := "11e. Grade(50)" expect := "F" got := FrbDo(pMod, "GRADE", 50) IF got == expect ; ? "PASS", label, "=", got ; pass++ ; ELSE ; ? "FAIL", label, "expect", expect, "got", got ; fail++ ; ENDIF FrbUnload(pMod) ? "" ? "================================================================" ? " pcode sweep:", pass, "passed,", fail, "failed" ? "================================================================" IF fail > 0 ? "FAIL summary" ENDIF RETURN