Skip to content

✨ feat(lang): support array operands for shift operators (<<, >>)#1319

Merged
harehare merged 1 commit intomainfrom
feat/shift-operator-array-support
Feb 22, 2026
Merged

✨ feat(lang): support array operands for shift operators (<<, >>)#1319
harehare merged 1 commit intomainfrom
feat/shift-operator-array-support

Conversation

@harehare
Copy link
Copy Markdown
Owner

  • Allow [array] << value to append value to array
  • Allow value >> [array] to prepend value to array
  • Update docs and tests for new operator behavior

- Allow [array] << value to append value to array
- Allow value >> [array] to prepend value to array
- Update docs and tests for new operator behavior
Copilot AI review requested due to automatic review settings February 22, 2026 14:17
Copy link
Copy Markdown
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 adds support for using arrays as operands with shift operators (<< and >>), enabling convenient array manipulation. The feature allows [array] << value to append and value >> [array] to prepend, providing an intuitive syntax for common array operations.

Changes:

  • Added array operand support for shift operators, where << appends to arrays and >> prepends to arrays
  • Improved error handling to use Error::InvalidTypes instead of silently returning None for invalid operand combinations
  • Added basic test coverage and updated documentation tables

Reviewed changes

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

Show a summary per file
File Description
docs/books/src/reference/operators.md Updated operator reference tables to document array behavior for shift operators
crates/mq-lang/src/eval/builtin.rs Implemented array handling in SHIFT_LEFT and SHIFT_RIGHT builtins, improved error handling
crates/mq-lang/tests/integration_tests.rs Added basic integration tests for array shift operations
crates/mq-repl/src/repl.rs Fixed syntax highlighting pattern by removing non-existent -> operator
.github/codecov.yml Added editors/zed to coverage exclusions
Comments suppressed due to low confidence (1)

docs/books/src/reference/operators.md:101

  • The documentation should include examples demonstrating the new array behavior for shift operators, similar to the examples provided for numbers, strings, and Markdown headings. Consider adding examples like:
# Append to array with left shift
[1, 2, 3] << 4
# => [1, 2, 3, 4]

# Prepend to array with right shift
0 >> [1, 2, 3]
# => [0, 1, 2, 3]

This would help users understand the new functionality more clearly.

#### Examples

```mq
# Bitwise right shift on numbers
4 >> 2
# => 1

shift_right(8, 2)
# => 2

# Remove characters from the end of a string
shift_right("hello", 2)
# => "hel"

"hello" >> 2
# => "hel"

# Demote a heading (increase depth)
let md = do to_markdown("# Heading 1") | first(); |
md >> 1
# => ## Heading 1
</details>

#[case::shift_right_number("shift_right(4, 2)", vec![RuntimeValue::None], Ok(vec![RuntimeValue::Number(1.into())].into()),)]
#[case::shift_right_number_operator("4 >> 2", vec![RuntimeValue::None], Ok(vec![RuntimeValue::Number(1.into())].into()),)]
#[case::shift_left_array_operator("[1] << 2", vec![RuntimeValue::None], Ok(vec![vec![RuntimeValue::Number(1.into()), RuntimeValue::Number(2.into())].into()].into()),)]
#[case::shift_right_array_operator("2 >> [1]", vec![RuntimeValue::None], Ok(vec![vec![RuntimeValue::Number(2.into()), RuntimeValue::Number(1.into())].into()].into()),)]
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

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

Consider adding test cases for edge cases:

  1. Appending/prepending to an empty array: [] << 1 and 1 >> []
  2. Appending/prepending an array to an array: [1, 2] << [3, 4] and [3, 4] >> [1, 2]
  3. Appending/prepending None: [1] << . and . >> [1] with None input

These edge cases would help ensure the implementation handles all scenarios correctly.

Suggested change
#[case::shift_right_array_operator("2 >> [1]", vec![RuntimeValue::None], Ok(vec![vec![RuntimeValue::Number(2.into()), RuntimeValue::Number(1.into())].into()].into()),)]
#[case::shift_right_array_operator("2 >> [1]", vec![RuntimeValue::None], Ok(vec![vec![RuntimeValue::Number(2.into()), RuntimeValue::Number(1.into())].into()].into()),)]
#[case::shift_left_array_empty_operator("[] << 1",
vec![RuntimeValue::None],
Ok(vec![vec![
RuntimeValue::Number(1.into()),
].into()].into()),)]
#[case::shift_right_array_empty_operator("1 >> []",
vec![RuntimeValue::None],
Ok(vec![vec![
RuntimeValue::Number(1.into()),
].into()].into()),)]
#[case::shift_left_array_to_array_operator("[1, 2] << [3, 4]",
vec![RuntimeValue::None],
Ok(vec![vec![
RuntimeValue::Number(1.into()),
RuntimeValue::Number(2.into()),
RuntimeValue::Number(3.into()),
RuntimeValue::Number(4.into()),
].into()].into()),)]
#[case::shift_right_array_to_array_operator("[3, 4] >> [1, 2]",
vec![RuntimeValue::None],
Ok(vec![vec![
RuntimeValue::Number(3.into()),
RuntimeValue::Number(4.into()),
RuntimeValue::Number(1.into()),
RuntimeValue::Number(2.into()),
].into()].into()),)]
#[case::shift_left_array_none_operator("[1] << .",
vec![RuntimeValue::None],
Ok(vec![vec![
RuntimeValue::Number(1.into()),
RuntimeValue::None,
].into()].into()),)]
#[case::shift_right_array_none_operator(". >> [1]",
vec![RuntimeValue::None],
Ok(vec![vec![
RuntimeValue::None,
RuntimeValue::Number(1.into()),
].into()].into()),)]

Copilot uses AI. Check for mistakes.
constants::builtins::SHIFT_LEFT.to_string(),
vec![std::mem::take(a), std::mem::take(b)],
)),
_ => unreachable!(),
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

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

The change from returning RuntimeValue::NONE to Error::InvalidTypes for invalid type combinations is an improvement and makes the shift operators consistent with other builtin functions. However, this is a behavior change that could break existing code that relied on the previous silent failure behavior. Consider documenting this as a breaking change in the CHANGELOG if it hasn't been done already.

Suggested change
_ => unreachable!(),
_ => Err(Error::InvalidTypes(
constants::builtins::SHIFT_LEFT.to_string(),
Vec::new(),
)),

Copilot uses AI. Check for mistakes.
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Feb 22, 2026

Merging this PR will not alter performance

✅ 29 untouched benchmarks


Comparing feat/shift-operator-array-support (666af43) with main (5e13f22)

Open in CodSpeed

@harehare harehare merged commit 146a887 into main Feb 22, 2026
11 checks passed
@harehare harehare deleted the feat/shift-operator-array-support branch February 22, 2026 22: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.

2 participants