lexer: add seven more unicode operators (#26074)

closes nim-lang/RFCs#571

Adds `⟑ ⟇ ⩓ ⩔ ■ □ ☆` with the same priority as `*`.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
Emmanuel M. Smith🔸
2026-08-05 16:12:17 +02:00
committed by GitHub
parent c69cf36610
commit 27763495bc
4 changed files with 44 additions and 5 deletions

View File

@@ -137,6 +137,11 @@ parameter and result types, not just their source-level shape. Use
See the [experimental manual](https://nim-lang.github.io/Nim/manual_experimental.html#typeminusbound-overloads)
for more information.
- Seven more Unicode characters are now parsed as operators, implementing the RFC
https://github.com/nim-lang/RFCs/issues/571: `⟑ ⟇ ⩓ ⩔ ■ □ ☆`. They all have the
same priority as `*` (multiplication). As with the other Unicode operators, Nim
only lexes them; their meaning is up to user code.
## Compiler changes
- Fixed a bug where `sizeof(T)` inside a `typedesc` template called from a generic type's

View File

@@ -845,8 +845,8 @@ proc getCharacter(L: var Lexer; tok: var Token) =
const
UnicodeOperatorStartChars = {'\226', '\194', '\195'}
# the allowed unicode characters ("∙ ∘ × ★ ⊗ ⊘ ⊙ ⊛ ⊠ ⊡ ∩ ∧ ⊓ ± ⊕ ⊖ ⊞ ⊟ ⊔")
# all start with one of these.
# the allowed unicode characters ("∙ ∘ × ⊗ ⊘ ⊙ ⊛ ⊠ ⊡ ∩ ∧ ⊓ ⟑ ⟇ ⩓ ⩔ ■ □
# ± ⊕ ⊖ ⊞ ⊟ ⊔") all start with one of these.
type
UnicodeOprPred = enum
@@ -878,7 +878,18 @@ proc unicodeOprLen(buf: cstring; pos: int): (int8, UnicodeOprPred) =
elif buf[pos+2] == '\159': result = 3.a # ⊟
elif buf[pos+2] == '\160': result = 3.m # ⊠
elif buf[pos+2] == '\161': result = 3.m # ⊡
elif buf[pos+1] == '\152' and buf[pos+2] == '\133': result = 3.m # ★
elif buf[pos+1] == '\150':
if buf[pos+2] == '\160': result = 3.m # ■
elif buf[pos+2] == '\161': result = 3.m # □
elif buf[pos+1] == '\152':
if buf[pos+2] == '\133': result = 3.m # ★
elif buf[pos+2] == '\134': result = 3.m # ☆
elif buf[pos+1] == '\159':
if buf[pos+2] == '\135': result = 3.m # ⟇
elif buf[pos+2] == '\145': result = 3.m # ⟑
elif buf[pos+1] == '\169':
if buf[pos+2] == '\147': result = 3.m # ⩓
elif buf[pos+2] == '\148': result = 3.m # ⩔
of '\194':
if buf[pos+1] == '\177': result = 2.a # ±
of '\195':

View File

@@ -712,8 +712,8 @@ Unicode Operators
These Unicode operators are also parsed as operators:
∙ ∘ × ★ ⊗ ⊘ ⊙ ⊛ ⊠ ⊡ ∩ ∧ ⊓ # same priority as * (multiplication)
± ⊕ ⊖ ⊞ ⊟ ⊔ # same priority as + (addition)
∙ ∘ × ⊗ ⊘ ⊙ ⊛ ⊠ ⊡ ∩ ∧ ⊓ ⟑ ⟇ ⩓ ⩔ ■ □ # same priority as * (multiplication)
± ⊕ ⊖ ⊞ ⊟ # same priority as + (addition)
Unicode operators can be combined with non-Unicode operator

View File

@@ -14,3 +14,26 @@ var y = 45
y *= 9 + 4 * 3
assert x == y
proc `⟑`(x, y: int): int = x * y
proc `⟇`(x, y: int): int = x * y
proc `⩓`(x, y: int): int = x * y
proc `⩔`(x, y: int): int = x * y
proc `■`(x, y: int): int = x * y
proc `□`(x, y: int): int = x * y
proc `☆`(x, y: int): int = x * y
proc `★`(x, y: int): int = x * y
assert 2 + 3 ⟑ 4 ⟇ 5 ⩓ 6 ⩔ 7 ■ 8 □ 9 ☆ 10 ★ 11 == 2 + 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11
proc `⟑=`(x: var int, y: int) = x *= y
proc `⩓++`(x, y: int): int = x * y
var z = 45
z ⟑= a⩓++4⟑3
var w = 45
w *= 9 * 4 * 3
assert z == w