Skip to content

Add GOTO and BREAK control statements to TP2 - #378

Draft
4Luke4 wants to merge 1 commit into
WeiDUorg:develfrom
4Luke4:agent/add-control-statements
Draft

Add GOTO and BREAK control statements to TP2#378
4Luke4 wants to merge 1 commit into
WeiDUorg:develfrom
4Luke4:agent/add-control-statements

Conversation

@4Luke4

@4Luke4 4Luke4 commented Aug 1, 2026

Copy link
Copy Markdown

Summary

This adds first-class GOTO, labels, and BREAK statements to both TP2 action and patch code.

OUTER_SET attempts = 0

::retry::
OUTER_SET attempts += 1

ACTION_IF attempts < 3 BEGIN
  GOTO retry
END

OUTER_WHILE 1 BEGIN
  BREAK
END

The scope model takes inspiration from Lua's control statements, while being adapted to WeiDU's action/patch execution model.

Syntax and semantics

  • ::label:: declares a label.
  • GOTO label resumes execution immediately after a visible label.
  • BREAK exits the innermost supported loop.
  • Labels are non-empty, case-sensitive literal names; they are not evaluated as variables.
  • Action and patch labels occupy separate namespaces.
  • A label is visible in its declaring list and nested same-domain structural lists.
  • A jump may leave a nested conditional or loop, but cannot jump into one.
  • Functions, macros, included files, opposite-domain embedded code, and separate-buffer patch bodies form control-flow boundaries.
  • ACTION_TRY and PATCH_TRY do not intercept control transfers.
  • Patch mutations are preserved when a patch GOTO or BREAK leaves a nested block.
  • BREAK exits the innermost:
    • action OUTER_WHILE, OUTER_FOR, ACTION_FOR_EACH, ACTION_PHP_EACH, or ACTION_BASH_FOR;
    • patch WHILE, FOR, PATCH_FOR_EACH, PATCH_PHP_EACH, or PATCH_BASH_FOR.
  • OUTER_FOR and FOR do not execute their increment lists after BREAK.

WeiDU validates the complete control-flow structure during parsing. It rejects:

  • undefined targets;
  • duplicate visible labels;
  • empty labels;
  • jumps into nested blocks;
  • cross-domain jumps;
  • jumps across macro/function/include boundaries;
  • BREAK outside a supported loop.

Diagnostics include the source filename, line, and column.

Implementation

  • Adds source-located action and patch AST nodes for labels, GOTO, and BREAK.
  • Introduces a dedicated static control-flow validator.
  • Uses cached label maps for constant-time target lookup.
  • Retains a fast path for lists without labels.
  • Uses an explicit program counter for stack-safe backward jumps.
  • Carries the current patch buffer through non-local patch control transfers.
  • Preserves scope and iteration-variable cleanup during transfers.
  • Keeps the size-constrained legacy parser unchanged by using WeiDU's existing fallback to the Elkhound grammar for the new productions.

Tests

A new make test-control-statements target covers:

  • forward and backward action and patch jumps;
  • jumps leaving nested loops;
  • patch-buffer preservation;
  • ACTION_TRY, PATCH_TRY, WITH_SCOPE, and PATCH_WITH_SCOPE;
  • all supported action and patch loop forms;
  • innermost-loop BREAK selection;
  • exact diagnostics for every invalid scope or target case.

A temporary branch-only workflow built the Linux executable using the repository's archived OCaml 4.08.1 unsafe-string toolchain, ran the complete regression suite, and generated the documentation successfully:

The repository's ordinary matrix on the same source tree also passed both macOS jobs. Its Windows job compiled the changed OCaml modules before reaching an unchanged src/reg.c Win32 API type error, while its ordinary Linux job stopped during provisioning because the configured non-archived OCaml switch was unavailable:

The disposable workflow was removed after validation and is not part of this pull request.

@4Luke4
4Luke4 marked this pull request as draft August 1, 2026 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant