@ -11,9 +11,9 @@ const PREC = [
'colon_quote' ,
'colon_range' ,
'plus' ,
'bitshift' ,
'times' ,
'rational' ,
'bitshift' ,
'power' ,
'call' ,
'decl' ,
@ -25,6 +25,10 @@ const PREC = [
return result ;
} , { } ) ;
const ASSIGN _OPERATORS = `
= += -= *= /= / /= \ \ = ^= ÷ = %= <<= >>= >>>= |= &= ⊻ = ≔ ⩴ ≕
` ;
const ARROW _OPERATORS = `
← → ↔ ↚ ↛ ↞ ↠ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔ ⇴ ⇶
⇷ ⇸ ⇹ ⇺ ⇻ ⇼ ⇽ ⇾ ⇿ ⟵ ⟶ ⟷ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾
@ -35,10 +39,6 @@ const ARROW_OPERATORS = `
⇜ ⇝ ↜ ↝ ↩ ↪ ↫ ↬ ↼ ↽ ⇀ ⇁ ⇄ ⇆ ⇇ ⇉ ⇋ ⇌ ⇚ ⇛ ⇠ ⇢
` ;
const ASSIGN _OPERATORS = `
= += -= *= /= / /= | \ = | ^= ÷ = %= <<= >>= >>>= || = | &= ⊻ = ≔ ⩴ ≕
` ;
const COMPARISON _OPERATORS = `
> < >= ≥ <= ≤ == === ≡ != ≠ !== ≢ ∈ ∉ ∋ ∌ ⊆ ⊈ ⊂ ⊄ ⊊ ∝ ∊ ∍ ∥ ∦ ∷ ∺ ∻ ∽ ∾ ≁
≃ ≂ ≄ ≅ ≆ ≇ ≈ ≉ ≊ ≋ ≌ ≍ ≎ ≐ ≑ ≒ ≓ ≖ ≗ ≘ ≙ ≚ ≛ ≜ ≝ ≞ ≟ ≣ ≦ ≧ ≨ ≩ ≪ ≫ ≬ ≭
@ -51,8 +51,10 @@ const COMPARISON_OPERATORS = `
⫹ ⫺ ⊢ ⊣ ⟂
` ;
const DOTTY _OPERATORS = '… ⁝ ⋮ ⋱ ⋰ ⋯' ;
const PLUS _OPERATORS = `
+ - | \ || ⊕ ⊖ ⊞ ⊟ | ++ | ∪ ∨ ⊔ ± ∓ ∔ ∸ ≂ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⧺ ⧻ ⨈
+ - | ⊕ ⊖ ⊞ ⊟ ++ ∪ ∨ ⊔ ± ∓ ∔ ∸ ≂ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⧺ ⧻ ⨈
⨢ ⨣ ⨤ ⨥ ⨦ ⨧ ⨨ ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛ ⩝ ⩡ ⩢ ⩣
` ;
@ -63,6 +65,8 @@ const TIMES_OPERATORS = `
⩚ ⩜ ⩞ ⩟ ⩠ ⫛ ⊍ ▷ ⨝ ⟕ ⟖ ⟗
` ;
const BITSHIFT _OPERATORS = '<< >> >>>' ;
const POWER _OPERATORS = `
^ ↑ ↓ ⇵ ⟰ ⟱ ⤈ ⤉ ⤊ ⤋ ⤒ ⤓ ⥉ ⥌ ⥍ ⥏ ⥑ ⥔ ⥕ ⥘ ⥙ ⥜ ⥝ ⥠ ⥡ ⥣ ⥥ ⥮ ⥯ ↑ ↓
` ;
@ -414,11 +418,11 @@ grammar({
$ . interpolation _expression ,
$ . _primary _expression ,
$ . _literal ,
$ . operator ,
) ,
_primary _expression : $ => choice (
$ . identifier ,
$ . operator ,
$ . array _expression ,
$ . array _comprehension _expression ,
$ . matrix _expression ,
@ -436,7 +440,16 @@ grammar({
repeat1 ( prec ( - 1 , seq ( ',' , $ . _expression ) ) )
) ) ,
operator : $ => choice ( '+' , $ . _plus _operator , $ . _times _operator , $ . _power _operator ) ,
operator : $ => choice (
$ . _comparison _operator ,
$ . _dotty _operator ,
$ . _plus _operator ,
$ . _times _operator ,
$ . _rational _operator ,
$ . _bitshift _operator ,
$ . _power _operator ,
$ . _unary _operator ,
) ,
parenthesized _expression : $ => prec ( 1 , seq (
'(' , choice ( $ . _expression _list , $ . spread _expression ) , ')'
@ -483,7 +496,7 @@ grammar({
) ,
call _expression : $ => prec ( PREC . call , seq (
$. _primary _expression ,
choice( $. _primary _expression , $ . operator ) ,
$ . _immediate _paren ,
choice ( $ . argument _list , $ . generator _expression ) ,
optional ( $ . do _clause )
@ -540,7 +553,7 @@ grammar({
$ . _expression ,
$ . bare _tuple _expression
) ,
choice( $ . _assign _operator , '=' ) ,
alias( choice( $ . _assign _operator , '=' ) , $ . operator ) ,
choice (
$ . _expression ,
$ . assignment _expression ,
@ -550,62 +563,34 @@ grammar({
unary _expression : $ => choice (
prec ( PREC . prefix , seq (
choice ( '>:' , '+' , '-' , '!' , '~' , '¬' , '√' , '∛' , '∜' ) ,
$ . _expression
) ) ,
prec ( PREC . postfix , seq (
$ . _expression ,
choice ( "'" , ".'" )
) )
) ,
binary _expression : $ => choice (
prec . left ( PREC . power , seq (
$ . _expression ,
$ . _power _operator ,
$ . _expression
) ) ,
prec . left ( PREC . times , seq (
$ . _expression ,
$ . _times _operator ,
$ . _expression
) ) ,
prec . left ( PREC . plus , seq (
$ . _expression ,
choice ( '+' , $ . _plus _operator ) ,
$ . _expression
) ) ,
prec . right ( PREC . arrow , seq (
alias ( $ . _unary _operator , $ . operator ) ,
$ . _expression ,
$ . _arrow _operator ,
$ . _expression
) ) ,
prec . right ( PREC . pipe _left , seq (
$ . _expression ,
'<|' ,
$ . _expression
) ) ,
prec . left ( PREC . pipe _right , seq (
$ . _expression ,
'|>' ,
$ . _expression
) ) ,
prec . left ( PREC . comparison , seq (
$ . _expression ,
choice ( 'in' , 'isa' , $ . _comparison _operator ) ,
$ . _expression
) ) ,
prec . left ( PREC . lazy _or , seq (
prec ( PREC . postfix , seq ( $ . _expression , alias ( "'" , $ . operator ) ) ) ,
) ,
binary _expression : $ => {
const table = [
[ prec . left , PREC . power , $ . _power _operator ] ,
[ prec . left , PREC . rational , $ . _rational _operator ] ,
[ prec . left , PREC . bitshift , $ . _bitshift _operator ] ,
[ prec . left , PREC . times , $ . _times _operator ] ,
[ prec . left , PREC . plus , choice ( '+' , $ . _plus _operator ) ] ,
[ prec . left , PREC . colon _range , $ . _dotty _operator ] ,
[ prec . right , PREC . arrow , $ . _arrow _operator ] ,
[ prec . right , PREC . pipe _left , '<|' ] ,
[ prec . left , PREC . pipe _right , '|>' ] ,
[ prec . left , PREC . comparison , choice ( 'in' , 'isa' , $ . _comparison _operator ) ] ,
[ prec . left , PREC . lazy _or , '||' ] ,
[ prec . left , PREC . lazy _and , '&&' ] ,
] ;
return choice ( ... table . map ( ( [ fn , prec , op ] ) => fn ( prec , seq (
$ . _expression ,
'||' ,
$ . _expression
) ) ,
prec . left ( PREC . lazy _and , seq (
alias ( op , $ . operator ) ,
$ . _expression ,
'&&' ,
$ . _expression
) )
) ,
) ) ) ) ;
} ,
ternary _expression : $ => prec . right ( PREC . conditional , seq (
$ . _expression ,
@ -757,14 +742,15 @@ grammar({
'(' , ')' ,
'{' , '}' ,
'&' ,
'|' ,
'$' ,
ARROW _OPERATORS ,
ASSIGN _OPERATORS ,
ARROW _OPERATORS ,
COMPARISON _OPERATORS ,
DOTTY _OPERATORS ,
PLUS _OPERATORS ,
POWER _OPERATORS ,
TIMES _OPERATORS ,
BITSHIFT _OPERATORS ,
POWER _OPERATORS
] ;
const operatorCharacters = operators
@ -775,9 +761,9 @@ grammar({
. replace ( /\\/g , '\\\\' )
. replace ( /!/g , '' ) ;
// First char: ASCII letter, Greek letter, Extended Latin letter, or ∇
// Remaining characters: not delimiter, not operator
return new RegExp ( ` [_a-zA-ZͰ-ϿĀ-ſ∇][^"' \` \\ s \\ . \\ - \\ [ \\ ] ${ operatorCharacters } ]* ` )
const start = "[_\\p{L}\\p{Nl}∇]"
const rest = ` [^"' \` \\ s \\ . \\ - \\ [ \\ ] ${ operatorCharacters } ]* `
return new RegExp ( start + rest )
} ,
// Literals
@ -872,17 +858,23 @@ grammar({
) ,
) ,
_unary _operator : $ => token ( addDots ( '+ - ! ~ ¬ √ ∛ ∜' ) ) ,
_power _operator : $ => token ( addDots ( POWER _OPERATORS ) ) ,
_bitshift _operator : $ => token ( addDots ( BITSHIFT _OPERATORS ) ) ,
_rational _operator : $ => token ( addDots ( '//' ) ) ,
_times _operator : $ => token ( addDots ( TIMES _OPERATORS ) ) ,
_plus _operator : $ => token ( choice ( '$' , addDots ( PLUS _OPERATORS ) ) ) ,
_ arrow _operator : $ => token ( choice ( ' --', '-->' , addDots ( ARROW _OPERATORS ) ) ) ,
_ dotty _operator : $ => token ( choice ( ' ..', addDots ( DOTTY _OPERATORS ) ) ) ,
_comparison _operator : $ => token ( choice (
'|<:|' , '|>:|' , addDots ( COMPARISON _OPERATORS )
) ) ,
_comparison _operator : $ => token ( choice ( '<:' , '>:' , addDots ( COMPARISON _OPERATORS ) ) ) ,
_arrow _operator : $ => token ( choice ( '<--' , '-->' , '<-->' , addDots ( ARROW _OPERATORS ) ) ) ,
_assign _operator : $ => token ( choice ( ':=' , '~' , '$=' , addDots ( ASSIGN _OPERATORS ) ) ) ,