✨ feat(mq-lang): add =~ regex match operator and is_regex_match builtin#1305
✨ feat(mq-lang): add =~ regex match operator and is_regex_match builtin#1305
Conversation
- Add =~ as a binary operator for regex matching (maps to is_regex_match) - Implement is_regex_match builtin function - Update parser, CST, AST, lexer, and token definitions - Add tests and update syntax highlighting for all editors Closes #1274
There was a problem hiding this comment.
Pull request overview
This PR adds a regex match operator (=~) and the is_regex_match builtin function to the mq language, providing a more ergonomic way to perform regex matching compared to the previous test() function that required chaining regex_match() with !is_empty(). The operator maps to the is_regex_match builtin, which returns a boolean indicating whether a pattern matches a string.
Changes:
- Added
=~binary operator for regex matching (note: issue #1274 specified~=but implementation uses=~) - Implemented
is_regex_matchbuiltin function that returns boolean instead of an array of matches - Updated
test()function in builtin.mq to use the more efficientis_regex_matchdirectly - Updated syntax highlighting across all editors (VSCode, Neovim, Zed, Playground, REPL)
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/mq-lang/src/lexer/token.rs | Added TildeEqual token kind for the =~ operator |
| crates/mq-lang/src/lexer.rs | Added lexer parser for =~ token and included it in binary operators |
| crates/mq-lang/src/cst/node.rs | Added RegexMatch variant to BinaryOp enum |
| crates/mq-lang/src/cst/parser.rs | Mapped TildeEqual token to RegexMatch binary operation |
| crates/mq-lang/src/ast/parser.rs | Set operator precedence, mapped to builtin function, added to operator recognition |
| crates/mq-lang/src/ast/constants.rs | Added IS_REGEX_MATCH constant for the builtin function name |
| crates/mq-lang/src/eval/builtin.rs | Implemented IS_REGEX_MATCH builtin with hash constant, dispatch entry, and helper function |
| crates/mq-lang/builtin.mq | Simplified test() to use is_regex_match directly instead of regex_match + !is_empty() |
| crates/mq-lang/tests/integration_tests.rs | Added basic test case for the =~ operator |
| editors/vscode/syntaxes/mq.tmLanguage.json | Added =~ to VSCode syntax highlighting |
| editors/neovim/syntax/mq.vim | Added =~ to Neovim syntax highlighting |
| editors/zed/languages/mq/highlights.scm | Added =~ to Zed syntax highlighting |
| packages/mq-playground/src/Playground.tsx | Added =~ to Monaco editor syntax highlighting |
| crates/mq-repl/src/repl.rs | Added =~ to REPL syntax highlighting |
Co-authored-by: Copilot <[email protected]>
… arithmetic operators
|
@copilot |
Co-authored-by: harehare <[email protected]>
Co-authored-by: harehare <[email protected]>
✅ test(mq-lang): expand =~ operator and is_regex_match test coverage
assets/mq.sublime-syntax
Outdated
| - match: '\b(def|do|let|if|elif|else|end|while|foreach|self|nodes|match|fn|break|continue|include|import|module|var|macro|quote|unquote|loop)\b' | ||
| scope: keyword.control.mq | ||
| - match: '(->|=|\||:|;|\?|!|\+|\-|\*|/|%|<|>|<=|>=|==|!=|&&)' | ||
| - match: '(->|=|\||:|;|\?|!|\+|\-|\*|/|%|<|>|<=|>=|==|!=|&&|=~)' |
There was a problem hiding this comment.
The =~ operator is placed after the = operator in the alternation pattern. In regex alternations, patterns are tried left-to-right, so the single = will match before =~ gets a chance to be tested. This will cause =~ to be incorrectly highlighted as two separate operators (= and ~).
The =~ operator should be placed before the single = operator in the pattern to ensure it matches correctly. The corrected pattern should be:
'(->|=~|=|\||:|;|\?|!|\+|\-|\*|/|%|<|>|<=|>=|==|!=|&&)'
This ensures that two-character operators like =~, <=, >=, ==, != are matched before their single-character prefixes.
| - match: '(->|=|\||:|;|\?|!|\+|\-|\*|/|%|<|>|<=|>=|==|!=|&&|=~)' | |
| - match: '(->|=~|=|\||:|;|\?|!|\+|\-|\*|/|%|<|>|<=|>=|==|!=|&&)' |
crates/mq-lang/src/eval/builtin.rs
Outdated
| const HASH_IS_REGEX_MATCH: u64 = fnv1a_hash_64("is_regex_match"); | ||
| const HASH_IS_NAN: u64 = fnv1a_hash_64("is_nan"); |
There was a problem hiding this comment.
The hash constant HASH_IS_REGEX_MATCH is not in alphabetical order. According to the codebase convention (see memory about hash constants being in alphabetical order), hash constants should be ordered alphabetically by function name.
Currently:
- HASH_IS_DEBUG_MODE (is_debug_mode)
- HASH_IS_REGEX_MATCH (is_regex_match)
- HASH_IS_NAN (is_nan)
Alphabetically correct order should be:
- HASH_IS_DEBUG_MODE (is_debug_mode)
- HASH_IS_NAN (is_nan)
- HASH_IS_REGEX_MATCH (is_regex_match)
The constant should be moved to line 2445 (after HASH_IS_NAN).
| const HASH_IS_REGEX_MATCH: u64 = fnv1a_hash_64("is_regex_match"); | |
| const HASH_IS_NAN: u64 = fnv1a_hash_64("is_nan"); | |
| const HASH_IS_NAN: u64 = fnv1a_hash_64("is_nan"); | |
| const HASH_IS_REGEX_MATCH: u64 = fnv1a_hash_64("is_regex_match"); |
|
@copilot |
…sh constant ordering and sublime-syntax operator placement Co-authored-by: harehare <[email protected]>
Co-authored-by: harehare <[email protected]>
📝 docs(mq-lang): document =~ regex match operator; fix hash ordering and syntax highlighting
Closes #1274