Skip to content

exit program (as documented in the keyword reference) does not parse; bare exit is a silent no-op at top level #700

Description

@logbie

Summary

exit program — the form given in the keyword reference — does not parse. Bare exit parses but is a no-op at top level: the program keeps running and exits 0. Neither spelling produces the documented "exit program" behaviour.

Reproduction

Documented form:

display "before"
exit program
display "after"

Bare form:

display "before"
exit
display "after"

Command:

wfl d2_exit_program.wfl
wfl d2_exit_bare_noop.wfl

Expected

Both should print before and stop. Docs/reference/reserved-keywords.md:610
lists exit under Control Flow with the usage column reading exit program,
and Docs/reference/keyword-reference.md:32 describes it as
| exit | Exit program/loop | ✗ |.

Actual

exit program:

error[ANALYZE-SEMANTIC]: Variable 'program' is not defined

Exit code: 3. (program is parsed as an operand, not part of the statement.)

Bare exit:

before
after

Exit code: 0 — the statement is accepted and does nothing.

Inside a loop, bare exit behaves like break (leaves the innermost loop and
continues afterwards); that part is coherent, but it is the loop half of the
documented "Exit program/loop" and the program half has no working spelling.

The statement exists in the AST and is executed as a control-flow signal:

// src/parser/ast.rs:232
ExitStatement { line: usize, column: usize },

// src/interpreter/mod.rs:7842-7846
Statement::ExitStatement { .. } => {
    Ok((Value::Null, ControlFlow::Exit))
}

ControlFlow::Exit is honoured by the loop drivers but not at program top level,
so the documented program-termination behaviour is unreachable.

Environment

  • wfl --version: WebFirst Language (WFL) version 26.8.4
  • binary: system install C:\Program Files\wfl\bin\wfl.exe
  • commit: c277d8f
  • OS: Windows 11 Pro 10.0.26200
  • build: release

Also reproduces on the repo build (26.8.2) — not a regression.
No .wflcfg in scope.

Context

Found while porting G:/repos/JShrink/src/JShrink/Minifier.php (a 738-line PHP
JavaScript minifier) to WFL. The port's CLI needs an early exit on a missing
argument, which is what sent us to exit.

This was encountered, not blocking — the port instead prints a usage line and
forces a nonzero status (see the companion issue on raising a fatal error with a
custom message). No stub was left.

Either half is a valid fix and they are independent: make exit program parse and
terminate with status 0, or make bare exit terminate at top level — but the two
reference pages should agree with whichever ships, since today they document a form
that errors and a form that silently does nothing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions