Repository navigation
Implement executable format argument expressions #1234
Description
Parent: #1116
Follow-up to: #1229 and draft PR #1233
Problem
After the active-format/filehandle work, perl5_t/t/op/write.t reaches TAP 581/636. The next execution cluster requires format argument lines to run normal Perl expressions when write executes.
For example, these must supply the value for the preceding picture field at write time:
format HASH =
@<<<
${{qw[ Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6 ]}}{"Wed"}
.
write HASH;Current implementation has two connected gaps:
RuntimeFormat.evaluateExpression()only recognizes a small subset of global scalar access. Other AST types produce<unsupported_expr>.- JVM
EmitFormat.emitNodeList()serializes every non-StringNodeexpression as a placeholderStringNode; even a richer runtime evaluator would no longer have executable syntax. The interpreter retains parsed nodes, but still calls the same limited evaluator.
This also means expression evaluation does not yet correctly support lexical capture, package lookup, blocks, operators, method calls, tied or overloaded values, evaluation order, or ordinary Perl diagnostics.
Desired design
Keep each parsed argument expression executable in both backends, and attach its executable representation to the RuntimeFormat object. At write time, evaluate the expressions left-to-right in scalar context against the declaration's lexical/dynamic environment, then pass their results to the corresponding picture fields.
The implementation should use shared runtime/compiler machinery where possible rather than growing a second ad-hoc AST interpreter in RuntimeFormat.
Key constraints:
- Do not stringify or serialize away nontrivial AST nodes during JVM format emission.
- Preserve lexical variables captured by a format declared inside a sub or block.
- Resolve package globals in the correct package, rather than hard-coding
main. - Evaluate each argument exactly once and preserve side effects, lvalue semantics, tie dispatch, and overload behavior.
- Propagate Perl-level errors and warnings rather than rendering placeholders or silently substituting values.
- Keep JVM and bytecode-interpreter behavior identical.
^ fields, ^* consumption, and ~~ continuation rely on correct argument evaluation. Their formatting/continuation rules may warrant separately staged sub-work, but this issue must establish the executable-expression pipeline they depend on.
Regression coverage
Add focused project-owned tests (do not modify imported core tests), validated on system Perl first, covering at least:
- global and lexical variables in format argument lines;
- nested expressions such as anonymous hashes and blocks;
- left-to-right evaluation and exactly-once side effects;
- tied and overloaded argument values;
- runtime errors/warnings from an argument expression;
- a
^field and a~~continuation case once expression execution is available.
Require the focused tests to pass on the JVM backend and --interpreter, then run make. Use perl5_t/t/op/write.t as integration evidence: the HASH, HASH2, BLOCK, and format-argument pragmata cases immediately after TAP 581 are useful initial targets.
Non-goals
- Regressing the active-format association fixed in Fix active formats for write filehandles #1233.
- Replacing the existing picture-field formatting implementation wholesale unless necessary for the focused semantics above.
Activity
fglock commentedon Oct 26, 2026
Resolved by PR #1883, merged as 9ce6897. Format argument expressions now execute at write time on both backends, and Perl core op/write.t passes 636/636 assertions.