Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 22, 2025

  • Use formatValue for Equal pattern value display (line 296)
  • Update RegExp pattern format to use /pattern/ syntax (line 302)
  • Move isPipeline to pattern.ts with type assertion (line 332)
  • Use @justinmchase/type for type checking in formatValue (lines 337-338)
  • Add support for Date, Symbol, and BigInt types (line 358)
  • Remove special case for objects with "kind" property (line 360)
  • Don't drill into successful (Ok) matches - only show failures
  • Consolidate input context with parse failed message at top
  • Show actual value found at rightmost failure point

Changes:

  • Removed redundant --- Input Context --- section
  • Added "Found: " line in the header next to parse failure position
  • Rightmost match now shows (found: <value>) inline to indicate what was actually encountered
  • This makes debugging clearer by showing both where the failure occurred and what value caused it
Original prompt

This section details on the original issue you should resolve

<issue_title>[debug]: Debugging expression lang failures</issue_title>
<issue_description>If you provide code to the epxression language which is an invalid program debugging what the failure is can be hard.

Please add an integration test to the expression lang which has an invalid expression (add 1 #) where the # represents an unexpected expression that the language cannot parse.

Visualizing the Failure

Please create a function visualizeMatchFailure(match: Match): string which emits a helpful human readable visualization for the failure intended to be printed to a console or to a file for debugging where only a text editor is available.

The structure of the match is very robust and can be circular. You will need to visualize these things:

  1. The hierarchical Pattern structure of the matches, using the names of the patterns
  2. The values matched, not matched, and the values expected
  3. Pipelines, which pipeline is failing, and the output of prior successful pipelines should be shown
  4. The final match failure should be tied back to a module and file path if possible

Expected

  1. The resulting match is a failure
  2. The visualization shows that the # specifically is where the match failed
  3. Matches for pipeline patterns are clearly denoted, in this case the expression step should be the one that is noted as the failure

</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #49


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI self-assigned this Oct 22, 2025
Copilot AI changed the title [WIP] Add integration test for debugging expression lang failures Add visualizeMatchFailure function for debugging expression language parse failures Oct 22, 2025
Copilot AI requested a review from justinmchase October 22, 2025 23:49
Copy link
Owner

@justinmchase justinmchase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Can you address the feedback?

Copy link
Contributor Author

Copilot AI commented Oct 23, 2025

@copilot Can you address the feedback?

All feedback addressed in commit 877cfeb:

  • Using formatValue for Equal pattern values
  • RegExp format updated to /pattern/ syntax
  • isPipeline moved to pattern.ts with type guard
  • formatValue now uses @justinmchase/type with switch statement
  • Added support for Date, Symbol, and BigInt types
  • Removed special case for objects with "kind" field

@justinmchase
Copy link
Owner

@copilot Your start of the output for the new EXPR_LANG_INVALID_00 test looks like this:

--- Match Tree ---
✗ Pipeline @ [0]
  ✗ [step 0] Expression @ [0]
    ✓ [0] Tokenizer → ["(", "add", " ", ... (7 items)]
      ✓ [0] Slice → ["(", "add", " ", ... (7 items)]
        ✓ [0] Slice → ["(", "add", " ", ... (7 items)]
          ✓ [0] Tokens → "("

The Tokenizer pattern is matching yet you are drilling into that matched pattern and generating a lot of output which doesn't contribute to the debugability of the failure.

Can you please change the code to not drill into matches that are Ok but to only drill into fail matches?

Copy link
Contributor Author

Copilot AI commented Oct 23, 2025

@copilot Your start of the output for the new EXPR_LANG_INVALID_00 test looks like this:

...

Done in 99ff0d1. The visualization now only drills into failed matches, not successful ones. Successful matches show their value but don't expand their children, significantly reducing output and focusing on the actual failure.

@justinmchase
Copy link
Owner

@copilot I've changed the visualizer function to emit output from the EXPR_LANG_INVALID_00 test to look like the below code block:

Visualized Match Failure:
Module: file:///home/justin/code/github.com/justinmchase/uffda/src/lang/expression/expression.lang.ts

🔴 Parse failed at position: [9].[5]

--- Match Stack ---
  at ExpressionLang@file:///home/justin/code/github.com/justinmchase/uffda/src/lang/expression/expression.lang.ts
  at Expression@file:///home/justin/code/github.com/justinmchase/uffda/src/lang/expression/expression.ts
  at Binary@file:///home/justin/code/github.com/justinmchase/uffda/src/lang/expression/binary.ts
  at Unary@file:///home/justin/code/github.com/justinmchase/uffda/src/lang/expression/unary.ts
  at Primary@file:///home/justin/code/github.com/justinmchase/uffda/src/lang/expression/primary.ts
  at Sequence@file:///home/justin/code/github.com/justinmchase/uffda/src/lang/expression/sequence.ts

--- Match Tree ---
✗ ExpressionLang
  ✓ Tokenizer → ["(", "add", " ", "1", " ", ... (2 items)]
  ✗ Expression
    ✗ Binary
      ✗ Unary
        ✗ Primary
          ✗ Sequence
            ✓ Equal("(") → "("
            ✓ Variable(p, Slice) → [{"kind":"reference","name":"add"}, {"kind":"number","value":1}]
         👉 ✗ Equal(")")

--- Input Context ---
Position: [9].[5]
value: "#"

Here are the changes from what you first created:

  1. I added a match stack which uses the m.scope.stack from the "right most match" to print the rules and modules from the error point
  2. I updated the match tree to...
  • Indentation is corrected
  • Only patterns tied to the root of a rule are printed
  • Or patterns which are ok
  • Or the right most match's pattern
  1. I removed the visualizations of the Path / Position for now, we will fix them in a followup PR.

Remaining

The last remaining tasks for you:

  1. Consolidate the --- Input Context --- section and the Parse failed at ... message at the top. I think that the input context section is redundant.
  2. Where the "right most" match is visualized in the tree, please show the actual value found which caused the equal pattern to not match.

Copy link
Contributor Author

Copilot AI commented Oct 23, 2025

@copilot I've changed the visualizer function to emit output from the EXPR_LANG_INVALID_00 test to look like the below code block:

...

Done in 3fd21cf. Changes made:

  1. Consolidated Input Context: Removed the redundant --- Input Context --- section and added "Found: " line in the header right after the parse failure position message.

  2. Show actual value at rightmost match: The rightmost failure now displays (found: <value>) inline, showing what was actually encountered that caused the pattern not to match.

Example output now shows:

🔴 Parse failed at position: [9].[5]
   Found: "#"

And in the tree:

👉 ✗ Equal(")") (found: "#")

@justinmchase justinmchase marked this pull request as ready for review October 23, 2025 13:04
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.

[debug]: Debugging expression lang failures

2 participants