⏺ Phase 9 (TRACE) is complete. Here's a summary: #12
No reviewers
Labels
No labels
bug
dependencies
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
rust
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
navicore/patch-rexx!12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "phase9"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Changes Made
src/eval.rs
(function calls)
src/parser.rs
tests/phase9.rs (new)
Results
Code Review: Phase 9 (TRACE) Implementation
I've reviewed PR #12 implementing TRACE functionality for the REXX interpreter. Overall, the implementation is solid and well-tested. Here are my findings:
Critical Issues
1. Redundant
.or_else()inTraceSetting::parse()(src/eval.rs:96-97)The
.or_else(|| trimmed.strip_prefix('?'))is redundant — it does the same thing as the first.strip_prefix('?'). This doesn't cause incorrect behavior (both operations are identical), but it's unnecessary computation.Impact: Performance — duplicate work on every "?" prefixed trace setting.
2. TRACE toggle behavior differs between instruction and BIF (src/eval.rs:500-502 vs 688-689)
The
TRACE ?instruction andTRACE('?')function handle the "?" toggle correctly by checkings.trim() == "?"BEFORE callingTraceSetting::parse(). However,TraceSetting::parse("?")returns a sentinel value withinteractive: truerather than properly representing "toggle only" semantics. This works only because callers special-case the input before parsing.REXX semantics concern: The current implementation is correct but fragile. If future code calls
TraceSetting::parse("?")without the pre-check, it will set the trace level to Normal instead of just toggling interactive mode.Recommendation: Either document that
TraceSetting::parse("?")should never be called directly (callers must check first), or return a different type (e.g.,Option<ParsedTraceSetting>where the enum hasToggleandSet(TraceSetting)variants).3. Interactive pause may hang on stdin EOF without signal handling (src/eval.rs:540-541)
If
read_line()returnsOk(0)(EOF), the code will break correctly. However, theis_err()check silently swallows all I/O errors including legitimate failures. REXX interactive trace should typically exit cleanly on EOF but may want to distinguish between EOF and actual errors.Impact: Minor — interactive trace mode will exit on any I/O error, which is acceptable behavior. Not a correctness issue for normal use.
Design Observations (Not Issues)
4. TRACE() BIF implementation duplicated in two locations (src/eval.rs:684-702 and 1468-1485)
The TRACE() built-in function is handled specially in both:
exec_call()for CALL TRACE statementeval_expr()for TRACE() function calls in expressionsThe logic is intentionally duplicated (not shared via a helper) because one returns via
RESULTvariable and the other returns a value directly. This is correct REXX semantics but creates maintenance burden.Suggestion (optional): Extract the core toggle/parse logic into a helper method like:
Then call from both locations. Not critical — current duplication is acceptable for this small function.
5. Trace intermediates for all expression nodes
The implementation adds
trace_intermediates()calls ineval_expr()for every expression type (literals, variables, compounds, operators, function calls). This is correct per REXX semantics at trace level "Intermediates" but adds overhead to every expression evaluation even when tracing is off.The current implementation checks
self.trace_setting.level >= TraceLevel::Intermediatesinsidetrace_intermediates(), so the overhead is just a method call + comparison. This is acceptable, but note that trace instrumentation is always-on rather than conditionally compiled.Not an issue — just an observation. The performance impact is negligible for an interpreter.
Test Coverage ✅
The test suite is excellent:
Error Handling ✅
InvalidTrace) per ANSI X3.274-1996IncorrectCall) appropriatelyREXX Semantics ✅
?) prefix handled correctly*-*(source),>>>(result),>L>(literal),>V>(variable),>O>(operator), etc.Performance ✅
to_string()calls in trace paths are unavoidable (need to format output)eval_exprinstrumentation are lazy (only when tracing enabled)Safety ✅
MAX_INTERPRET_DEPTH)Summary
Approve with minor suggestions. The implementation is functionally correct, well-tested, and follows REXX semantics properly. The issues noted are:
None of these block merge. Consider addressing #1 and #2 in a follow-up if desired.
Tests: 403 tests pass (371 existing + 32 new) ✅
Clippy: Clean with
-D warnings✅REXX compliance: Correct per ANSI X3.274-1996 ✅
PR Review: Phase 9 (TRACE Implementation)
Reviewed the TRACE instruction implementation for correctness, REXX semantics, error handling, safety, and performance.
Critical Issues
1. Incorrect Tracing of Label Clauses (src/eval.rs:219-222)
Impact: Labels are traced twice when reached via SIGNAL
When a SIGNAL jumps to a label, the label is traced at line 221:
However, when execution continues from
idx + 1, the next clause might be traced again if it should be traced normally. This creates duplicate trace output.REXX Semantics: Labels reached via SIGNAL should only be traced once. The label clause itself should be traced when jumped to, and subsequent clauses traced according to normal rules.
Recommendation: The current logic traces the label at the jump point, which is correct. However, verify that execution continues correctly and labels aren't double-traced during normal sequential execution after a SIGNAL.
2. Trace Output During SIGNAL Handling (src/eval.rs:267-274)
Correctness Issue: Labels are always traced at Labels level or above, but this may be inconsistent
In
exec_clause_outer, the pre-execution trace logic is:This means a label will only be traced if encountered during sequential execution at Labels level or above. However, in the SIGNAL handling code (line 220-222), labels are traced at Labels level when jumped to. This creates an asymmetry: labels encountered sequentially vs. via SIGNAL have different trace behavior.
REXX Semantics: According to ANSI X3.274-1996, labels should be traced consistently regardless of how they're reached.
Recommendation: Verify REXX standard behavior for label tracing and ensure consistency.
3. Interactive Pause with Empty Input (src/eval.rs:547-550)
Safety Concern: Loop termination relies on empty line, but EOF handling is unclear
This breaks on either:
.is_err()) — good.is_empty()) — problematicIssue: If the user enters a blank line during interactive trace, the pause exits. However, REXX interactive trace traditionally requires explicit continuation. A blank line should typically be treated as a NOP, not as "exit interactive mode."
REXX Semantics: REXX interactive trace (? mode) typically requires explicit commands or continuation. Exiting on blank line may not match standard behavior.
Recommendation: Verify REXX standard behavior for interactive trace termination. Consider using a specific command (like an empty INTERPRET clause that does nothing) or requiring explicit trace mode changes.
4. Trace Interactive Pause Recursion (src/eval.rs:559)
Safety Concern: Deep recursion possible via nested INTERPRET
During interactive pause, the user can execute arbitrary REXX code, including:
INTERPRETstatements that trigger more interactive pausesWhile
exec_interpret_bodyhas depth limits for normal INTERPRET, the interactive pause could potentially create additional recursion vectors.Recommendation: Document or verify that
MAX_INTERPRET_DEPTHcovers interactive pause depth. Consider adding a guard against excessive interactive nesting if not already handled.5. CALL TRACE Argument Validation (src/eval.rs:691-702)
Inconsistency: Function call validation accepts 0 arguments, CALL statement doesn't specify
In the function call path (eval_expr, lines 1470-1477):
In the CALL statement path (exec_call, lines 691-702):
Issue: The error messages differ slightly:
While not critical, consistency in error messages aids user understanding.
Recommendation: Use consistent error messages between TRACE() BIF and CALL TRACE.
Minor Issues
6. Performance: Unnecessary Clone in TRACE Default (src/parser.rs:1146)
Issue: Creates a heap-allocated String for a single character on every
TRACEwithout arguments.Recommendation: Consider using a static string or interning single-character strings. However, this is minor given that TRACE instructions are relatively rare during execution.
7. Trace Output Format Line Numbers (src/eval.rs:537-540)
Question: The line number is right-justified to 6 characters. Is this sufficient for large REXX programs?
According to ANSI X3.274-1996, REXX programs can be arbitrarily long. While 6 characters supports up to 999,999 lines (ample for most programs), consider whether truncation or overflow should be handled.
Recommendation: This is likely fine for practical use. Document if there's a specific design decision here.
Positive Observations
✅ Error Handling: Correct error number (24) used for invalid TRACE settings
✅ Division by Zero: Existing arithmetic code correctly handles division by zero (lines 1569-1571, 1587-1589, 1602-1604)
✅ REXX Semantics: Case-insensitive trace level parsing correctly implemented
✅ Test Coverage: Comprehensive tests covering instruction, BIF, settings, output format, and integration scenarios
✅ Safety: No obvious panics on malformed input; errors properly propagated via Result types
✅ Trace Tags: Correct tag types for intermediates (>L>, >V>, >C>, >O>, >P>, >F>)
Summary
The implementation is solid with good test coverage. The critical issues identified are mostly semantic correctness concerns around:
These should be verified against REXX standard behavior. The other issues are minor and mostly involve consistency and edge case handling.
Recommendation: Verify label tracing and interactive pause behavior against the ANSI X3.274-1996 standard or a reference implementation (Regina, ooREXX). Otherwise, the implementation is ready to merge with minor refinements.
PR #12 TRACE Implementation Review
Summary
✅ APPROVED - Production-quality implementation with excellent architecture, proper REXX compliance, and comprehensive test coverage.
Detailed Analysis
1. Architecture - EXCELLENT
The TraceAction enum design (src/eval.rs:82-112) is exemplary - eliminates ambiguity between "toggle interactive" and "set level" operations. Parsing correctly handles empty strings, bare "?", "?", and "" with all paths using TraceLevel::parse() for consistency.
2. Error Handling - CORRECT ✓
Error 24 (RexxError::InvalidTrace) correctly used per ANSI X3.274-1996 §8.3.36. Test trace_invalid_errors confirms error 24 raised for invalid settings.
3. ANSI REXX Compliance - VERIFIED ✓
Trace level hierarchy correctly implemented - Labels and Commands are peer levels, traced at proper levels per spec. Output format matches ANSI exactly with proper line numbers and tags. TRACE() BIF behavior correct (returns previous setting, accepts 0-1 args, rejects 2+).
4. Edge Cases - ALL HANDLED ✓
Trace parsing handles empty strings, whitespace, mixed case, invalid values, and interactive toggles correctly. Interactive pause correctly interprets null lines, handles EOF/I/O errors, and uses existing INTERPRET machinery.
5. Safety - NO PANICS OR UNSAFE OPERATIONS ✓
All operations properly error-handled with RexxResult and ? propagation. No unsafe blocks, no unchecked indexing. Clippy clean with -D warnings.
6. Performance - EFFICIENT ✓
Minimal allocations (one string per apply_trace_setting call, only when executed). trace_intermediates() guards with matches!() before output. TraceLevel is Copy, TraceSetting only cloned when setting new values. No to_string() in hot paths.
7. Code Quality
Single apply_trace_setting() shared by TRACE instruction, CALL TRACE, and TRACE() BIF. All expression types consistently instrumented with appropriate tags (>L>, >V>, >C>, >O>, >P>, >F>).
8. Test Coverage - COMPREHENSIVE ✓
40 tests covering instruction execution, setting parsing, BIF behavior, output format, and integration scenarios. All tests pass.
Conclusion
NO ISSUES FOUND
Production-quality code with:
Recommendation: MERGE