Interpreter Test Reference — Control Flow and Procedures
These tests verify control-flow statements and procedure semantics: loops and their boundary conditions, case, break, exit, parameter passing (by value and by reference), return values and their defaults, and the isolation rules that keep one call from corrupting another.
Control Flow
| Test |
What it verifies |
ControlFlowTests |
The core statements: if/then/else, begin..end blocks, while, repeat/until, for/to, for/downto, case/of/else, nested if with boolean operators, and exit with a value. |
CaseStatementComparisonTests |
case compares typed values like the = operator, not formatted text: Code labels match case-insensitively, and a Decimal 1.0 matches an integer-shaped label 1. (Audit spec.) |
CaseRangeAndMultiValueTests |
case labels support comma-separated value lists and inclusive .. ranges (1, 3..5, 9:), including Code ranges compared case-insensitively; single labels and else still work. |
ForLoopBoundaryTests |
A for loop with equal bounds (5 to 5, 5 downto 5) runs the body exactly once; empty ranges (3 to 1) run zero times. (Audit spec.) |
BreakStatementScopeTests |
break leaves the loop immediately and statements after it in the same block do not execute — verified for while, repeat, for, and foreach. (Audit spec.) |
WhileConditionSideEffectTests |
exit inside a while body leaves immediately without re-evaluating the condition; a normal loop evaluates the condition once per iteration plus once to terminate. (Audit spec.) |
Procedures and Parameters
| Test |
What it verifies |
ProcedureAndParameterTests |
Pass-by-value leaves the caller's variable unchanged; var parameters mutate it; procedures return each primitive type; and recursion works (fact(5) = 120). |
ProcedureReturnDefaultTests |
A procedure that ends without exit(...) returns the type default (0, empty, false), not the value a previous call left behind — even in an untyped context. (Audit spec.) |
ParameterSizeLeakTests |
A sized parameter or local (Code[5]) does not leak its length onto later size-less parameters and locals; the sized variable itself still enforces its length. (Audit spec.) |
VarParamWriteBackTests |
Writing a var parameter back into a sized caller variable (Text[3]) enforces the caller's maximum length (overflow), while fitting values write back correctly. (Audit spec.) |
ExitWithoutReturnTypeTests |
A bare exit; in a procedure with no return type leaves the procedure (unconditionally and conditionally) instead of raising an unknown-identifier error. (Audit spec.) |
OptionReturnTypeTests |
A procedure with an Option return type works and returns the ordinal, and returns 0 as its default when it ends without exit. (Audit spec.) |
ReturnValueAliasingTests |
Two procedure calls in one expression use separate return-value cells, so a second call falling off the end cannot overwrite the first call's result (Five() + Seven() = 12). (Audit spec.) |
ParenlessCallNativeMirrorTests |
The native parenless-call semantics: a parameterless call may omit () in expressions, as a statement, mid-chain, and on builtins, record/text/collection members, and user procedures; a parenless call still requires arguments where they are mandatory. Native-mirrored. |
ParenlessCallScriptTests |
Parameterless calls without () in scripts: collection members (d.Count, l.Reverse), as an assignment source and in chains (d.Keys.Count), text members (t.Trim), record members on a temporary record (t.Count, t.FindFirst, t.Delete), builtins (today) and user procedures; a variable shadows a same-named parameterless builtin; and parenless does not relax argument checking or silence unknown-member errors. |