diff --git a/DEV.md b/DEV.md
index efa20662..a59dd193 100644
--- a/DEV.md
+++ b/DEV.md
@@ -378,7 +378,7 @@ Rank tries `whole` before `each_pair`. `whole`, in order:
4. `pervasive_cells`: a pervasive primitive under nested Rank;
5. monadic operand: `cell_rule`, which also takes folds, atops and a bound left argument.
-- `primitive_cells` runs a primitive on the whole argument along the cells' axes. A form that `extends` runs whole at a cell rank at least its own. Other forms follow the `cells` fact (`CellRule`) in their `Primitive::info()` row: `⊖ , ↑ ↓ ⌷ #` and rotate-first call their axis forms; `⍉` sends each cell's axes after the frame's; `≢`, `ρ` give constants; a reshape keeping a cell's items in order is a view; `⊂` encloses each cell of rank 1 or more via its axis form, whose cells are views of the argument's items. Any other form with a left argument every cell shares takes `paired_cells`.
+- `primitive_cells` runs a primitive on the whole argument along the cells' axes. A form that `extends` runs whole at a cell rank at least its own. Other forms follow the `cells` fact (`CellRule`) in their `Primitive::info()` row: `, ↑ ↓ ⌷ #` call their axis forms; `⍉` sends each cell's axes after the frame's; `≢`, `ρ` give constants; a reshape keeping a cell's items in order is a view; `⊂` encloses each cell of rank 1 or more via its axis form, whose cells are views of the argument's items. Any other form with a left argument every cell shares takes `paired_cells`. `⌽₀` selects each cell's first axis through the shared Axis route.
- `paired_cells`: joins each pair of cells for `,` and `⍪`; calls a form that extends once where both cells are at least its ranks; first repeats an argument every cell shares over the frame (`agreement::spread`).
- `padded_call`, `paired_cells` leave an argument with a named frame axis to the per-cell path, which pairs frames by name (`named_frame`). Names on cell axes pair in whole calls as per-cell calls pair them.
- A pervasive primitive folds or scans a simple array along the cell's axis (`folded_cells`); `f/∘,` folds all cell axes at once. An atop applies its inner function's rule, then Rank for its outer function.
diff --git a/editors/jetbrains/BPL.tmbundle/Syntaxes/bpl.tmLanguage.json b/editors/jetbrains/BPL.tmbundle/Syntaxes/bpl.tmLanguage.json
index c8007243..298d8386 100644
--- a/editors/jetbrains/BPL.tmbundle/Syntaxes/bpl.tmLanguage.json
+++ b/editors/jetbrains/BPL.tmbundle/Syntaxes/bpl.tmLanguage.json
@@ -45,7 +45,7 @@
"name": "string.quoted.single.bpl"
},
{
- "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\\?¯∞⍬\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\\.⊗⌸⍣⇄⊘@∂⍚⌺/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
+ "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\\?¯∞⍬\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\\.⊗⌸⍣⇄⊘@∂⍚⌺/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
"name": "variable.other.bpl"
},
{
@@ -86,7 +86,7 @@
}
},
{
- "match": "[\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿]",
+ "match": "[\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿]",
"name": "support.function.bpl"
},
{
diff --git a/editors/jetbrains/BPL.tmbundle/Syntaxes/hpl.tmLanguage.json b/editors/jetbrains/BPL.tmbundle/Syntaxes/hpl.tmLanguage.json
index cf1fd6bf..51f0b64a 100644
--- a/editors/jetbrains/BPL.tmbundle/Syntaxes/hpl.tmLanguage.json
+++ b/editors/jetbrains/BPL.tmbundle/Syntaxes/hpl.tmLanguage.json
@@ -19,7 +19,7 @@
"applyEndPatternLast": true
},
{
- "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←是⎕出入•系α甲ω乙⍶丙⍹丁∇递遞⍢循⍝注◇句⁝隔\\?若¯负負∞永⍬空\\+加\\-减減×乘号號÷除⌈上⌊下\\|绝余絕餘\\*幂冪⊛对對○圆圓π周√根!阶拣階揀∧极且極∨析或⊼方否⊽双莫雙\\~非无無=等≠别初別<小≤限退>大≥达进達進ι位↦至:键卸鍵ρ形≢数异數異≡同深,连連⍪接矩⊂包⊃选合選⊆巢段∊属展屬∪并独併獨∩交重⍋升⍒降↑取↓去拆⌽转轉⊖纵縱⍉翻⊤编編⊥译譯⍎行⍕文⌷索⌹解逆\\#复複↕窗⍭素⨸因⌻零值⍸处间處間⍷寻群尋⊢右⊣左¿掷抽擲¨遍ᵇ按⍨己换換↣先⍤秩∘承⍠轴軸⍥经經↢后後\\.内內⊗表⌸组組⍣次止⇄优優⊘兼@于於∂导梯導⍚择擇⌺邻鄰/总總⌿汇匯\\\\累⍀续續⁻反⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
+ "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←是⎕出入•系α甲ω乙⍶丙⍹丁∇递遞⍢循⍝注◇句⁝隔\\?若¯负負∞永⍬空\\+加\\-减減×乘号號÷除⌈上⌊下\\|绝余絕餘\\*幂冪⊛对對○圆圓π周√根!阶拣階揀∧极且極∨析或⊼方否⊽双莫雙\\~非无無=等≠别初別<小≤限退>大≥达进達進ι位↦至:键卸鍵ρ形≢数异數異≡同深,连連⍪接矩⊂包⊃选合選⊆巢段∊属展屬∪并独併獨∩交重⍋升⍒降↑取↓去拆⌽转轉⍉翻⊤编編⊥译譯⍎行⍕文⌷索⌹解逆\\#复複↕窗⍭素⨸因⌻零值⍸处间處間⍷寻群尋⊢右⊣左¿掷抽擲¨遍ᵇ按⍨己换換↣先⍤秩∘承⍠轴軸⍥经經↢后後\\.内內⊗表⌸组組⍣次止⇄优優⊘兼@于於∂导梯導⍚择擇⌺邻鄰/总總⌿汇匯\\\\累⍀续續⁻反⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
"name": "variable.other.bpl"
},
{
@@ -35,7 +35,7 @@
"name": "constant.numeric.bpl"
},
{
- "match": "[加减減乘号號除上下绝余絕餘幂冪对對圆圓周根阶拣階揀极且極析或方否双莫雙非无無等别初別小限退大达进達進位至键卸鍵形数异數異同深连連接矩包选合選巢段属展屬并独併獨交重升降取去拆转轉纵縱翻编編译譯行文索解逆复複窗素因零值处间處間寻群尋右左掷抽擲]",
+ "match": "[加减減乘号號除上下绝余絕餘幂冪对對圆圓周根阶拣階揀极且極析或方否双莫雙非无無等别初別小限退大达进達進位至键卸鍵形数异數異同深连連接矩包选合選巢段属展屬并独併獨交重升降取去拆转轉翻编編译譯行文索解逆复複窗素因零值处间處間寻群尋右左掷抽擲]",
"name": "support.function.bpl"
},
{
diff --git a/editors/jetbrains/BPL.xml b/editors/jetbrains/BPL.xml
index 9416ebb6..848b519e 100644
--- a/editors/jetbrains/BPL.xml
+++ b/editors/jetbrains/BPL.xml
@@ -114,11 +114,6 @@
-
-
-
-
-
@@ -964,11 +959,6 @@
-
-
-
-
-
@@ -1034,11 +1024,6 @@
-
-
-
-
-
diff --git a/editors/vim/syntax/bpl.vim b/editors/vim/syntax/bpl.vim
index 746a7656..9c4728ab 100644
--- a/editors/vim/syntax/bpl.vim
+++ b/editors/vim/syntax/bpl.vim
@@ -2,10 +2,10 @@ if exists('b:current_syntax')
finish
endif
-syntax match bplName /\v%(_\d+|_\S|_|[^\s\x00-\x1f\x7f-\x9f0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\?¯∞⍬\+\-×÷⌈⌊\|\*⊛○π√!∧∨⊼⊽\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\.⊗⌸⍣⇄⊘@∂⍚⌺\/⌿\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\(\)\[\]\{\}'";\$_ₑⱼᵣ])+/
+syntax match bplName /\v%(_\d+|_\S|_|[^\s\x00-\x1f\x7f-\x9f0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\?¯∞⍬\+\-×÷⌈⌊\|\*⊛○π√!∧∨⊼⊽\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\.⊗⌸⍣⇄⊘@∂⍚⌺\/⌿\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\(\)\[\]\{\}'";\$_ₑⱼᵣ])+/
syntax match bplSystem /\v[•][A-Za-z_∆⍙][A-Za-z0-9_∆⍙]*/
syntax match bplString /\v\$[ad]/
-syntax match bplFunction /[+×÷⌈⌊|*⊛○π√!∧∨⊼⊽~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹#↕⍭⨸⌻⍸⍷⊢⊣¿-]/
+syntax match bplFunction /[+×÷⌈⌊|*⊛○π√!∧∨⊼⊽~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹#↕⍭⨸⌻⍸⍷⊢⊣¿-]/
syntax match bplMonadicOperator #\v%(ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)|[¨ᵇ⍨⊗⌸⇄∂/⌿\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ]#
syntax match bplDyadicOperator /[↣⍤∘⍠⍥↢.⍣⊘@⍚⌺]/
syntax match bplArgument /[αω⍶⍹∇⍢]/
diff --git a/editors/windows/layout.h b/editors/windows/layout.h
index 982c1695..704b5466 100644
--- a/editors/windows/layout.h
+++ b/editors/windows/layout.h
@@ -246,7 +246,6 @@ static DEADKEY deadkeys[] = {
DEADTRANS(0x22a3, 0x2395, 0x2360, 0),
DEADTRANS(0x205d, 0x2395, 0x2360, 0),
DEADTRANS(0x006f, 0x25cb, 0x25cb, 0),
- DEADTRANS(0x002d, 0x25cb, 0x2296, 0),
DEADTRANS(0x005c, 0x25cb, 0x2349, 0),
DEADTRANS(0x002f, 0x25cb, 0x2298, 0),
DEADTRANS(0x002a, 0x25cb, 0x229b, 0),
@@ -260,7 +259,6 @@ static DEADKEY deadkeys[] = {
DEADTRANS(0x25cb, 0x25cb, 0x25cb, 0),
DEADTRANS(0x221e, 0x25cb, 0x229b, 0),
DEADTRANS(0x2078, 0x25cb, 0x229b, 0),
- DEADTRANS(0x00af, 0x25cb, 0x2296, 0),
DEADTRANS(0x00f7, 0x25cb, 0x2a38, 0),
DEADTRANS(0x236d, 0x25cb, 0x2349, 0),
DEADTRANS(0x2229, 0x25cb, 0x235d, 0),
diff --git a/lib/array.bpl b/lib/array.bpl
index 6d595095..2e36e5ba 100644
--- a/lib/array.bpl
+++ b/lib/array.bpl
@@ -61,7 +61,7 @@ disp ← { α←⍬ ⍝ Boxed sketch of nested array.
sizes←⌈/rows ,⊗ ⌈⌿cols
ctd=0?sizes↑¨ω; ⍝ top-left alignment.
[v h]←sepr⌈0.5×⊃(ρ¨ω)-sizes
- v⊖¨h⌽¨sizes↑¨ω ⍝ centred aligned subarrays.
+ v⌽₀¨h⌽¨sizes↑¨ω ⍝ centred aligned subarrays.
}
gaps←{ ⍝ Gap-separated sub-planes.
α≤2ₓ?ω; ⍝ lowish rank: done.
diff --git a/lib/dyalog.bpl b/lib/dyalog.bpl
index 90547c36..6853f628 100644
--- a/lib/dyalog.bpl
+++ b/lib/dyalog.bpl
@@ -11,7 +11,7 @@ segs←{~ω∊α ⊆ ω} ⍝ Separator-delimited segments.
m_91←{ω>100ₓ?ω-10ₓ;∇ ∇ ω+11ₓ} ⍝ McCarthy's M91 function.
⍝ From https://dfns.dyalog.com/c_life.htm
-life←{[$t ω]∨.∧3ₓ 4ₓ=¨⊂+/,¯1 0 1⊖⊗¯1 0 1⌽⊗⊂ω}
+life←{[$t ω]∨.∧3ₓ 4ₓ=¨⊂+/,¯1 0 1⌽₀⊗¯1 0 1⌽⊗⊂ω}
⍝ From https://dfns.dyalog.com/c_rmcm.htm
rmcm←{ ⍝ Replace comments with blanks.
@@ -864,7 +864,7 @@ packH←{ ⍝ Huffman packing.
0ₓ=⍹?α(⍶ ci⌷⊢)ω;
1ₓ=⍹?⊃α(⍶¨⊂₀)ω;
¯1ₓ=⍹?⊃ α ⍶∘(1↣↓)¨⊂₀ ω;
- 2ₓ=⍹?α (⍶∘⊖⍢1)Under⊖ ω;
+ 2ₓ=⍹?α (⍶∘(⌽₀)⍢1)Under(⌽₀) ω;
¯2ₓ=⍹?α ⍶∘(¯1↣↓)⍢2 ω;
3ₓ=⍹?αtiω (⍶⍢0)⍤2 ∞ ω;
¯3ₓ=⍹?αtjω (⍶⍢0)⍤2 ∞ ω
diff --git a/lib/graph.bpl b/lib/graph.bpl
index cd7af69c..862de30a 100644
--- a/lib/graph.bpl
+++ b/lib/graph.bpl
@@ -292,7 +292,7 @@ queensX ← { ⍝ Exact cover N-Queens.
dm←-/¨ι2#ω ⍝ diagonals.
du←<∪,dm ⍝ unique diagonals.
x←dm =⊗ du
- y←⊖dm =⊗ du
+ y←⌽₀dm =⊗ du
m←,₀ ₁x,y,r,f ⍝ constraints matrix.
d←~ ι1↓ρm ∊ ι⊽ρdu ⍝ mask of required cols.
[ω ω]ρ d X m ⍝ exact cover - matrix of queens.
diff --git a/lib/numeric.bpl b/lib/numeric.bpl
index 34a2b1fd..957165ba 100644
--- a/lib/numeric.bpl
+++ b/lib/numeric.bpl
@@ -255,7 +255,7 @@ det ← { ⍝ Determinant of square matrix.
gauss_jordan ← { ⍝ Gauss-Jordan elimination.
elim←{ ⍝ elimination of row/col α
p←α+↑⍒|α↓[: α]⌷ω
- swap←⊖@[α p] ω ⍝ αth and pth rows exchanged
+ swap←⌽₀@[α p] ω ⍝ αth and pth rows exchanged
mat←swap.[α α]÷⍨@α swap ⍝ col diagonal reduced to 1
mat - mat.[: α]×α≠ι≢ω ×⊗ α⌷mat
}
diff --git a/lib/tree.bpl b/lib/tree.bpl
index e72a580b..ca0eb960 100644
--- a/lib/tree.bpl
+++ b/lib/tree.bpl
@@ -7,11 +7,11 @@
hang ← { ⍝ node label α with formatted subtrees ω hung below it.
key_val←α
null←0 0ρ"" ⍝ format of null tree.
- fmts←{⊖ω}\"┌└"{ ⍝ hang subtrees by ┌─ ─┐ branches.
+ fmts←{⌽₀ω}\"┌└"{ ⍝ hang subtrees by ┌─ ─┐ branches.
[0 0]ₓ≡ρω?ω; ⍝ null: done.
mask←∧\' '=↑↓⌽ωᵀ
⍉⌽⊃[⌽α,mask#'│'],↓⌽ωᵀ
- }¨{⊖ω}\ω ⍝ formatted subtrees.
+ }¨{⌽₀ω}\ω ⍝ formatted subtrees.
case←~[null null]≡¨fmts ⍝ non-null subtree cases.
join←⊥case ⊃ "∘┐┘┤"
join≡'∘'?⊃,↓key_val;
diff --git a/nbs/bpl.xml b/nbs/bpl.xml
index 406ab7be..8f71770d 100644
--- a/nbs/bpl.xml
+++ b/nbs/bpl.xml
@@ -7,14 +7,14 @@
-
+
-
+
diff --git a/nbs/evaluation.qmd b/nbs/evaluation.qmd
index 0892d6a1..67d02b86 100644
--- a/nbs/evaluation.qmd
+++ b/nbs/evaluation.qmd
@@ -122,7 +122,7 @@ m←[1 2 3◇4 5 6] ◇ [: 1]⌷m ⍝ 2 5
Some functions have a default axis:
- `/ \ ⌽ ,` work along the last axis.
-- `⌿ ⍀ ⊖ ⍪` work along the first axis.
+- `⌿ ⍀ ⍪` work along the first axis; `⌽₀` reverses or rotates it.
- Replicate `N#Y` and the partitions `N⊂Y` and `N⊆Y` work along the first axis.
- Encode `⊤` puts its digits on the last axis. Decode `⊥` reads them from the last axis.
diff --git a/nbs/gallery/reaction.bpl b/nbs/gallery/reaction.bpl
index 7c27a3ab..590f6ebf 100644
--- a/nbs/gallery/reaction.bpl
+++ b/nbs/gallery/reaction.bpl
@@ -6,7 +6,7 @@
n←250
⎕←"centres←",⍎⁻ centres←40+¿[≥¿4 2]ρ170
seed←∨⌿{8>|ω₀-ιn ∧⊗ 8>|ω₁-ιn}¹ centres
-lap←{1⌽ω + ¯1⌽ω + 1⊖ω + ¯1⊖ω - 4×ω}
+lap←{1⌽ω + ¯1⌽ω + 1⌽₀ω + ¯1⌽₀ω - 4×ω}
[feed kill]←0.0545 0.062
step←{
[a b]←ω
diff --git a/nbs/glyphs.qmd b/nbs/glyphs.qmd
index 192f01ee..d867a1a0 100644
--- a/nbs/glyphs.qmd
+++ b/nbs/glyphs.qmd
@@ -50,7 +50,6 @@ The names in these tables are the ones you type. In the REPL, a backtick and any
| `,` [comma](glyphs/comma.qmd) | | ravel | catenate | |
| `⍪` [comma-bar](glyphs/comma-bar.qmd) | Alt-Minus , | table | catenate-first | |
| `⌽` [circle-stile](glyphs/circle-stile.qmd) | Alt-2 | reverse | rotate | |
-| `⊖` [circle-bar](glyphs/circle-bar.qmd) | Alt-o Minus | reverse-first | rotate-first | |
| `⍉` [circle-backslash](glyphs/circle-backslash.qmd) | Alt-o Backslash | transpose | reorder-axes | |
| `↑` [up-arrow](glyphs/up-arrow.qmd) | Alt-k | first | take | Monad takes first major cell |
| `↓` [down-arrow](glyphs/down-arrow.qmd) | Alt-j | split | drop | |
@@ -158,6 +157,7 @@ System names start with `•`. [System functions](system-functions.qmd) lists th
- [Numbers](numbers.qmd): bare numbers are approximate. `ₓ` marks an exact integer, and `r` or `ᵣ` an exact rational, as in J: `1ᵣ÷3ᵣ` is `1ᵣ3`, while `1ₓ÷3ₓ` floors to `0ₓ`. Predicates, positions, tally and shape are exact. See [Mathish mode](numbers.qmd#mathish-mode) for comparison and zero-division conventions.
- [Agreement](evaluation.qmd#agreement-and-pervasion): pervasive functions, Each and Rank align leading axes. An axis of length 1 expands to match: `2 3ρι6 + 10 20` is `[10 11 12◇23 24 25]`.
- [Major cells](principles.ipynb#functions-act-on-major-cells): `∊ ~ ∪ ∩` compare major cells, `N#Y` replicates them, `N⊂Y` and `N⊆Y` split along the first axis. `⊤` and `⊥` put digits on the last axis, as J.
+- [Reverse and rotate](glyphs/circle-stile.qmd): `⌽₀` selects the first axis, replacing `⊖`; plain `⌽` selects the last. [Axis](glyphs/quad-colon.qmd) also extends data with trailing length-1 axes when a nonnegative axis does not yet exist.
- [System names](system-functions.qmd): written `•name`, as BQN, not `⎕NAME`. Most Dyalog system functions and variables are not included.
- [Axis keys](keyed.ipynb) name data. `K:Y` evaluates its keys. `T.a` is `"a"⊃T`. `T.(expr)` and `T⍎Y` evaluate with the keys of `T` as names.
- [Dfns](dfns.ipynb): BPL has dfns, with no tradfns and no colon control structures such as `:If`.
diff --git a/nbs/glyphs/circle-bar.qmd b/nbs/glyphs/circle-bar.qmd
deleted file mode 100644
index 56def98a..00000000
--- a/nbs/glyphs/circle-bar.qmd
+++ /dev/null
@@ -1,18 +0,0 @@
-# `⊖` — Reverse first / Rotate first
-
-Function. Keys: `Alt-o Minus`. Hanzi: `纵` (`縱`). Ranks: `∞` monadic, `∞ ∞` dyadic
-
-First-axis forms of [`⌽`](circle-stile.qmd). `⊖⍠K` overrides the axis.
-
-```bpl
-⊖2 3ρι6ₓ ⍝ [3 4 5◇0 1 2]ₓ
-1⊖3 2ρι6ₓ ⍝ [2 3◇4 5◇0 1]ₓ
-```
-
-## Inverse
-
-`⊖⁻Y` is `⊖Y`. `X⊖⁻Y` rotates `Y` back by `X`.
-
-```bpl
-1⊖⁻[3 4◇1 2] ⍝ [1 2◇3 4]
-```
diff --git a/nbs/glyphs/circle-stile.qmd b/nbs/glyphs/circle-stile.qmd
index 2825fbcf..d5f7f06c 100644
--- a/nbs/glyphs/circle-stile.qmd
+++ b/nbs/glyphs/circle-stile.qmd
@@ -2,7 +2,7 @@
Function. Keys: `Alt-2`. Hanzi: `转` (`轉`). Ranks: `1` monadic, `0 1` dyadic
-`⌽Y` reverses the last axis. `⌽⍠K` selects the axis.
+`⌽Y` reverses the last axis. [Axis](quad-colon.qmd) selects another: `⌽₀` reverses the first axis, and `⌽₋₁` selects the last. `⌽₀` replaces Dyalog's `⊖`.
```bpl
⌽1 2 3 ⍝ 3 2 1
@@ -16,7 +16,12 @@ Function. Keys: `Alt-2`. Hanzi: `转` (`轉`). Ranks: `1` monadic, `0 1` dyadic
¯1⌽"abcd" ⍝ "dabc"
```
-A count array supplies counts for the unrotated axes. See [`⊖`](circle-bar.qmd).
+A count array supplies counts for the unrotated axes: one count per column when rotating a matrix's first axis.
+
+```bpl
+1⌽₀3 2ρι6ₓ ⍝ [2 3◇4 5◇0 1]ₓ
+0 1 2⌽₀[1 2 3◇4 5 6◇7 8 9] ⍝ [1 5 9◇4 8 3◇7 2 6]
+```
## Inverse
diff --git a/nbs/glyphs/jot-diaeresis.qmd b/nbs/glyphs/jot-diaeresis.qmd
index e56e42c9..913f8bd2 100644
--- a/nbs/glyphs/jot-diaeresis.qmd
+++ b/nbs/glyphs/jot-diaeresis.qmd
@@ -57,7 +57,7 @@ Rank calls each of these functions once on the whole argument, with the same res
- a pervasive function, as in `m +⍤1 v`, where no frame axis has a name
- a fold or scan by a pervasive primitive on a simple array, as in `+/⍤1 m`, which runs as `+/m` does
- a monadic primitive at its own rank or above, such as `⌽⍤1 m`, except `ι`, `↦` and `⍎`
-- `⊖`, `,`, `↑`, `↓`, `⌷`, `⍉` and `#` along the cells' axes, `≢` and `ρ`, and a reshape that keeps each cell's items in order
+- `⌽₀`, `,`, `↑`, `↓`, `⌷`, `⍉` and `#` along the cells' axes, `≢` and `ρ`, and a reshape that keeps each cell's items in order
- dyadic `,` and `⍪`, joining each pair of cells, where the two arguments' frames match
- a dyadic primitive at its own ranks or above, where the two arguments' frames match, such as `v ⌽⍤0 1 m`, except `↦`, `:`, `⊂`, `⊃`, `⊆` and `⍕`
- `+.×`, `⌹`, `-.×` and [`•decompose`](../system/decompose.qmd) on a stack of matrices
diff --git a/nbs/glyphs/quad-colon.qmd b/nbs/glyphs/quad-colon.qmd
index 60a5ac8c..cf261ab5 100644
--- a/nbs/glyphs/quad-colon.qmd
+++ b/nbs/glyphs/quad-colon.qmd
@@ -12,6 +12,16 @@ ax←0 ◇ +/⍠ax m ⍝ [3 5 7]ₓ
Numeric [subscripts](../scripts.ipynb#subscripts) give literal axes: `+/₀` is `+/⍠0`, and `+/₁ ₂` is `+/⍠[1 2]`. Use `⍠` for names, computed axes and options records.
+`⌽₀` reverses the first axis; `⌽₋₁` reverses the last, as plain `⌽` does. A nonnegative axis beyond the data's rank adds trailing length-1 axes as views before applying the function. For example, axis 1 views a vector of shape `[2]` as `[2 1]`. The rule is shared by axis-aware functions, without copying the items:
+
+```bpl
+10 20 ,₁ 30 40 ⍝ [10 30◇20 40]
+2#₁10 20 ⍝ [10 10◇20 20]
+2↑₁10 20 ⍝ [10 0◇20 0]
+```
+
+Negative axes select existing axes from the end, not new axes. With two data arguments, existing mixed-rank agreement still applies when the selected axes exist in the higher-rank argument. Counts and selectors, such as `2` in `2#₁10 20`, keep their ordinary meaning. An atom has no axes, so selecting axis 0 first makes a length-1 vector.
+
Rank is the case that selects the last `r` axes. So `⍤1` and `⍠¯1` both select the last axis.
```bpl
@@ -60,7 +70,7 @@ A primitive with its own axis meaning keeps it:
- Multi-axis reduce, including seeded reduce. `+/⍠1 2` flattens each cell before reducing.
- Partitioned enclose and partition. `1 0 1 0⊂⍠1` and `1 1 2 2⊆⍠1` cut the whole matrix into blocks along axis 1. `⊂⍠K` matches Dyalog. Dyalog's `⊆[K]` partitions each lane instead, which is `{α⊆ω}⍠K` here.
- Rotate with a count array. `1 2 3 4⌽⍠0` pairs one count with each column.
-- Mix. `⊃⍠A` places the cell axes among the frame axes.
+- Mix. `⊃⍠A` places the assembled cell axes among the frame axes; it does not extend the nested input's axes.
- Axis selectors. `ι⍠A` returns the keys or positions of the selected axes.
```bpl
@@ -112,4 +122,4 @@ A call checks the fill when it starts, against each argument that it could fill,
## Errors
- `RANK`: an axis operand that is not a unit or vector
-- `DOMAIN`: axes that aren't whole, repeated axes, axes outside the higher-rank argument, an options record with a key other than `fill`, a function that fills no position, Windows or Stencil, or a fill that doesn't keep its value as the data's type
+- `DOMAIN`: axes that aren't whole, repeated axes, negative axes outside the higher-rank argument, an options record with a key other than `fill`, a function that fills no position, Windows or Stencil, or a fill that doesn't keep its value as the data's type
diff --git a/nbs/hpl.xml b/nbs/hpl.xml
index 36bca38e..c280b4cb 100644
--- a/nbs/hpl.xml
+++ b/nbs/hpl.xml
@@ -5,11 +5,11 @@
-
+
-
+
diff --git a/nbs/keyboard.qmd b/nbs/keyboard.qmd
index 8f0d0d5a..862ce998 100644
--- a/nbs/keyboard.qmd
+++ b/nbs/keyboard.qmd
@@ -24,7 +24,7 @@ Orange borders mark dead keys. You can hold or release Option between keys. Hold
| 6 | ⁶ | 0–9:⁰–⁹; -Space:⁻; -0–9:⁻⁰–⁻⁹; b:ᵇ; t:ᵀ; u:ᵘ |
| - | ¯ | ,:⍪; \:⍀; /:⌿; a:⍶; w:⍹; 7:⍙; `:⍚; 0:⊼; 9:⊽; e:⍷; i:⍸; z:⊆ |
| q | ⎕ | t:⌻; =:⌸; u:⌹; `:⌺; ;:⍠; \:⌷ |
-| o | ○ | -:⊖; \:⍉; /:⊘; m:⊗; u:⨸; 8:⊛; c:⍝; b:⍎; n:⍕ |
+| o | ○ | \:⍉; /:⊘; m:⊗; u:⨸; 8:⊛; c:⍝; b:⍎; n:⍕ |
| \ | ⍭ | 7:⍋; g:⍒ |
This is the US-based map used in the browser and REPL, and by the native BasedPL-us macOS layout. Regional macOS layouts preserve their native Option characters and move conflicting BPL shortcuts. See [macOS installation](#macos-installation).
diff --git a/nbs/llms.txt b/nbs/llms.txt
index 63f6d56d..3819d63f 100644
--- a/nbs/llms.txt
+++ b/nbs/llms.txt
@@ -42,7 +42,7 @@ Entry: Dyalog diff, example, defining page. Index, not reference: read a feature
- [`@`](glyphs/at.html.md) Under: `f@g`: `f` on `g`'s selection, written back (BQN `⌾`, not Dyalog `@`): `⌊@(10×)1.25 2.78`→`1.2 2.7`. positions/`[p]`: left arg aligns with right by position, by key if both keyed: `10 20 30 +@[0 2] 1 2 3`→`11 2 33`.
- [`∘`](glyphs/jot.html.md) atop: `α f∘g ω`≡`f α g ω` (BQN; Dyalog `α f g ω`): `10 -∘| ¯3`→`¯7`.
- [`⍤`](glyphs/jot-diaeresis.html.md) rank, only: `+/¹m` (`+/⍤1 m`) row sums. fn right operand computes ranks.
-- [`⍠`](glyphs/quad-colon.html.md) axis: along axes by number or name: `+/⍠0 m`, `+/⍠"month" sales`. options record sets fill: `5↑⍠["fill":¯1] 1 2`→`1 2 ¯1 ¯1 ¯1`.
+- [`⍠`](glyphs/quad-colon.html.md) axis: select cell axes by number or name: `+/₀m`, `+/⍠"month" sales`. Other axes form the frame; cells pair by leading agreement. Negative axes count from the end: `⌽₋₁`≡`⌽`, `⌽₀` reverses first (replaces `⊖`). A nonnegative axis beyond the data's rank adds trailing length-1 view axes: `10 20,₁30 40`→`[10 30◇20 40]`; `2#₁10 20`→`[10 10◇20 20]`. Negative axes select existing axes; existing mixed-rank agreement and count/selector arguments are unchanged. Mix `⊃⍠A` places assembled cell axes, not input axes. Options record sets fill: `5↑⍠["fill":¯1] 1 2`→`1 2 ¯1 ¯1 ¯1`.
- [`⌺`](glyphs/quad-diamond.html.md) stencil: Rank over centred windows: `f⌺3 v`≡`f⁻¹ [¯3]↕v`; `life⌺[3 3] g`≡`life⁻² [¯3 ¯3]↕g`. `f` gets each window alone, no `α` (J `;._3`). fn right operand computes window from args.
- [`.`](glyphs/dot.html.md) dot: after array: `.name` field, `.[I]` select. Standalone `.[I]` is a selector fn. `T.¨[I]`, `T.¹ ²[I]`, `T.⍤(1 2)[I]` modify that selector, then apply to `T`; `f.¨[I]` selects from `f`'s result. Named/grouped operator heads need a space: `T. op[I]`, `T. (op)[I]`. Tight `T.op[I]`/`T.(expr)[I]` keep field/scope meanings. First current-level bracket starts selectors; groups/dfns stay whole. Subject first, selectors once. Monadic `f.g`: J determinant: `-.×[1 2◇3 4]`→`¯2`.
- [`⍣`](glyphs/star-diaeresis.html.md) power: count list keeps history: `2×⍣(ι5) 1`→`1 2 4 8 16`. `f⍣∞` fixed point.
diff --git a/nbs/principles.ipynb b/nbs/principles.ipynb
index 172c581e..459badda 100644
--- a/nbs/principles.ipynb
+++ b/nbs/principles.ipynb
@@ -1014,7 +1014,7 @@
"id": "6fef7d3d",
"metadata": {},
"source": [
- "BPL follows BQN's leading-axis model. A function that works on a whole array acts on its major cells, the cells along its first axis. The last-axis glyphs `⌽ / \\ ,` are the leading-axis functions applied at rank 1. Their first-axis twins `⊖ ⌿ ⍀ ⍪` are the leading-axis functions themselves. Every function therefore treats a matrix by the same rule.\n",
+ "BPL follows BQN's leading-axis model. A function that works on a whole array acts on its major cells, the cells along its first axis. The last-axis glyphs `⌽ / \\ ,` are the leading-axis functions applied at rank 1. Their first-axis forms `⌽₀ ⌿ ⍀ ⍪` are the leading-axis functions themselves. Every function therefore treats a matrix by the same rule.\n",
"\n",
"Search follows that rule. `ι ∊ ~ ∪ ∩` compare the major cells of the searched argument, which for a matrix are its rows. Here `~` removes every row that is `1 2`, leaving a one-row matrix:"
]
diff --git a/nbs/study/01_basics.ipynb b/nbs/study/01_basics.ipynb
index afd3b874..1da87433 100644
--- a/nbs/study/01_basics.ipynb
+++ b/nbs/study/01_basics.ipynb
@@ -2618,7 +2618,7 @@
{
"data": {
"text/plain": [
- "3 5 0 5 5"
+ "4 2 1 5 0"
]
},
"metadata": {},
@@ -2638,7 +2638,7 @@
{
"data": {
"text/plain": [
- "0.5836406264 0.07477551829"
+ "0.2900967403 0.2565137201"
]
},
"metadata": {},
@@ -2674,7 +2674,7 @@
{
"data": {
"text/plain": [
- "13 45 28 18 9 42 39 44 35 23 16 49 32"
+ "32 18 51 25 1 46 29 44 49 3 41 2 23"
]
},
"metadata": {},
diff --git a/nbs/study/06_rearranging-arrays.ipynb b/nbs/study/06_rearranging-arrays.ipynb
index 36dabe47..293b1caf 100644
--- a/nbs/study/06_rearranging-arrays.ipynb
+++ b/nbs/study/06_rearranging-arrays.ipynb
@@ -328,7 +328,7 @@
"id": "7b284ee6",
"metadata": {},
"source": [
- "### `⊖` (Circle Bar)"
+ "### `⌽₀` (First-axis reverse and rotate)"
]
},
{
@@ -336,7 +336,7 @@
"id": "45a8f3e7",
"metadata": {},
"source": [
- "#### monadic `⊖` (Reverse First)"
+ "#### monadic `⌽₀` (Reverse First)"
]
},
{
@@ -344,7 +344,7 @@
"id": "857aa3ca",
"metadata": {},
"source": [
- "`⊖` acts along the first axis. A vector has only one axis, so `⌽` and `⊖` do the same thing there. On a matrix, `⊖` reverses or rotates the rows."
+ "The subscript selects an axis: `⌽₀` acts along the first, while `⌽₋₁` acts along the last, as plain `⌽` does. A vector has only one axis, so these give the same result there. On a matrix, `⌽₀` reverses or rotates the rows."
]
},
{
@@ -364,7 +364,7 @@
}
],
"source": [
- "⊖\"trams\""
+ "⌽₀\"trams\""
]
},
{
@@ -386,7 +386,7 @@
}
],
"source": [
- "⊖mat"
+ "⌽₀mat"
]
},
{
@@ -416,7 +416,7 @@
}
],
"source": [
- "⊖⁻⊖mat"
+ "⌽₀⁻⌽₀mat"
]
},
{
@@ -424,7 +424,7 @@
"id": "ae5a17ec",
"metadata": {},
"source": [
- "#### dyadic `⊖` (Rotate First)"
+ "#### dyadic `⌽₀` (Rotate First)"
]
},
{
@@ -444,7 +444,7 @@
}
],
"source": [
- "3⊖\"HatStand\""
+ "3⌽₀\"HatStand\""
]
},
{
@@ -466,7 +466,7 @@
}
],
"source": [
- "¯1⊖mat"
+ "¯1⌽₀mat"
]
},
{
@@ -496,7 +496,7 @@
}
],
"source": [
- "¯1⊖⁻¯1⊖mat"
+ "¯1⌽₀⁻¯1⌽₀mat"
]
},
{
diff --git a/python/basedpl/assets/macos/BasedPL-de.bundle/Contents/Resources/BasedPL-de.keylayout b/python/basedpl/assets/macos/BasedPL-de.bundle/Contents/Resources/BasedPL-de.keylayout
index b152bc69..86603424 100644
--- a/python/basedpl/assets/macos/BasedPL-de.bundle/Contents/Resources/BasedPL-de.keylayout
+++ b/python/basedpl/assets/macos/BasedPL-de.bundle/Contents/Resources/BasedPL-de.keylayout
@@ -1792,7 +1792,6 @@
-
@@ -1877,7 +1876,6 @@
-
@@ -2178,7 +2176,6 @@
-
@@ -2405,7 +2402,6 @@
-
@@ -2485,7 +2481,6 @@
-
@@ -2786,7 +2781,6 @@
-
@@ -3050,7 +3044,6 @@
-
@@ -3129,7 +3122,6 @@
-
@@ -3380,7 +3372,6 @@
-
@@ -3938,7 +3929,6 @@
-
@@ -4017,7 +4007,6 @@
-
@@ -4268,7 +4257,6 @@
-
diff --git a/python/basedpl/assets/macos/BasedPL-es.bundle/Contents/Resources/BasedPL-es.keylayout b/python/basedpl/assets/macos/BasedPL-es.bundle/Contents/Resources/BasedPL-es.keylayout
index 8785b093..fbf76e01 100644
--- a/python/basedpl/assets/macos/BasedPL-es.bundle/Contents/Resources/BasedPL-es.keylayout
+++ b/python/basedpl/assets/macos/BasedPL-es.bundle/Contents/Resources/BasedPL-es.keylayout
@@ -1786,7 +1786,6 @@
-
@@ -1871,7 +1870,6 @@
-
@@ -2173,7 +2171,6 @@
-
@@ -2394,7 +2391,6 @@
-
@@ -2474,7 +2470,6 @@
-
@@ -2776,7 +2771,6 @@
-
@@ -3036,7 +3030,6 @@
-
@@ -3115,7 +3108,6 @@
-
@@ -3380,7 +3372,6 @@
-
@@ -3943,7 +3934,6 @@
-
@@ -4027,7 +4017,6 @@
-
@@ -4281,7 +4270,6 @@
-
diff --git a/python/basedpl/assets/macos/BasedPL-fr.bundle/Contents/Resources/BasedPL-fr.keylayout b/python/basedpl/assets/macos/BasedPL-fr.bundle/Contents/Resources/BasedPL-fr.keylayout
index 388229dd..e8849b47 100644
--- a/python/basedpl/assets/macos/BasedPL-fr.bundle/Contents/Resources/BasedPL-fr.keylayout
+++ b/python/basedpl/assets/macos/BasedPL-fr.bundle/Contents/Resources/BasedPL-fr.keylayout
@@ -1678,7 +1678,6 @@
-
@@ -1850,7 +1849,6 @@
-
@@ -2181,7 +2179,6 @@
-
@@ -2316,7 +2313,6 @@
-
@@ -2468,7 +2464,6 @@
-
@@ -2799,7 +2794,6 @@
-
@@ -2972,7 +2966,6 @@
-
@@ -3125,7 +3118,6 @@
-
@@ -3403,7 +3395,6 @@
-
@@ -3879,7 +3870,6 @@
-
@@ -4037,7 +4027,6 @@
-
@@ -4320,7 +4309,6 @@
-
diff --git a/python/basedpl/assets/macos/BasedPL-uk.bundle/Contents/Resources/BasedPL-uk.keylayout b/python/basedpl/assets/macos/BasedPL-uk.bundle/Contents/Resources/BasedPL-uk.keylayout
index 9f7de751..9fafe5c1 100644
--- a/python/basedpl/assets/macos/BasedPL-uk.bundle/Contents/Resources/BasedPL-uk.keylayout
+++ b/python/basedpl/assets/macos/BasedPL-uk.bundle/Contents/Resources/BasedPL-uk.keylayout
@@ -1721,7 +1721,6 @@
-
@@ -1881,7 +1880,6 @@
-
@@ -2180,7 +2178,6 @@
-
@@ -2355,7 +2352,6 @@
-
@@ -2496,7 +2492,6 @@
-
@@ -2795,7 +2790,6 @@
-
@@ -3008,7 +3002,6 @@
-
@@ -3149,7 +3142,6 @@
-
@@ -3398,7 +3390,6 @@
-
@@ -3905,7 +3896,6 @@
-
@@ -4051,7 +4041,6 @@
-
@@ -4305,7 +4294,6 @@
-
diff --git a/python/basedpl/assets/macos/BasedPL-us.bundle/Contents/Resources/BasedPL-us.keylayout b/python/basedpl/assets/macos/BasedPL-us.bundle/Contents/Resources/BasedPL-us.keylayout
index 4d78cf5c..927004fb 100644
--- a/python/basedpl/assets/macos/BasedPL-us.bundle/Contents/Resources/BasedPL-us.keylayout
+++ b/python/basedpl/assets/macos/BasedPL-us.bundle/Contents/Resources/BasedPL-us.keylayout
@@ -1721,7 +1721,6 @@
-
@@ -1882,7 +1881,6 @@
-
@@ -2186,7 +2184,6 @@
-
@@ -2357,7 +2354,6 @@
-
@@ -2498,7 +2494,6 @@
-
@@ -2802,7 +2797,6 @@
-
@@ -3011,7 +3005,6 @@
-
@@ -3152,7 +3145,6 @@
-
@@ -3402,7 +3394,6 @@
-
@@ -3913,7 +3904,6 @@
-
@@ -4059,7 +4049,6 @@
-
@@ -4314,7 +4303,6 @@
-
diff --git a/python/basedpl/bpl.tmLanguage.json b/python/basedpl/bpl.tmLanguage.json
index c8007243..298d8386 100644
--- a/python/basedpl/bpl.tmLanguage.json
+++ b/python/basedpl/bpl.tmLanguage.json
@@ -45,7 +45,7 @@
"name": "string.quoted.single.bpl"
},
{
- "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\\?¯∞⍬\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\\.⊗⌸⍣⇄⊘@∂⍚⌺/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
+ "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\\?¯∞⍬\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\\.⊗⌸⍣⇄⊘@∂⍚⌺/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
"name": "variable.other.bpl"
},
{
@@ -86,7 +86,7 @@
}
},
{
- "match": "[\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿]",
+ "match": "[\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿]",
"name": "support.function.bpl"
},
{
diff --git a/python/basedpl/browser/language.js b/python/basedpl/browser/language.js
index 7bf7eec0..dfb3229f 100644
--- a/python/basedpl/browser/language.js
+++ b/python/basedpl/browser/language.js
@@ -1,3 +1,3 @@
// Generated by basedpl.editors.browser.
-export const grammar = {"name": "bpl", "displayName": "BPL", "scopeName": "source.bpl", "fileTypes": ["bpl"], "patterns": [{"begin": "[⍝]", "beginCaptures": {"0": {"name": "comment.line.bpl"}}, "end": "$", "contentName": "comment.line.bpl", "patterns": [], "applyEndPatternLast": true}, {"begin": "\"", "beginCaptures": {"0": {"name": "string.quoted.double.bpl"}}, "end": "\"|$", "contentName": "string.quoted.double.bpl", "patterns": [{"match": "\"\"", "name": "string.quoted.double.bpl"}], "applyEndPatternLast": true, "endCaptures": {"0": {"name": "string.quoted.double.bpl"}}}, {"match": "'.?'", "name": "string.quoted.single.bpl"}, {"match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\\?¯∞⍬\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\\.⊗⌸⍣⇄⊘@∂⍚⌺/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+", "name": "variable.other.bpl"}, {"match": "[•][A-Za-z_∆⍙][A-Za-z0-9_∆⍙]*", "name": "support.function.bpl"}, {"match": "(?:[¯]?[∞]|[¯]?(\\d+([.]\\d+)?|[.]\\d+)([eEₑ][¯]?\\d+)?([jJⱼ][¯]?(\\d+([.]\\d+)?|[.]\\d+)([eEₑ][¯]?\\d+)?|[rᵣ][¯]?\\d+)?)(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)?|[ₑⱼᵣ]", "name": "constant.numeric.bpl"}, {"match": "[⍬](?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)?", "name": "constant.numeric.bpl"}, {"match": "\\$[tfn]", "name": "constant.numeric.bpl"}, {"match": "\\$[ad]", "name": "string.quoted.double.bpl"}, {"begin": "[\\])](?=(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ))", "beginCaptures": {"0": {"name": "source.bpl"}}, "end": "(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)|$", "contentName": "constant.numeric.bpl", "patterns": [], "applyEndPatternLast": true, "endCaptures": {"0": {"name": "constant.numeric.bpl"}}}, {"match": "[\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⊖⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿]", "name": "support.function.bpl"}, {"match": "(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)", "name": "keyword.operator.monadic.bpl"}, {"match": "[¨ᵇ⍨⊗⌸⇄∂/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ]", "name": "keyword.operator.monadic.bpl"}, {"match": "[↣⍤∘⍠⍥↢\\.⍣⊘@⍚⌺]", "name": "keyword.operator.dyadic.bpl"}, {"match": "[αω⍶⍹∇⍢]", "name": "variable.parameter.bpl"}, {"match": "[←⎕◇⁝\\?₀₁₂₃₄₅₆₇₈₉₋]", "name": "keyword.control.bpl"}]};
-export const symbols = [{"glyph": "←", "name": "left-arrow", "kind": "syntax", "monad": "assign", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["是", "是"], "shortcut": " h"}, {"glyph": "⎕", "name": "quad", "kind": "syntax", "monad": "io", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["出入", "出入"], "shortcut": " q"}, {"glyph": "•", "name": "bullet", "kind": "system", "monad": "system", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["系", "系"], "shortcut": " y"}, {"glyph": "α", "name": "alpha", "kind": "argument", "monad": "left-argument", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["甲", "甲"], "shortcut": " a"}, {"glyph": "ω", "name": "omega", "kind": "argument", "monad": "right-argument", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["乙", "乙"], "shortcut": " w"}, {"glyph": "⍶", "name": "alpha-underbar", "kind": "argument", "monad": "left-operand", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["丙", "丙"], "shortcut": " - a"}, {"glyph": "⍹", "name": "omega-underbar", "kind": "argument", "monad": "right-operand", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["丁", "丁"], "shortcut": " - w"}, {"glyph": "∇", "name": "del", "kind": "argument", "monad": "recursion", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["递", "遞"], "shortcut": " g"}, {"glyph": "⍢", "name": "del-diaeresis", "kind": "argument", "monad": "operator-recursion", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["循", "循"], "shortcut": " 1 g"}, {"glyph": "⍝", "name": "lamp", "kind": "comment", "monad": "comment", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["注", "注"], "shortcut": " o c"}, {"glyph": "◇", "name": "diamond", "kind": "syntax", "monad": "separator", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["句", "句"], "shortcut": " `"}, {"glyph": "⁝", "name": "tricolon", "kind": "syntax", "monad": "token-separator", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["隔", "隔"], "shortcut": " :"}, {"glyph": "?", "name": "question", "kind": "syntax", "monad": "predicate", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["若", "若"], "shortcut": ""}, {"glyph": "¯", "name": "overbar", "kind": "literal", "monad": "negative", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["负", "負"], "shortcut": " -"}, {"glyph": "∞", "name": "infinity", "kind": "literal", "monad": "", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["永", "永"], "shortcut": " 8"}, {"glyph": "⍬", "name": "zilde", "kind": "literal", "monad": "empty", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["空", "空"], "shortcut": " )"}, {"glyph": "+", "name": "plus", "kind": "function", "monad": "conjugate", "dyad": "add", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["加", "加"], "shortcut": ""}, {"glyph": "-", "name": "minus", "kind": "function", "monad": "negate", "dyad": "subtract", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["减", "減"], "shortcut": ""}, {"glyph": "×", "name": "times", "kind": "function", "monad": "sign", "dyad": "multiply", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["乘号", "乘號"], "shortcut": " m"}, {"glyph": "÷", "name": "obelus", "kind": "function", "monad": "reciprocal", "dyad": "divide", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["除", "除"], "shortcut": " u"}, {"glyph": "⌈", "name": "upstile", "kind": "function", "monad": "ceiling", "dyad": "maximum", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["上", "上"], "shortcut": " s"}, {"glyph": "⌊", "name": "downstile", "kind": "function", "monad": "floor", "dyad": "minimum", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["下", "下"], "shortcut": " d"}, {"glyph": "|", "name": "stile", "kind": "function", "monad": "magnitude", "dyad": "residue", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["绝余", "絕餘"], "shortcut": ""}, {"glyph": "*", "name": "star", "kind": "function", "monad": "exponential", "dyad": "exponent", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["幂", "冪"], "shortcut": ""}, {"glyph": "⊛", "name": "circle-star", "kind": "function", "monad": "natural-log", "dyad": "logarithm", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["对", "對"], "shortcut": " o 8"}, {"glyph": "○", "name": "circle", "kind": "function", "monad": "cis", "dyad": "circular", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["圆", "圓"], "shortcut": " o"}, {"glyph": "π", "name": "pi", "kind": "function", "monad": "pi-times", "dyad": "pi-ratio", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["周", "周"], "shortcut": " p"}, {"glyph": "√", "name": "radical", "kind": "function", "monad": "sqrt", "dyad": "root", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["根", "根"], "shortcut": " 3"}, {"glyph": "!", "name": "exclamation", "kind": "function", "monad": "factorial", "dyad": "binomial", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["阶拣", "階揀"], "shortcut": ""}, {"glyph": "∧", "name": "wedge", "kind": "function", "monad": "polar", "dyad": "and", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["极且", "極且"], "shortcut": " 0"}, {"glyph": "∨", "name": "vee", "kind": "function", "monad": "real-imag", "dyad": "or", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["析或", "析或"], "shortcut": " 9"}, {"glyph": "⊼", "name": "wedge-bar", "kind": "function", "monad": "square", "dyad": "nand", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["方否", "方否"], "shortcut": " - 0"}, {"glyph": "⊽", "name": "vee-bar", "kind": "function", "monad": "double", "dyad": "nor", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["双莫", "雙莫"], "shortcut": " - 9"}, {"glyph": "~", "name": "tilde", "kind": "function", "monad": "not", "dyad": "without", "monad_rank": "0", "dyad_ranks": "∞ ∞", "hanzi": ["非无", "非無"], "shortcut": ""}, {"glyph": "=", "name": "equals", "kind": "function", "monad": "classify", "dyad": "equal", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["等", "等"], "shortcut": ""}, {"glyph": "≠", "name": "not-equals", "kind": "function", "monad": "unique-mask", "dyad": "not-equal", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["别初", "別初"], "shortcut": " +"}, {"glyph": "<", "name": "less-than", "kind": "function", "monad": "sort-up", "dyad": "less", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["小", "小"], "shortcut": ""}, {"glyph": "≤", "name": "less-than-or-equal", "kind": "function", "monad": "decrement", "dyad": "less-equal", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["限退", "限退"], "shortcut": " <"}, {"glyph": ">", "name": "greater-than", "kind": "function", "monad": "sort-down", "dyad": "greater", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["大", "大"], "shortcut": ""}, {"glyph": "≥", "name": "greater-than-or-equal", "kind": "function", "monad": "increment", "dyad": "greater-equal", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["达进", "達進"], "shortcut": " >"}, {"glyph": "ι", "name": "iota", "kind": "function", "monad": "indices", "dyad": "index-of", "monad_rank": "1", "dyad_ranks": "∞ ∞", "hanzi": ["位", "位"], "shortcut": " i"}, {"glyph": "↦", "name": "right-arrow-from-bar", "kind": "function", "monad": "range", "dyad": "to", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["至", "至"], "shortcut": " l"}, {"glyph": ":", "name": "colon", "kind": "function", "monad": "unkey", "dyad": "keyed", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["键卸", "鍵卸"], "shortcut": ""}, {"glyph": "ρ", "name": "rho", "kind": "function", "monad": "shape", "dyad": "reshape", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["形", "形"], "shortcut": " r"}, {"glyph": "≢", "name": "equal-underbar-slash", "kind": "function", "monad": "tally", "dyad": "not-match", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["数异", "數異"], "shortcut": " ?"}, {"glyph": "≡", "name": "equal-underbar", "kind": "function", "monad": "depth", "dyad": "match", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["同深", "同深"], "shortcut": " ="}, {"glyph": ",", "name": "comma", "kind": "function", "monad": "ravel", "dyad": "catenate", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["连", "連"], "shortcut": ""}, {"glyph": "⍪", "name": "comma-bar", "kind": "function", "monad": "table", "dyad": "catenate-first", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["接矩", "接矩"], "shortcut": " - ,"}, {"glyph": "⊂", "name": "left-shoe", "kind": "function", "monad": "enclose", "dyad": "partitioned-enclose", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["包", "包"], "shortcut": " z"}, {"glyph": "⊃", "name": "right-shoe", "kind": "function", "monad": "mix", "dyad": "pick", "monad_rank": "0", "dyad_ranks": "1 ∞", "hanzi": ["选合", "選合"], "shortcut": " x"}, {"glyph": "⊆", "name": "left-shoe-underbar", "kind": "function", "monad": "nest", "dyad": "partition", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["巢段", "巢段"], "shortcut": " - z"}, {"glyph": "∊", "name": "epsilon", "kind": "function", "monad": "enlist", "dyad": "member", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["属展", "屬展"], "shortcut": " e"}, {"glyph": "∪", "name": "down-shoe", "kind": "function", "monad": "unique", "dyad": "union", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["并独", "併獨"], "shortcut": " v"}, {"glyph": "∩", "name": "up-shoe", "kind": "function", "monad": "duplicates", "dyad": "intersection", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["交重", "交重"], "shortcut": " c"}, {"glyph": "⍋", "name": "delta-stile", "kind": "function", "monad": "grade-up", "dyad": "grade-up-by", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["升", "升"], "shortcut": " \\ 7"}, {"glyph": "⍒", "name": "del-stile", "kind": "function", "monad": "grade-down", "dyad": "grade-down-by", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["降", "降"], "shortcut": " \\ g"}, {"glyph": "↑", "name": "up-arrow", "kind": "function", "monad": "first", "dyad": "take", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["取", "取"], "shortcut": " k"}, {"glyph": "↓", "name": "down-arrow", "kind": "function", "monad": "split", "dyad": "drop", "monad_rank": "1", "dyad_ranks": "1 ∞", "hanzi": ["去拆", "去拆"], "shortcut": " j"}, {"glyph": "⌽", "name": "circle-stile", "kind": "function", "monad": "reverse", "dyad": "rotate", "monad_rank": "1", "dyad_ranks": "0 1", "hanzi": ["转", "轉"], "shortcut": " 2"}, {"glyph": "⊖", "name": "circle-bar", "kind": "function", "monad": "reverse-first", "dyad": "rotate-first", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["纵", "縱"], "shortcut": " o -"}, {"glyph": "⍉", "name": "circle-backslash", "kind": "function", "monad": "transpose", "dyad": "reorder-axes", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["翻", "翻"], "shortcut": " o \\"}, {"glyph": "⊤", "name": "down-tack", "kind": "function", "monad": "binary-encode", "dyad": "encode", "monad_rank": "∞", "dyad_ranks": "1 0", "hanzi": ["编", "編"], "shortcut": " n"}, {"glyph": "⊥", "name": "up-tack", "kind": "function", "monad": "binary-decode", "dyad": "decode", "monad_rank": "1", "dyad_ranks": "1 1", "hanzi": ["译", "譯"], "shortcut": " b"}, {"glyph": "⍎", "name": "hydrant", "kind": "function", "monad": "execute", "dyad": "execute-in", "monad_rank": "1", "dyad_ranks": "∞ ∞", "hanzi": ["行", "行"], "shortcut": " o b"}, {"glyph": "⍕", "name": "thorn", "kind": "function", "monad": "format", "dyad": "format-spec", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["文", "文"], "shortcut": " o n"}, {"glyph": "⌷", "name": "squad", "kind": "function", "monad": "materialise", "dyad": "index", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["索", "索"], "shortcut": " q \\"}, {"glyph": "⌹", "name": "domino", "kind": "function", "monad": "matrix-inverse", "dyad": "matrix-divide", "monad_rank": "2", "dyad_ranks": "∞ 2", "hanzi": ["解逆", "解逆"], "shortcut": " q u"}, {"glyph": "#", "name": "hash", "kind": "function", "monad": "runs", "dyad": "replicate", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["复", "複"], "shortcut": ""}, {"glyph": "↕", "name": "up-down-arrow", "kind": "function", "monad": "pairs", "dyad": "windows", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["窗", "窗"], "shortcut": " K"}, {"glyph": "⍭", "name": "stile-tilde", "kind": "function", "monad": "prime", "dyad": "prime-mode", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["素", "素"], "shortcut": " \\"}, {"glyph": "⨸", "name": "circle-divide", "kind": "function", "monad": "factors", "dyad": "factor-spec", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["因", "因"], "shortcut": " o u"}, {"glyph": "⌻", "name": "quad-jot", "kind": "function", "monad": "roots", "dyad": "polyval", "monad_rank": "1", "dyad_ranks": "1 0", "hanzi": ["零值", "零值"], "shortcut": " q t"}, {"glyph": "⍸", "name": "iota-underbar", "kind": "function", "monad": "where", "dyad": "interval-index", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["处间", "處間"], "shortcut": " - i"}, {"glyph": "⍷", "name": "epsilon-underbar", "kind": "function", "monad": "groups", "dyad": "find", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["寻群", "尋群"], "shortcut": " - e"}, {"glyph": "⊢", "name": "right-tack", "kind": "function", "monad": "same", "dyad": "right", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["右", "右"], "shortcut": " '"}, {"glyph": "⊣", "name": "left-tack", "kind": "function", "monad": "same-left", "dyad": "left", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["左", "左"], "shortcut": " ;"}, {"glyph": "¿", "name": "inverted-question", "kind": "function", "monad": "roll", "dyad": "deal", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["掷抽", "擲抽"], "shortcut": " /"}, {"glyph": "¨", "name": "diaeresis", "kind": "monadic-operator", "monad": "each", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["遍", "遍"], "shortcut": " 1"}, {"glyph": "ᵇ", "name": "superscript-b", "kind": "monadic-operator", "monad": "bitwise", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["按", "按"], "shortcut": " 6 b"}, {"glyph": "⍨", "name": "tilde-diaeresis", "kind": "monadic-operator", "monad": "self", "dyad": "commute", "monad_rank": "", "dyad_ranks": "", "hanzi": ["己换", "己換"], "shortcut": " 1 `"}, {"glyph": "↣", "name": "right-tail-arrow", "kind": "dyadic-operator", "monad": "before", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["先", "先"], "shortcut": " ."}, {"glyph": "⍤", "name": "jot-diaeresis", "kind": "dyadic-operator", "monad": "rank", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["秩", "秩"], "shortcut": " 1 t"}, {"glyph": "∘", "name": "jot", "kind": "dyadic-operator", "monad": "atop", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["承", "承"], "shortcut": " t"}, {"glyph": "⍠", "name": "quad-colon", "kind": "dyadic-operator", "monad": "axis", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["轴", "軸"], "shortcut": " q ;"}, {"glyph": "⍥", "name": "circle-diaeresis", "kind": "dyadic-operator", "monad": "over", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["经", "經"], "shortcut": " 1 o"}, {"glyph": "↢", "name": "left-tail-arrow", "kind": "dyadic-operator", "monad": "after", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["后", "後"], "shortcut": " ,"}, {"glyph": ".", "name": "dot", "kind": "dyadic-operator", "monad": "determinant", "dyad": "inner-product", "monad_rank": "", "dyad_ranks": "", "hanzi": ["内", "內"], "shortcut": ""}, {"glyph": "⊗", "name": "circle-times", "kind": "monadic-operator", "monad": "outer-product", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["表", "表"], "shortcut": " o m"}, {"glyph": "⌸", "name": "quad-equal", "kind": "monadic-operator", "monad": "key", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["组", "組"], "shortcut": " q ="}, {"glyph": "⍣", "name": "star-diaeresis", "kind": "dyadic-operator", "monad": "power", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["次止", "次止"], "shortcut": " 1 8"}, {"glyph": "⇄", "name": "right-left-arrows", "kind": "monadic-operator", "monad": "optimize", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["优", "優"], "shortcut": " 4"}, {"glyph": "⊘", "name": "circle-slash", "kind": "dyadic-operator", "monad": "valences", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["兼", "兼"], "shortcut": " o /"}, {"glyph": "@", "name": "at", "kind": "dyadic-operator", "monad": "under", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["于", "於"], "shortcut": ""}, {"glyph": "∂", "name": "partial", "kind": "monadic-operator", "monad": "derivative", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["导梯", "導梯"], "shortcut": " f"}, {"glyph": "⍚", "name": "diamond-underbar", "kind": "dyadic-operator", "monad": "agenda", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["择", "擇"], "shortcut": " - `"}, {"glyph": "⌺", "name": "quad-diamond", "kind": "dyadic-operator", "monad": "stencil", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["邻", "鄰"], "shortcut": " q `"}, {"glyph": "/", "name": "slash", "kind": "monadic-operator", "monad": "reduce", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["总", "總"], "shortcut": ""}, {"glyph": "⌿", "name": "slash-bar", "kind": "monadic-operator", "monad": "reduce-first", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["汇", "匯"], "shortcut": " - /"}, {"glyph": "\\", "name": "backslash", "kind": "monadic-operator", "monad": "scan", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["累", "累"], "shortcut": ""}, {"glyph": "⍀", "name": "backslash-bar", "kind": "monadic-operator", "monad": "scan-first", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["续", "續"], "shortcut": " - \\"}, {"glyph": "⁻", "name": "superscript-minus", "kind": "monadic-operator", "monad": "inverse", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["反", "反"], "shortcut": " _"}];
+export const grammar = {"name": "bpl", "displayName": "BPL", "scopeName": "source.bpl", "fileTypes": ["bpl"], "patterns": [{"begin": "[⍝]", "beginCaptures": {"0": {"name": "comment.line.bpl"}}, "end": "$", "contentName": "comment.line.bpl", "patterns": [], "applyEndPatternLast": true}, {"begin": "\"", "beginCaptures": {"0": {"name": "string.quoted.double.bpl"}}, "end": "\"|$", "contentName": "string.quoted.double.bpl", "patterns": [{"match": "\"\"", "name": "string.quoted.double.bpl"}], "applyEndPatternLast": true, "endCaptures": {"0": {"name": "string.quoted.double.bpl"}}}, {"match": "'.?'", "name": "string.quoted.single.bpl"}, {"match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←⎕•αω⍶⍹∇⍢⍝◇⁝\\?¯∞⍬\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿¨ᵇ⍨↣⍤∘⍠⍥↢\\.⊗⌸⍣⇄⊘@∂⍚⌺/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+", "name": "variable.other.bpl"}, {"match": "[•][A-Za-z_∆⍙][A-Za-z0-9_∆⍙]*", "name": "support.function.bpl"}, {"match": "(?:[¯]?[∞]|[¯]?(\\d+([.]\\d+)?|[.]\\d+)([eEₑ][¯]?\\d+)?([jJⱼ][¯]?(\\d+([.]\\d+)?|[.]\\d+)([eEₑ][¯]?\\d+)?|[rᵣ][¯]?\\d+)?)(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)?|[ₑⱼᵣ]", "name": "constant.numeric.bpl"}, {"match": "[⍬](?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)?", "name": "constant.numeric.bpl"}, {"match": "\\$[tfn]", "name": "constant.numeric.bpl"}, {"match": "\\$[ad]", "name": "string.quoted.double.bpl"}, {"begin": "[\\])](?=(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ))", "beginCaptures": {"0": {"name": "source.bpl"}}, "end": "(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)|$", "contentName": "constant.numeric.bpl", "patterns": [], "applyEndPatternLast": true, "endCaptures": {"0": {"name": "constant.numeric.bpl"}}}, {"match": "[\\+\\-×÷⌈⌊\\|\\*⊛○π√!∧∨⊼⊽\\~=≠<≤>≥ι↦:ρ≢≡,⍪⊂⊃⊆∊∪∩⍋⍒↑↓⌽⍉⊤⊥⍎⍕⌷⌹\\#↕⍭⨸⌻⍸⍷⊢⊣¿]", "name": "support.function.bpl"}, {"match": "(?:ₓ₁|ₓ₂|ₓ₄|ₓ₈|ₓ|ₕ|ₛ|ₚ|ₐ|ᵣ)", "name": "keyword.operator.monadic.bpl"}, {"match": "[¨ᵇ⍨⊗⌸⇄∂/⌿\\\\⍀⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ]", "name": "keyword.operator.monadic.bpl"}, {"match": "[↣⍤∘⍠⍥↢\\.⍣⊘@⍚⌺]", "name": "keyword.operator.dyadic.bpl"}, {"match": "[αω⍶⍹∇⍢]", "name": "variable.parameter.bpl"}, {"match": "[←⎕◇⁝\\?₀₁₂₃₄₅₆₇₈₉₋]", "name": "keyword.control.bpl"}]};
+export const symbols = [{"glyph": "←", "name": "left-arrow", "kind": "syntax", "monad": "assign", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["是", "是"], "shortcut": " h"}, {"glyph": "⎕", "name": "quad", "kind": "syntax", "monad": "io", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["出入", "出入"], "shortcut": " q"}, {"glyph": "•", "name": "bullet", "kind": "system", "monad": "system", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["系", "系"], "shortcut": " y"}, {"glyph": "α", "name": "alpha", "kind": "argument", "monad": "left-argument", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["甲", "甲"], "shortcut": " a"}, {"glyph": "ω", "name": "omega", "kind": "argument", "monad": "right-argument", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["乙", "乙"], "shortcut": " w"}, {"glyph": "⍶", "name": "alpha-underbar", "kind": "argument", "monad": "left-operand", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["丙", "丙"], "shortcut": " - a"}, {"glyph": "⍹", "name": "omega-underbar", "kind": "argument", "monad": "right-operand", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["丁", "丁"], "shortcut": " - w"}, {"glyph": "∇", "name": "del", "kind": "argument", "monad": "recursion", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["递", "遞"], "shortcut": " g"}, {"glyph": "⍢", "name": "del-diaeresis", "kind": "argument", "monad": "operator-recursion", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["循", "循"], "shortcut": " 1 g"}, {"glyph": "⍝", "name": "lamp", "kind": "comment", "monad": "comment", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["注", "注"], "shortcut": " o c"}, {"glyph": "◇", "name": "diamond", "kind": "syntax", "monad": "separator", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["句", "句"], "shortcut": " `"}, {"glyph": "⁝", "name": "tricolon", "kind": "syntax", "monad": "token-separator", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["隔", "隔"], "shortcut": " :"}, {"glyph": "?", "name": "question", "kind": "syntax", "monad": "predicate", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["若", "若"], "shortcut": ""}, {"glyph": "¯", "name": "overbar", "kind": "literal", "monad": "negative", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["负", "負"], "shortcut": " -"}, {"glyph": "∞", "name": "infinity", "kind": "literal", "monad": "", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["永", "永"], "shortcut": " 8"}, {"glyph": "⍬", "name": "zilde", "kind": "literal", "monad": "empty", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["空", "空"], "shortcut": " )"}, {"glyph": "+", "name": "plus", "kind": "function", "monad": "conjugate", "dyad": "add", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["加", "加"], "shortcut": ""}, {"glyph": "-", "name": "minus", "kind": "function", "monad": "negate", "dyad": "subtract", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["减", "減"], "shortcut": ""}, {"glyph": "×", "name": "times", "kind": "function", "monad": "sign", "dyad": "multiply", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["乘号", "乘號"], "shortcut": " m"}, {"glyph": "÷", "name": "obelus", "kind": "function", "monad": "reciprocal", "dyad": "divide", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["除", "除"], "shortcut": " u"}, {"glyph": "⌈", "name": "upstile", "kind": "function", "monad": "ceiling", "dyad": "maximum", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["上", "上"], "shortcut": " s"}, {"glyph": "⌊", "name": "downstile", "kind": "function", "monad": "floor", "dyad": "minimum", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["下", "下"], "shortcut": " d"}, {"glyph": "|", "name": "stile", "kind": "function", "monad": "magnitude", "dyad": "residue", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["绝余", "絕餘"], "shortcut": ""}, {"glyph": "*", "name": "star", "kind": "function", "monad": "exponential", "dyad": "exponent", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["幂", "冪"], "shortcut": ""}, {"glyph": "⊛", "name": "circle-star", "kind": "function", "monad": "natural-log", "dyad": "logarithm", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["对", "對"], "shortcut": " o 8"}, {"glyph": "○", "name": "circle", "kind": "function", "monad": "cis", "dyad": "circular", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["圆", "圓"], "shortcut": " o"}, {"glyph": "π", "name": "pi", "kind": "function", "monad": "pi-times", "dyad": "pi-ratio", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["周", "周"], "shortcut": " p"}, {"glyph": "√", "name": "radical", "kind": "function", "monad": "sqrt", "dyad": "root", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["根", "根"], "shortcut": " 3"}, {"glyph": "!", "name": "exclamation", "kind": "function", "monad": "factorial", "dyad": "binomial", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["阶拣", "階揀"], "shortcut": ""}, {"glyph": "∧", "name": "wedge", "kind": "function", "monad": "polar", "dyad": "and", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["极且", "極且"], "shortcut": " 0"}, {"glyph": "∨", "name": "vee", "kind": "function", "monad": "real-imag", "dyad": "or", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["析或", "析或"], "shortcut": " 9"}, {"glyph": "⊼", "name": "wedge-bar", "kind": "function", "monad": "square", "dyad": "nand", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["方否", "方否"], "shortcut": " - 0"}, {"glyph": "⊽", "name": "vee-bar", "kind": "function", "monad": "double", "dyad": "nor", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["双莫", "雙莫"], "shortcut": " - 9"}, {"glyph": "~", "name": "tilde", "kind": "function", "monad": "not", "dyad": "without", "monad_rank": "0", "dyad_ranks": "∞ ∞", "hanzi": ["非无", "非無"], "shortcut": ""}, {"glyph": "=", "name": "equals", "kind": "function", "monad": "classify", "dyad": "equal", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["等", "等"], "shortcut": ""}, {"glyph": "≠", "name": "not-equals", "kind": "function", "monad": "unique-mask", "dyad": "not-equal", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["别初", "別初"], "shortcut": " +"}, {"glyph": "<", "name": "less-than", "kind": "function", "monad": "sort-up", "dyad": "less", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["小", "小"], "shortcut": ""}, {"glyph": "≤", "name": "less-than-or-equal", "kind": "function", "monad": "decrement", "dyad": "less-equal", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["限退", "限退"], "shortcut": " <"}, {"glyph": ">", "name": "greater-than", "kind": "function", "monad": "sort-down", "dyad": "greater", "monad_rank": "∞", "dyad_ranks": "0 0", "hanzi": ["大", "大"], "shortcut": ""}, {"glyph": "≥", "name": "greater-than-or-equal", "kind": "function", "monad": "increment", "dyad": "greater-equal", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["达进", "達進"], "shortcut": " >"}, {"glyph": "ι", "name": "iota", "kind": "function", "monad": "indices", "dyad": "index-of", "monad_rank": "1", "dyad_ranks": "∞ ∞", "hanzi": ["位", "位"], "shortcut": " i"}, {"glyph": "↦", "name": "right-arrow-from-bar", "kind": "function", "monad": "range", "dyad": "to", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["至", "至"], "shortcut": " l"}, {"glyph": ":", "name": "colon", "kind": "function", "monad": "unkey", "dyad": "keyed", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["键卸", "鍵卸"], "shortcut": ""}, {"glyph": "ρ", "name": "rho", "kind": "function", "monad": "shape", "dyad": "reshape", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["形", "形"], "shortcut": " r"}, {"glyph": "≢", "name": "equal-underbar-slash", "kind": "function", "monad": "tally", "dyad": "not-match", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["数异", "數異"], "shortcut": " ?"}, {"glyph": "≡", "name": "equal-underbar", "kind": "function", "monad": "depth", "dyad": "match", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["同深", "同深"], "shortcut": " ="}, {"glyph": ",", "name": "comma", "kind": "function", "monad": "ravel", "dyad": "catenate", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["连", "連"], "shortcut": ""}, {"glyph": "⍪", "name": "comma-bar", "kind": "function", "monad": "table", "dyad": "catenate-first", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["接矩", "接矩"], "shortcut": " - ,"}, {"glyph": "⊂", "name": "left-shoe", "kind": "function", "monad": "enclose", "dyad": "partitioned-enclose", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["包", "包"], "shortcut": " z"}, {"glyph": "⊃", "name": "right-shoe", "kind": "function", "monad": "mix", "dyad": "pick", "monad_rank": "0", "dyad_ranks": "1 ∞", "hanzi": ["选合", "選合"], "shortcut": " x"}, {"glyph": "⊆", "name": "left-shoe-underbar", "kind": "function", "monad": "nest", "dyad": "partition", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["巢段", "巢段"], "shortcut": " - z"}, {"glyph": "∊", "name": "epsilon", "kind": "function", "monad": "enlist", "dyad": "member", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["属展", "屬展"], "shortcut": " e"}, {"glyph": "∪", "name": "down-shoe", "kind": "function", "monad": "unique", "dyad": "union", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["并独", "併獨"], "shortcut": " v"}, {"glyph": "∩", "name": "up-shoe", "kind": "function", "monad": "duplicates", "dyad": "intersection", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["交重", "交重"], "shortcut": " c"}, {"glyph": "⍋", "name": "delta-stile", "kind": "function", "monad": "grade-up", "dyad": "grade-up-by", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["升", "升"], "shortcut": " \\ 7"}, {"glyph": "⍒", "name": "del-stile", "kind": "function", "monad": "grade-down", "dyad": "grade-down-by", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["降", "降"], "shortcut": " \\ g"}, {"glyph": "↑", "name": "up-arrow", "kind": "function", "monad": "first", "dyad": "take", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["取", "取"], "shortcut": " k"}, {"glyph": "↓", "name": "down-arrow", "kind": "function", "monad": "split", "dyad": "drop", "monad_rank": "1", "dyad_ranks": "1 ∞", "hanzi": ["去拆", "去拆"], "shortcut": " j"}, {"glyph": "⌽", "name": "circle-stile", "kind": "function", "monad": "reverse", "dyad": "rotate", "monad_rank": "1", "dyad_ranks": "0 1", "hanzi": ["转", "轉"], "shortcut": " 2"}, {"glyph": "⍉", "name": "circle-backslash", "kind": "function", "monad": "transpose", "dyad": "reorder-axes", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["翻", "翻"], "shortcut": " o \\"}, {"glyph": "⊤", "name": "down-tack", "kind": "function", "monad": "binary-encode", "dyad": "encode", "monad_rank": "∞", "dyad_ranks": "1 0", "hanzi": ["编", "編"], "shortcut": " n"}, {"glyph": "⊥", "name": "up-tack", "kind": "function", "monad": "binary-decode", "dyad": "decode", "monad_rank": "1", "dyad_ranks": "1 1", "hanzi": ["译", "譯"], "shortcut": " b"}, {"glyph": "⍎", "name": "hydrant", "kind": "function", "monad": "execute", "dyad": "execute-in", "monad_rank": "1", "dyad_ranks": "∞ ∞", "hanzi": ["行", "行"], "shortcut": " o b"}, {"glyph": "⍕", "name": "thorn", "kind": "function", "monad": "format", "dyad": "format-spec", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["文", "文"], "shortcut": " o n"}, {"glyph": "⌷", "name": "squad", "kind": "function", "monad": "materialise", "dyad": "index", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["索", "索"], "shortcut": " q \\"}, {"glyph": "⌹", "name": "domino", "kind": "function", "monad": "matrix-inverse", "dyad": "matrix-divide", "monad_rank": "2", "dyad_ranks": "∞ 2", "hanzi": ["解逆", "解逆"], "shortcut": " q u"}, {"glyph": "#", "name": "hash", "kind": "function", "monad": "runs", "dyad": "replicate", "monad_rank": "∞", "dyad_ranks": "1 ∞", "hanzi": ["复", "複"], "shortcut": ""}, {"glyph": "↕", "name": "up-down-arrow", "kind": "function", "monad": "pairs", "dyad": "windows", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["窗", "窗"], "shortcut": " K"}, {"glyph": "⍭", "name": "stile-tilde", "kind": "function", "monad": "prime", "dyad": "prime-mode", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["素", "素"], "shortcut": " \\"}, {"glyph": "⨸", "name": "circle-divide", "kind": "function", "monad": "factors", "dyad": "factor-spec", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["因", "因"], "shortcut": " o u"}, {"glyph": "⌻", "name": "quad-jot", "kind": "function", "monad": "roots", "dyad": "polyval", "monad_rank": "1", "dyad_ranks": "1 0", "hanzi": ["零值", "零值"], "shortcut": " q t"}, {"glyph": "⍸", "name": "iota-underbar", "kind": "function", "monad": "where", "dyad": "interval-index", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["处间", "處間"], "shortcut": " - i"}, {"glyph": "⍷", "name": "epsilon-underbar", "kind": "function", "monad": "groups", "dyad": "find", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["寻群", "尋群"], "shortcut": " - e"}, {"glyph": "⊢", "name": "right-tack", "kind": "function", "monad": "same", "dyad": "right", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["右", "右"], "shortcut": " '"}, {"glyph": "⊣", "name": "left-tack", "kind": "function", "monad": "same-left", "dyad": "left", "monad_rank": "∞", "dyad_ranks": "∞ ∞", "hanzi": ["左", "左"], "shortcut": " ;"}, {"glyph": "¿", "name": "inverted-question", "kind": "function", "monad": "roll", "dyad": "deal", "monad_rank": "0", "dyad_ranks": "0 0", "hanzi": ["掷抽", "擲抽"], "shortcut": " /"}, {"glyph": "¨", "name": "diaeresis", "kind": "monadic-operator", "monad": "each", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["遍", "遍"], "shortcut": " 1"}, {"glyph": "ᵇ", "name": "superscript-b", "kind": "monadic-operator", "monad": "bitwise", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["按", "按"], "shortcut": " 6 b"}, {"glyph": "⍨", "name": "tilde-diaeresis", "kind": "monadic-operator", "monad": "self", "dyad": "commute", "monad_rank": "", "dyad_ranks": "", "hanzi": ["己换", "己換"], "shortcut": " 1 `"}, {"glyph": "↣", "name": "right-tail-arrow", "kind": "dyadic-operator", "monad": "before", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["先", "先"], "shortcut": " ."}, {"glyph": "⍤", "name": "jot-diaeresis", "kind": "dyadic-operator", "monad": "rank", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["秩", "秩"], "shortcut": " 1 t"}, {"glyph": "∘", "name": "jot", "kind": "dyadic-operator", "monad": "atop", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["承", "承"], "shortcut": " t"}, {"glyph": "⍠", "name": "quad-colon", "kind": "dyadic-operator", "monad": "axis", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["轴", "軸"], "shortcut": " q ;"}, {"glyph": "⍥", "name": "circle-diaeresis", "kind": "dyadic-operator", "monad": "over", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["经", "經"], "shortcut": " 1 o"}, {"glyph": "↢", "name": "left-tail-arrow", "kind": "dyadic-operator", "monad": "after", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["后", "後"], "shortcut": " ,"}, {"glyph": ".", "name": "dot", "kind": "dyadic-operator", "monad": "determinant", "dyad": "inner-product", "monad_rank": "", "dyad_ranks": "", "hanzi": ["内", "內"], "shortcut": ""}, {"glyph": "⊗", "name": "circle-times", "kind": "monadic-operator", "monad": "outer-product", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["表", "表"], "shortcut": " o m"}, {"glyph": "⌸", "name": "quad-equal", "kind": "monadic-operator", "monad": "key", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["组", "組"], "shortcut": " q ="}, {"glyph": "⍣", "name": "star-diaeresis", "kind": "dyadic-operator", "monad": "power", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["次止", "次止"], "shortcut": " 1 8"}, {"glyph": "⇄", "name": "right-left-arrows", "kind": "monadic-operator", "monad": "optimize", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["优", "優"], "shortcut": " 4"}, {"glyph": "⊘", "name": "circle-slash", "kind": "dyadic-operator", "monad": "valences", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["兼", "兼"], "shortcut": " o /"}, {"glyph": "@", "name": "at", "kind": "dyadic-operator", "monad": "under", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["于", "於"], "shortcut": ""}, {"glyph": "∂", "name": "partial", "kind": "monadic-operator", "monad": "derivative", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["导梯", "導梯"], "shortcut": " f"}, {"glyph": "⍚", "name": "diamond-underbar", "kind": "dyadic-operator", "monad": "agenda", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["择", "擇"], "shortcut": " - `"}, {"glyph": "⌺", "name": "quad-diamond", "kind": "dyadic-operator", "monad": "stencil", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["邻", "鄰"], "shortcut": " q `"}, {"glyph": "/", "name": "slash", "kind": "monadic-operator", "monad": "reduce", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["总", "總"], "shortcut": ""}, {"glyph": "⌿", "name": "slash-bar", "kind": "monadic-operator", "monad": "reduce-first", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["汇", "匯"], "shortcut": " - /"}, {"glyph": "\\", "name": "backslash", "kind": "monadic-operator", "monad": "scan", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["累", "累"], "shortcut": ""}, {"glyph": "⍀", "name": "backslash-bar", "kind": "monadic-operator", "monad": "scan-first", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["续", "續"], "shortcut": " - \\"}, {"glyph": "⁻", "name": "superscript-minus", "kind": "monadic-operator", "monad": "inverse", "dyad": "", "monad_rank": "", "dyad_ranks": "", "hanzi": ["反", "反"], "shortcut": " _"}];
diff --git a/python/basedpl/browser/layout.json b/python/basedpl/browser/layout.json
index 3db234f6..624d3e3e 100644
--- a/python/basedpl/browser/layout.json
+++ b/python/basedpl/browser/layout.json
@@ -80,7 +80,7 @@
"subscript-minus": {"terminator": "₋", "keys": {"0": "₋₀", "1": "₋₁", "2": "₋₂", "3": "₋₃", "4": "₋₄", "5": "₋₅", "6": "₋₆", "7": "₋₇", "8": "₋₈", "9": "₋₉", ")": "₋₀", "!": "₋₁", "@": "₋₂", "#": "₋₃", "$": "₋₄", "%": "₋₅", "^": "₋₆", "&": "₋₇", "*": "₋₈", "(": "₋₉"}},
"bar": {"terminator": "¯", "keys": {",": "⍪", "\\": "⍀", "/": "⌿", "a": "⍶", "w": "⍹", "7": "⍙", "`": "⍚", "0": "⊼", "9": "⊽", "e": "⍷", "i": "⍸", "z": "⊆"}},
"quad": {"terminator": "⎕", "keys": {"t": "⌻", ":": "⍠", "=": "⌸", "u": "⌹", "|": "⌷", "`": "⌺", ";": "⍠", "\\": "⌷"}},
- "circle": {"terminator": "○", "keys": {"-": "⊖", "\\": "⍉", "/": "⊘", "*": "⊛", "m": "⊗", "u": "⨸", "8": "⊛", "c": "⍝", "b": "⍎", "n": "⍕"}},
+ "circle": {"terminator": "○", "keys": {"\\": "⍉", "/": "⊘", "*": "⊛", "m": "⊗", "u": "⨸", "8": "⊛", "c": "⍝", "b": "⍎", "n": "⍕"}},
"stile": {"terminator": "⍭", "keys": {"7": "⍋", "g": "⍒"}}
}
}
diff --git a/python/basedpl/hpl.tmLanguage.json b/python/basedpl/hpl.tmLanguage.json
index cf1fd6bf..51f0b64a 100644
--- a/python/basedpl/hpl.tmLanguage.json
+++ b/python/basedpl/hpl.tmLanguage.json
@@ -19,7 +19,7 @@
"applyEndPatternLast": true
},
{
- "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←是⎕出入•系α甲ω乙⍶丙⍹丁∇递遞⍢循⍝注◇句⁝隔\\?若¯负負∞永⍬空\\+加\\-减減×乘号號÷除⌈上⌊下\\|绝余絕餘\\*幂冪⊛对對○圆圓π周√根!阶拣階揀∧极且極∨析或⊼方否⊽双莫雙\\~非无無=等≠别初別<小≤限退>大≥达进達進ι位↦至:键卸鍵ρ形≢数异數異≡同深,连連⍪接矩⊂包⊃选合選⊆巢段∊属展屬∪并独併獨∩交重⍋升⍒降↑取↓去拆⌽转轉⊖纵縱⍉翻⊤编編⊥译譯⍎行⍕文⌷索⌹解逆\\#复複↕窗⍭素⨸因⌻零值⍸处间處間⍷寻群尋⊢右⊣左¿掷抽擲¨遍ᵇ按⍨己换換↣先⍤秩∘承⍠轴軸⍥经經↢后後\\.内內⊗表⌸组組⍣次止⇄优優⊘兼@于於∂导梯導⍚择擇⌺邻鄰/总總⌿汇匯\\\\累⍀续續⁻反⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
+ "match": "(?:_\\d+|_\\S|_|[^\\s\\p{Cc}0-9←是⎕出入•系α甲ω乙⍶丙⍹丁∇递遞⍢循⍝注◇句⁝隔\\?若¯负負∞永⍬空\\+加\\-减減×乘号號÷除⌈上⌊下\\|绝余絕餘\\*幂冪⊛对對○圆圓π周√根!阶拣階揀∧极且極∨析或⊼方否⊽双莫雙\\~非无無=等≠别初別<小≤限退>大≥达进達進ι位↦至:键卸鍵ρ形≢数异數異≡同深,连連⍪接矩⊂包⊃选合選⊆巢段∊属展屬∪并独併獨∩交重⍋升⍒降↑取↓去拆⌽转轉⍉翻⊤编編⊥译譯⍎行⍕文⌷索⌹解逆\\#复複↕窗⍭素⨸因⌻零值⍸处间處間⍷寻群尋⊢右⊣左¿掷抽擲¨遍ᵇ按⍨己换換↣先⍤秩∘承⍠轴軸⍥经經↢后後\\.内內⊗表⌸组組⍣次止⇄优優⊘兼@于於∂导梯導⍚择擇⌺邻鄰/总總⌿汇匯\\\\累⍀续續⁻反⁰¹²³⁴⁵⁶⁷⁸⁹⁻ᵀᵘₓ₀₁₂₃₄₅₆₇₈₉₋ₓ₁ₓ₂ₓ₄ₓ₈ₓₕₛₚₐᵣ\\(\\)\\[\\]\\{\\}'\";\\$_ₑⱼᵣ])+",
"name": "variable.other.bpl"
},
{
@@ -35,7 +35,7 @@
"name": "constant.numeric.bpl"
},
{
- "match": "[加减減乘号號除上下绝余絕餘幂冪对對圆圓周根阶拣階揀极且極析或方否双莫雙非无無等别初別小限退大达进達進位至键卸鍵形数异數異同深连連接矩包选合選巢段属展屬并独併獨交重升降取去拆转轉纵縱翻编編译譯行文索解逆复複窗素因零值处间處間寻群尋右左掷抽擲]",
+ "match": "[加减減乘号號除上下绝余絕餘幂冪对對圆圓周根阶拣階揀极且極析或方否双莫雙非无無等别初別小限退大达进達進位至键卸鍵形数异數異同深连連接矩包选合選巢段属展屬并独併獨交重升降取去拆转轉翻编編译譯行文索解逆复複窗素因零值处间處間寻群尋右左掷抽擲]",
"name": "support.function.bpl"
},
{
diff --git a/src/batch.rs b/src/batch.rs
index bcaf8264..7c18fdee 100644
--- a/src/batch.rs
+++ b/src/batch.rs
@@ -285,8 +285,8 @@ pub(crate) fn call(op: Op<'_>, left: Option<&Value>, right: &Value, level: u64,
/// `p` along cell axis `axis` of batched run `level`, as one call along that axis of the batch's whole, past its frame. Only forms that act along one axis and treat every other axis alike take this route: `⌽` and `⊖` with no left argument or a scalar one, and `#` with the same counts for every cell. A larger left argument of `⌽` or `⊖` would pair with the frame's axes in the whole call. Any other call along an axis stops the run, because no rule moves the axis past the frame.
fn along(p: Primitive, axis: usize, x: Option>, y: Arg<'_>, level: u64, span: &Span) -> Option> {
let routed = match (p, x) {
- (Primitive::Reverse(_), None) | (Primitive::Replicate, Some(Arg::Constant(_))) => true,
- (Primitive::Reverse(_), Some(Arg::Constant(c))) => c.shape().is_empty(), _ => false
+ (Primitive::Reverse, None) | (Primitive::Replicate, Some(Arg::Constant(_))) => true,
+ (Primitive::Reverse, Some(Arg::Constant(c))) => c.shape().is_empty(), _ => false
};
let (true, Arg::Batched(b)) = (routed, y) else { return stop(Stop::refusing(level, p)) };
Some(p.call_axis(x.map(Arg::all), &b.whole, Some(axis + b.frame), span).and_then(|whole| result(level, whole, b.frame, || true, Stop::refusing(level, p))))
diff --git a/src/derivative.rs b/src/derivative.rs
index a4785194..1eadc2fa 100644
--- a/src/derivative.rs
+++ b/src/derivative.rs
@@ -748,7 +748,7 @@ fn decode(left: Option<&Value>, right: &Value, span: &Span) -> Result 1 { return Err(Error::new(ErrorKind::Unsupported, "∂ differentiates ⊥ only with a scalar or vector base")); }
- let reverse = |v: &Value, span: &Span| Primitive::Reverse(false).call(None, v, span);
+ let reverse = |v: &Value, span: &Span| Primitive::Reverse.call(None, v, span);
let digits = if ylen == len { right.clone() } else {
let d = if right.shape().is_empty() { Primitive::Ravel.call(None, right, span)? } else { right.clone() };
Primitive::Replicate.call_axis(Some(&Value::integer(len as i64)), &d, Some(d.shape().len() - 1), span)?
diff --git a/src/derivative/tape.rs b/src/derivative/tape.rs
index 8e4a4ebb..e47fa939 100644
--- a/src/derivative/tape.rs
+++ b/src/derivative/tape.rs
@@ -232,6 +232,8 @@ impl Back<'_> {
/// Adds `u` at the walk `base`, `steps` of the node that `read` reads. A broadcast's cotangent sums along the axes it repeats over (step 0) first, and only the remaining axes write back. A repeated axis reads one offset of its source, its start, which joins the base.
fn add_walked(&mut self, read: &Read, base: usize, steps: &[Steps], u: Value) -> Result<(), Error> {
if !self.live(read.of) { return Ok(()); }
+ // A read may split one logical result axis into several walk axes, as replicate does. Fold repeats in that walk's shape.
+ let u = u.with_shape(steps.iter().map(Steps::len).collect::>()).described("a cotangent has its read's walk shape")?;
let starts: Vec<(usize, usize)> = steps.iter().enumerate().filter_map(|(a, s)| match *s {
Steps::Stride { start, len, step: 0 } if len > 1 => Some((a, start)), _ => None
}).collect();
@@ -470,7 +472,7 @@ fn spread(u: &Value, along: usize, layout: &Layout, span: &Span) -> Result Result {
- let flip = |v: &Value| Primitive::Reverse(false).call_axis(None, v, Some(axis), span);
+ let flip = |v: &Value| Primitive::Reverse.call_axis(None, v, Some(axis), span);
flip(&Operation::Fold(PLUS, kind).call(Pairing::Axis(Some(axis)), None, &flip(u)?, span)?)
}
diff --git a/src/eval/operators/axes.rs b/src/eval/operators/axes.rs
index 04c479a2..9ffa2f65 100644
--- a/src/eval/operators/axes.rs
+++ b/src/eval/operators/axes.rs
@@ -18,6 +18,9 @@ pub(super) fn native_primitive(f: &Function, dyadic: bool) -> Option<(Primitive,
pub(in crate::eval) fn along_axes(f: &Function, spec: &Value, left: Option<&Value>, right: &Value, span: &Span) -> Result {
if spec.keys(0).is_some() { return with_options(f, spec, left, right, span); }
if let FunctionNode::Primitive(p) = f.node() && p.facts(left.is_some()).axes { return Ok(Bound::from(p.call_axes(left, right, spec, span)?)); }
+ if let Some((spec, x, y)) = crate::primitive::extended_axes(spec, left, right, !matches!(f.node(), FunctionNode::Fold(..)))? {
+ return along_axes(f, &spec, x.as_ref(), &y, span);
+ }
match f.node() {
FunctionNode::Fold(operand, kind) => Ok(Bound::from(fold(operand, *kind, Some(spec), left, right, span)?)), _ => cell_axes(f, spec, left, right, span)
}
@@ -47,13 +50,13 @@ fn filled(f: &Function, spec: &Value, fill: &Value, left: Option<&Value>, right:
N::Composed(Axis, [F(g), V(inner)]) if inner.keys(0).is_some() => with_options(g, inner, left, right, span),
N::Composed(Axis, [F(g), V(axes)]) => match g.node() {
N::Primitive(p) if p.facts(left.is_some()).axes => primitive(*p, false, Some(axes)),
- _ => cell_axes(&Function::new(N::Composed(Axis, [F(g.clone()), V(spec.clone())]), span)?, axes, left, right, span),
+ _ => along_axes(&Function::new(N::Composed(Axis, [F(g.clone()), V(spec.clone())]), span)?, axes, left, right, span),
},
_ => Err(Error::domain("this function reads no fill")),
}
}
-/// Apply `f` to the cells made of the selected axes. The other axes form the frame. The selected axes must exist in the higher-rank argument. An axis given by name is selected wherever each argument's layout puts it, and an axis given by number at the higher-rank argument's position. An argument that lacks one of them is one whole cell.
+/// Apply `f` to the cells made of the selected axes. The other axes form the frame. An axis given by name is selected wherever each argument's layout puts it, and an axis given by number at the higher-rank argument's position. An argument that lacks one of them is one whole cell.
pub(in crate::eval) fn cell_axes(f: &Function, spec: &Value, left: Option<&Value>, right: &Value, span: &Span) -> Result {
let target = match left { Some(x) if x.shape().len() > right.shape().len() => x, _ => right };
let order = target.shape().len();
diff --git a/src/eval/operators/rank.rs b/src/eval/operators/rank.rs
index 1c709b1b..7047df49 100644
--- a/src/eval/operators/rank.rs
+++ b/src/eval/operators/rank.rs
@@ -122,11 +122,20 @@ fn vector_product(f: Primitive, g: Primitive, x: &Value, y: &Value, span: &Span)
/// `f` on each rank-`k` cell of `y`, as calls on the whole of `y` along the cells' axes. The frame's axes keep their keys and names. `None` where no rule covers `f`.
fn cell_rule(f: &Function, y: &Value, k: usize, span: &Span) -> Option> {
- use {crate::primitive::CellRule, FunctionNode as N, Operand::{Function as F, Value as V}, OperatorKind::{Atop, Before}};
+ use {crate::primitive::CellRule, FunctionNode as N, Operand::{Function as F, Value as V}, OperatorKind::{Atop, Axis, Before}};
match f.node() {
N::Primitive(p) => primitive_cells(*p, None, y, k, span),
N::Fold(g, kind) => folded_cells(pervasive_primitive(g, true)?, *kind, &[kind.default_axis(k)], None, y, k, span),
N::Composed(Before, [V(a), F(g)]) => primitive_cells(g.dyadic_primitive()?, Some(a), y, k, span),
+ N::Composed(Axis, [F(g), V(spec)]) if spec.keys(0).is_none() => {
+ let p = primitive(g, false)?;
+ if !p.facts(false).axes || !matches!(p.facts(false).cells, CellRule::Same | CellRule::Every | CellRule::Encloses) { return None; }
+ let frame = y.shape().len() - k;
+ let cell = y.layout().axes(frame..y.shape().len());
+ let selected = crate::primitive::axes(&crate::primitive::resolve_axes_in(spec, &cell).ok()?, k).ok()?;
+ let spec = Value::integers(vec![selected.len()], selected.iter().map(|&a| (frame + a) as i64).collect()).ok()?;
+ Some(p.call_axes(None, y, &spec, span))
+ }
N::Composed(Atop, [F(g), F(h)]) => {
// A fold of each cell's items, joined into one axis as monadic `,` joins them (`CellRule::Every`), folds all the cell axes at once. That takes folds in turn where the primitive allows them. Folds in turn reach sliding folds over windows.
if let (N::Fold(op, kind), Some(p)) = (g.node(), primitive(h, false)) {
@@ -172,7 +181,6 @@ fn primitive_cells(p: Primitive, left: Option<&Value>, y: &Value, k: usize, span
let Some(a) = left else {
if p.extends_at(None, k) { return Some(p.call(None, y, span)); }
return match p.facts(false).cells {
- CellRule::First if k > 0 => Some(p.call_axes(None, y, &axes(0, 1), span)),
CellRule::Every => Some(p.call_axes(None, y, &axes(0, k), span)),
CellRule::Encloses if k > 0 => Some(p.call_axes(None, y, &axes(0, k), span)),
CellRule::Length | CellRule::Shape => cell_constant(p, &y.layout().axes(frame..frame + k))
@@ -201,7 +209,6 @@ fn primitive_cells(p: Primitive, left: Option<&Value>, y: &Value, k: usize, span
match p.facts(true).cells {
// A left argument of a form that runs along leading cell axes has one item for each axis it applies to. A named selector stays on the cell path, because the whole array's frame axes could pair with its name.
CellRule::Leading if vector && a.len() <= k && !a.elements().any(|e| e.layout().has_names()) => Some(p.call_axes(Some(a), y, &axes(0, a.len()), span)),
- CellRule::First if a.shape().is_empty() && k > 0 => Some(p.call_axes(Some(a), y, &axes(0, 1), span)),
CellRule::Along if vector && k > 0 => Some(p.call_axes(Some(a), y, &axes(0, 1), span)),
// Each destination lies inside the cell.
CellRule::Axes if vector => a.as_items().nonnegative_integers::().ok().filter(|to| to.iter().all(|&d| d < k)).map(|to| moved(&to)),
diff --git a/src/primitive.rs b/src/primitive.rs
index d354f0a5..4198f17d 100644
--- a/src/primitive.rs
+++ b/src/primitive.rs
@@ -187,7 +187,7 @@ pub(crate) enum Comparison { Equal, NotEqual, Less, LessEqual, Greater, GreaterE
pub(crate) enum Primitive {
Arithmetic(Arithmetic), Math(Math), Bitwise(u8), Random, Identity(bool), Compare(Comparison), Iota, Range, Keys, Depth, Where, Member, Union, Intersection,
Find, Grade(bool), Index, Bracket, Encode, Decode, MatrixDivide, Execute, Format, Shape, Tally, Ravel, Enclose, Nest, Mix, Take, Drop, Replicate,
- CatenateFirst, Reverse(bool), Transpose, Windows, Prime, Factor, Polynomial, Exact(Exact), Real(Real), Special(Special)
+ CatenateFirst, Reverse, Transpose, Windows, Prime, Factor, Polynomial, Exact(Exact), Real(Real), Special(Special)
}
/// A function with exact results under either kinds, which `ₓ` after a primitive reaches, as `Math::Arc` is the inverse that `○⁻` reaches. `⌊ₓ`, `⌈ₓ` and dyadic `÷ₓ` give integers, each through one kernel. Each shares the row of the primitive it modifies, as `Bracket` shares `⌷`'s.
@@ -274,7 +274,7 @@ impl Primitive {
];
match self {
Self::Arithmetic(Plus | Minus | Divide)
- | Self::Reverse(_)
+ | Self::Reverse
| Self::Transpose
| Self::Identity(_)
| Self::Math(Not)
@@ -435,8 +435,35 @@ pub(crate) fn axes(axis: &Value, rank: usize) -> Result, Error> {
}
Ok(result)
}
+
+/// Missing nonnegative axes append singleton view axes to the data arguments. Negative axes still resolve against their original rank. `paired` includes the left argument's data; counts, seeds and selectors stay whole. No result means no extension is needed.
+pub(crate) fn extended_axes(spec: &Value, left: Option<&Value>, right: &Value, paired: bool) -> Result