5.4.2.16 On...GoSub Statement
Note
This section describes the implementation of MS-VBAL §5.4.2.16 On...GoSub Statement.
Syntax
| AST node | Instruction kind | Notes |
|---|---|---|
| OnGoSubStatementNode | GoSubTable |
Lowering resolves the statement's labels into Instruction.Targets. |
An On expression GoSub label, ... statement is represented by OnGoSubStatementNode, and lowers to the
InstructionKind GoSubTable
(RD-VBAL §3.5.2 Instruction).
OnGoSubStatementNode holds its targets in a Labels list. Each target is an expression naming or numbering a
label or line, with no static link to the label node: the same convention as GoSub
(RD-VBAL §3.4.2 Simple Statements).
OnGoToStatementNode and
OnGoSubStatementNode are separate node types, rather than one shared node with a Kind.
Static Semantics
Lowering resolves each label in the list into Instruction.Targets
(RD-VBAL §3.5.3 Lowering Block Statements).
| Condition | Result |
|---|---|
| The procedure defines the label. | Its Targets entry is the label's offset. |
The procedure does not define the label, e.g. Missing in On n GoSub A, Missing. |
Lowering reports VBC09309 Label not defined for it. Each undefined label in the list is reported on its own. |
Runtime Semantics
GoSubTable performs the same selector algorithm as JumpTable
(RD-VBAL §5.4.2.13 On...GoTo Statement), and in addition pushes a
resumption point on a successful branch:
- The selector expression is evaluated once.
- The evaluated value is Let-coerced to
Integer. Let n be the coerced value. - If n is zero, or greater than the number of labels, execution falls through to the next instruction without branching.
- Otherwise, if n is negative or greater than 255, run-time error 5 is raised.
- Otherwise, the offset right after the
On…GoSubis pushed onto the activation's GoSub Resumption List, and execution branches to the n'th label (1-based) inInstruction.Targets.
The push in step 5 is the same push a bare GoSub performs
(RD-VBAL §5.4.2.14 GoSub Statement). A later Return pops it
(RD-VBAL §5.4.2.15 Return Statement).
| Condition | Run-time error |
|---|---|
| n is negative, or greater than 255 (step 4). | 5 — Invalid procedure call or argument |
A label with no statement after it, including the end-label of the lexically enclosing procedure declaration, resolves to the offset right past the last instruction. A branch to it completes the activation as if execution had reached the end of the procedure body (RD-VBAL §3.5.1 InstructionList).
Implementation
RDCore.Runtime.Execution.ProcedureExecutordispatchesGoSubTableinstructions, in the code path it shares withJumpTable.RDCore.Runtime.Execution.JumpTableEvaluatorevaluates the selector and Let-coerces it toInteger(steps 1 and 2), by callingVBNumericLetCoercionTypeRuntimeSemanticsdirectly, bypassing the let-coercion provider.- The push in step 5 goes through
CallStackFrame.PushGoSubReturn.
⏮️ RD-VBAL §5.4.2.15 Return Statement | ⏭️ RD-VBAL §5.4.2.17 Exit Sub Statement