Skip to content

Conversation

@harehare
Copy link
Owner

@harehare harehare commented Jan 1, 2026

Add support for do...end block syntax as an alternative to colon syntax
for while, foreach, and match constructs. Both syntaxes are now supported
simultaneously for backward compatibility.

Changes:

  • Modified CST parser to accept 'do' keyword before block bodies
  • Modified AST parser to handle do...end syntax
  • Added comprehensive integration tests for new syntax
  • All existing tests pass, ensuring backward compatibility

Examples:
while (x > 0) do x - 1 end
foreach(item, arr) do process(item) end
match (value) do | 1: "one" | 2: "two" end

Add support for do...end block syntax as an alternative to colon syntax
for while, foreach, and match constructs. Both syntaxes are now supported
simultaneously for backward compatibility.

Changes:
- Modified CST parser to accept 'do' keyword before block bodies
- Modified AST parser to handle do...end syntax
- Added comprehensive integration tests for new syntax
- All existing tests pass, ensuring backward compatibility

Examples:
  while (x > 0) do x - 1 end
  foreach(item, arr) do process(item) end
  match (value) do | 1: "one" | 2: "two" end
Copilot AI review requested due to automatic review settings January 1, 2026 14:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces do...end block syntax as an alternative to the existing colon syntax for while, foreach, and match constructs in the mq language. The implementation ensures backward compatibility by supporting both syntaxes simultaneously.

Key Changes

  • Modified CST and AST parsers to recognize and handle the do keyword before block bodies
  • Added comprehensive test coverage for the new syntax across all three affected constructs (while, foreach, match)
  • Ensured coexistence of both syntaxes through conditional parsing logic

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
crates/mq-lang/tests/integration_tests.rs Added integration tests verifying do...end syntax works correctly for while loops, foreach loops, and match expressions, including nested and control flow scenarios
crates/mq-lang/src/cst/parser.rs Updated CST parser to detect and consume do keyword as alternative to colon, added corresponding unit tests for new syntax structures
crates/mq-lang/src/ast/parser.rs Modified AST parser to handle do...end blocks in while, foreach, and match expressions, with unit tests confirming correct AST generation

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 1, 2026

CodSpeed Performance Report

Merging #1045 will not alter performance

Comparing feat/add-do-end-syntax (68bc447) with main (44a704e)1

Summary

✅ 29 untouched

Footnotes

  1. No successful run was found on main (65780e2) during the generation of this report, so 44a704e was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

harehare and others added 2 commits January 2, 2026 08:22
Add formatting support for do...end syntax in while, foreach, and match statements.
Includes proper spacing around the do keyword and comprehensive tests for various
scenarios (oneline, multiline, nested, with guards).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Consolidates duplicate code for formatting 'do' keyword spacing into
a new `format_do_with_spacing` helper method, improving maintainability
and reducing code duplication.
Copilot AI review requested due to automatic review settings January 2, 2026 01:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment on lines +384 to +390
// If there's no colon or do, split before the right parenthesis
let expr_index = if let Some(index) = do_index.or(colon_index) {
index
} else {
Self::find_token_position(node, |kind| matches!(kind, mq_lang::TokenKind::RParen))
.map(|index| index + 1)
.unwrap_or(0)
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The calculation of expr_index has changed significantly and may not match the original calculate_split_position logic. The removed code called self.calculate_split_position(node, 0) which likely had specific logic for determining split positions. The new implementation directly finds the RParen position, which could produce different behavior. Consider verifying that this simplified logic handles all edge cases that calculate_split_position was designed for.

Suggested change
// If there's no colon or do, split before the right parenthesis
let expr_index = if let Some(index) = do_index.or(colon_index) {
index
} else {
Self::find_token_position(node, |kind| matches!(kind, mq_lang::TokenKind::RParen))
.map(|index| index + 1)
.unwrap_or(0)
// If there's no colon or do, split before the right parenthesis.
// If no suitable token is found at all, default to the end of the children
// to avoid changing behavior by arbitrarily splitting at index 0.
let expr_index = if let Some(index) = do_index.or(colon_index) {
index
} else {
Self::find_token_position(node, |kind| matches!(kind, mq_lang::TokenKind::RParen))
.map(|index| index + 1)
.unwrap_or(node.children.len())

Copilot uses AI. Check for mistakes.

// Format match arms and end
let remaining_children: Vec<_> = node.children.iter().skip(colon_pos + 1).collect();
let remaining_children: Vec<_> = remaining_children.collect();
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The variable remaining_children is shadowing the iterator of the same name from line 833. This creates confusion as the name is reused for a collected vector. Consider renaming the collected vector to something like match_arms_and_end or remaining_nodes_vec to distinguish it from the iterator.

Copilot uses AI. Check for mistakes.
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.

2 participants