diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-07-07 16:17:58 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-07-07 16:17:58 -0400 |
| commit | 91b5abe9fa8b2394606f0eb82bfaeb54fa8a33e8 (patch) | |
| tree | 26746a3f1c81874c8a65c705d19e6f13355f460c /spec | |
| parent | 85c54f4c22897972025d76502b9e305541ec5a6e (diff) | |
Use # instead of ⍝ for comments
Diffstat (limited to 'spec')
| -rw-r--r-- | spec/grammar.md | 16 | ||||
| -rw-r--r-- | spec/reference.bqn | 148 | ||||
| -rw-r--r-- | spec/token.md | 4 |
3 files changed, 84 insertions, 84 deletions
diff --git a/spec/grammar.md b/spec/grammar.md index 2ea60e65..082e8e14 100644 --- a/spec/grammar.md +++ b/spec/grammar.md @@ -25,8 +25,8 @@ Starting at the highest-order objects, modifiers and compositions have fairly si _cmpExp_ = _comp_ | _c_ ASGN _cmpExp_ _modExpr = _mod - | _comp_ ( value | Func ) ⍝ Right partial application - | Operand _comp_ ⍝ Left partial application + | _comp_ ( value | Func ) # Right partial application + | Operand _comp_ # Left partial application | _m ASGN _modExpr Functions can be formed by fully applying operators or as trains. Operators are left-associative, so that the left operand (`Operand`) can include operators but the right operand (`value | Func`) cannot. Trains are right-associative, but bind less tightly than operators. Assignment is not allowed in the top level of a train: it must be parenthesized. @@ -37,10 +37,10 @@ Functions can be formed by fully applying operators or as trains. Operators are Operand = value | Derv Fork = Func - | Operand Func Fork ⍝ 3-train - | nothing Func Fork ⍝ 2-train + | Operand Func Fork # 3-train + | nothing Func Fork # 2-train Train = Fork - | Func Fork ⍝ 2-train + | Func Fork # 2-train FuncExpr = Train | F ASGN FuncExpr @@ -59,7 +59,7 @@ Value expressions are complicated by the possibility of list assignment. We also lhs = lhsValue | lhsStr valExpr = arg | lhs ASGN valExpr - | lhs Derv "↩" valExpr ⍝ Modified assignment + | lhs Derv "↩" valExpr # Modified assignment A header looks like a name for the thing being headed, or its application to inputs (possibly twice in the case of modifiers and compositions). As with assignment, it is restricted to a simple form with no extra parentheses. The full list syntax is allowed for arguments. As a special rule, a monadic function header specifically can omit the function when the argument is not just a name (as this would conflict with a value label). The following cases define only headers with arguments, which are assumed to be special cases; there can be any number of these. Headers without arguments can only refer to the general case—note that operands are not pattern matched—so there can be at most two of these kinds of headers, indicating the monadic and dyadic cases. @@ -70,8 +70,8 @@ A header looks like a name for the thing being headed, or its application to inp ModH1 = HeadF ( _m | "_𝕣" ) CmpH1 = HeadF ( _c_ | "_𝕣_" ) HeadG FuncHead = headW? ( F | "𝕊" ) headX - | vl | "(" valExpr ")" | brVal | list ⍝ value, - | ANY ( "‿" ANY )+ ⍝ but not v + | vl | "(" valExpr ")" | brVal | list # value, + | ANY ( "‿" ANY )+ # but not v _modHead = headW? ModH1 headX _cmpHed_ = headW? CmpH1 headX diff --git a/spec/reference.bqn b/spec/reference.bqn index 241be28a..84f403bf 100644 --- a/spec/reference.bqn +++ b/spec/reference.bqn @@ -1,49 +1,49 @@ -⍝ This file gives reference implementations of BQN primitives assuming -⍝ limited initial functionality. Implementations are designed to be -⍝ simple and not fast. - -⍝ Not yet included: characters, complex numbers, comparison tolerance, -⍝ selective assignment, and Under. - -⍝ In some cases an operation is defined with limited functionality at -⍝ first and later expanded. For convenience, rather than renaming these -⍝ limited versions, every primitive use refers to the most recent -⍝ definition in source code, as if redefinitions shadowed previous -⍝ primitive definitions. - - -⍝⌜ -⍝ LAYER 0: Assumed functionality - -⍝ IEEE 754, except NaN results cause an error and -0 is converted to 0. -⍝ LIMITED to the stated cases and real number arguments. -+ ⍝ Add -- ⍝ Negate Subtract -× ⍝ Multiply -÷ ⍝ Reciprocal Divide -⋆ ⍝ Exponential Power -⌊ ⍝ Floor -= ⍝ Equals -≤ ⍝ Less Than or Equal to - -⍝ Other basic functionality that we need to assume -IsArray ⍝ Return 1 if 𝕩 is an array -! ⍝ 𝕩 is 0 or 1; throw an error if it's 0 -≢ ⍝ LIMITED to monadic case -⥊ ⍝ LIMITED to array 𝕩 and (×´𝕨)≡≢𝕩 -⊑ ⍝ LIMITED to natural number 𝕩 and vector 𝕨 -_amend ⍝ {(𝕗⊑𝕩)↩𝕨⋄𝕩} -↕ ⍝ LIMITED to number 𝕩 -Identity ⍝ Left or right identity of function 𝕏 -⁼ ⍝ Inverse of function 𝔽 -Type ⍝ Scalar (enclosed) prototype of 𝕩 - - -⍝⌜ -⍝ LAYER 1: Foundational operators and functions - -⍝ Combinators -◶ ← {𝕨((𝕨𝔽𝕩)⊑𝕘){𝔽}𝕩} ⍝ LIMITED to number left operand result +# This file gives reference implementations of BQN primitives assuming +# limited initial functionality. Implementations are designed to be +# simple and not fast. + +# Not yet included: characters, complex numbers, comparison tolerance, +# selective assignment, and Under. + +# In some cases an operation is defined with limited functionality at +# first and later expanded. For convenience, rather than renaming these +# limited versions, every primitive use refers to the most recent +# definition in source code, as if redefinitions shadowed previous +# primitive definitions. + + +#⌜ +# LAYER 0: Assumed functionality + +# IEEE 754, except NaN results cause an error and -0 is converted to 0. +# LIMITED to the stated cases and real number arguments. ++ # Add +- # Negate Subtract +× # Multiply +÷ # Reciprocal Divide +⋆ # Exponential Power +⌊ # Floor += # Equals +≤ # Less Than or Equal to + +# Other basic functionality that we need to assume +IsArray # Return 1 if 𝕩 is an array +! # 𝕩 is 0 or 1; throw an error if it's 0 +≢ # LIMITED to monadic case +⥊ # LIMITED to array 𝕩 and (×´𝕨)≡≢𝕩 +⊑ # LIMITED to natural number 𝕩 and vector 𝕨 +_amend # {(𝕗⊑𝕩)↩𝕨⋄𝕩} +↕ # LIMITED to number 𝕩 +Identity # Left or right identity of function 𝕏 +⁼ # Inverse of function 𝔽 +Type # Scalar (enclosed) prototype of 𝕩 + + +#⌜ +# LAYER 1: Foundational operators and functions + +# Combinators +◶ ← {𝕨((𝕨𝔽𝕩)⊑𝕘){𝔽}𝕩} # LIMITED to number left operand result ⊘ ← {𝕨((1{𝔽}𝕨)-0)◶𝔽‿𝔾 𝕩} ⊢ ← {𝕩} ⊣ ← {𝕩}⊘{𝕨} @@ -53,7 +53,7 @@ Type ⍝ Scalar (enclosed) prototype of 𝕩 ⊸ ← {(𝔽𝕨⊣𝕩)𝔾𝕩} ⟜ ← {(𝕨⊣𝕩)𝔽𝔾𝕩} -⍝ LIMITED to numeric arguments for scalar cases +# LIMITED to numeric arguments for scalar cases √ ← 2⊸√ ⊘ (⋆⟜÷˜) ∧ ← × ∨ ← (+-×) @@ -66,9 +66,9 @@ Type ⍝ Scalar (enclosed) prototype of 𝕩 × ↩ 0⊸(<->) ⊘ × ⌊ ↩ ⌊ ⊘ {(𝕨>𝕩)⊑𝕨‿𝕩} ⌈ ← -∘⌊∘- ⊘ {(𝕨<𝕩)⊑𝕨‿𝕩} -≢ ↩ IsArray◶⟨⟩‿≢ ⍝ LIMITED to monadic case +≢ ↩ IsArray◶⟨⟩‿≢ # LIMITED to monadic case -¨ ← _eachm ⍝ LIMITED to monadic case and array 𝕩 +¨ ← _eachm # LIMITED to monadic case and array 𝕩 ´ ← _reduce _eachm←{ @@ -86,14 +86,14 @@ _reduce←{ Length ← (0<0⊑≢)◶⟨1⋄0⊑⊢⟩∘≢ -⍝⌜ -⍝ LAYER 2: Pervasion -⍝ After defining _perv, we apply it to all scalar functions, -⍝ making them pervasive. I'm not going to write that out. +#⌜ +# LAYER 2: Pervasion +# After defining _perv, we apply it to all scalar functions, +# making them pervasive. I'm not going to write that out. ToArray ← IsArray◶<‿⊢ -∾ ← {k←≠𝕨⋄k⊸≤◶⟨⊑⟜𝕨⋄-⟜k⊑𝕩˜⟩¨↕k+≠𝕩} ⍝ LIMITED to two vector arguments +∾ ← {k←≠𝕨⋄k⊸≤◶⟨⊑⟜𝕨⋄-⟜k⊑𝕩˜⟩¨↕k+≠𝕩} # LIMITED to two vector arguments _table←{ m←≠a←⥊𝕨 ⋄ n←≠b←⥊𝕩 ⋄ F←𝔽 @@ -103,7 +103,7 @@ _table←{ } _eachd←{ - _e←{ ⍝ 𝕨 has smaller or equal rank + _e←{ # 𝕨 has smaller or equal rank k←≠p←≢𝕨 ⋄ q←≢𝕩 ! ∧´(⊑⟜p=⊑⟜q)¨↕k l←×´(q⊑˜k⊸+)¨↕q≠⊸-k @@ -112,7 +112,7 @@ _eachd←{ } (>○(≠≢))◶⟨𝔽_e⋄𝔽˜_e˜⟩ } -_perv←{ ⍝ Pervasion +_perv←{ # Pervasion (⊢⊘∨○IsArray)◶⟨𝔽⋄𝔽{𝕨𝔽_perv𝕩}¨⟩ } @@ -120,9 +120,9 @@ _perv←{ ⍝ Pervasion ¨ ↩ {(𝔽_eachm)⊘(𝔽_eachd)○ToArray} -⍝⌜ -⍝ LAYER 3: Remove other limits -⍝ Now all implementations are full except ∾; ↕ is monadic only +#⌜ +# LAYER 3: Remove other limits +# Now all implementations are full except ∾; ↕ is monadic only Int←IsArray◶⟨⌊⊸=,0⟩ Nat←IsArray◶⟨0⊸≤∧⌊⊸=,0⟩ @@ -167,14 +167,14 @@ Depth←IsArray◶0‿{1+0⌈´Depth¨⥊𝕩} ⊑ ↩ (0¨∘≢)⊸Pick ⊘ Pick ⥊ ↩ Deshape ⊘ Reshape ↕ ↩ Range -◶ ↩ {𝕨((𝕨𝔽𝕩)⊑𝕘){𝔽}𝕩} ⍝ Same definition, new Pick +◶ ↩ {𝕨((𝕨𝔽𝕩)⊑𝕘){𝔽}𝕩} # Same definition, new Pick ≡ ← Depth ⊘ Match ≢ ↩ ≢ ⊘ (¬Match) -⍝⌜ -⍝ LAYER 4: Operators +#⌜ +# LAYER 4: Operators > ↩ Unbox ⊘ > ≍ ← >∘Pair @@ -232,8 +232,8 @@ _iterate_←{ } -⍝⌜ -⍝ LAYER 5: Structural functions +#⌜ +# LAYER 5: Structural functions ⊏ ← 0⊸Select ⊘ Select ↑ ← Prefixes ⊘ Take @@ -244,10 +244,10 @@ _iterate_←{ _onAxes_←{ F←𝔽 - (𝔾<≡)∘⊣◶{ ⍝ One axis + (𝔾<≡)∘⊣◶{ # One axis ! 1≤≠≢𝕩 𝕨F𝕩 - }‿{ ⍝ Multiple axes + }‿{ # Multiple axes ! 1≥≠≢𝕨 ! 𝕨≤○≠≢𝕩 R←{(⊑𝕨)F(1 DropV 𝕨)⊸R˘𝕩}⍟{0<≠𝕨} @@ -313,8 +313,8 @@ Rep ← Indices⊸⊏ Replicate ← {0<≠≢𝕨}◶(⥊˜⟜≠Rep⊢)‿{!𝕨=○≠𝕩⋄𝕨Rep𝕩} _onAxes_ (1-0=≠) -⍝⌜ -⍝ LAYER 6: Everything else +#⌜ +# LAYER 6: Everything else ∾ ↩ Join ⊘ JoinTo ⊔ ← ⊔⟜(↕≠⚇1) ⊘ Group @@ -329,7 +329,7 @@ Replicate ← {0<≠≢𝕨}◶(⥊˜⟜≠Rep⊢)‿{!𝕨=○≠𝕩⋄𝕨Rep ⊒ ← OccurrenceCount⊘ ProgressiveIndexOf Join←{ - C←(<⟨⟩)⥊⊸∾⌜´⊢ ⍝ Cartesian array product + C←(<⟨⟩)⥊⊸∾⌜´⊢ # Cartesian array product ! IsArray 𝕩 s←≢¨𝕩 d←≠⊑s @@ -350,7 +350,7 @@ Group←{ (𝕨⊸=/𝕩˜)¨↕1+¯1⌈´⚇1𝕨 } -⍝ Searching +# Searching IndexOf←{ c←1-˜≠≢𝕨 ! 0≤c @@ -380,10 +380,10 @@ ReorderAxes←{ } Transpose←(≠∘≢-1˜)⊸ReorderAxes⍟(0<≠∘≢) -⍝ Sorting -Cmp ← ∨○IsArray◶{ ⍝ No arrays - 𝕨(>-<)𝕩 ⍝ Assume they're numbers -}‿{ ⍝ At least one array +# Sorting +Cmp ← ∨○IsArray◶{ # No arrays + 𝕨(>-<)𝕩 # Assume they're numbers +}‿{ # At least one array e←𝕨-˜○(∨´0=≢)𝕩 𝕨(e=0)◶e‿{ c←𝕨×∘-○(IsArray+≠∘≢)𝕩 diff --git a/spec/token.md b/spec/token.md index 430869ac..8315c9c2 100644 --- a/spec/token.md +++ b/spec/token.md @@ -2,9 +2,9 @@ This page describes BQN's token formation rules (token formation is also called BQN source code should be considered as a series of unicode code points, which we refer to as "characters". The separator between lines in a file is considered to be a single character, newline, even though some operating systems such as Windows typically represent it with a two-character CRLF sequence. Implementers should note that not all languages treat unicode code points as atomic, as exposing the UTF-8 or UTF-16 representation instead is common. For a language such as JavaScript that uses UTF-16, the double-struck characters `𝕨𝕎𝕩𝕏𝕗𝔽𝕘𝔾` are represented as two 16-bit surrogate characters, but BQN treats them as a single unit. -A BQN *character literal* consists of a single character between single quotes, such as `'a'`, and a *string literal* consists of any number of characters between double quotes, such as `""` or `"abc"`. Character and string literals take precedence with comments over other tokenization rules, so that `⍝` between quotes does not start a comment and whitespace between quotes is not removed, but a quote within a comment does not start a character literal. Almost any character can be included directly in a character or string literal without escaping. The only exception is the double quote character `"`, which must be written twice to include it in a string, as otherwise it would end the string instead. Character literals require no escaping at all, as the length is fixed. In particular, literals for the double and single quote characters are written `'''` and `'"'`, while length-1 strings containing these characters are `"'"` and `""""`. +A BQN *character literal* consists of a single character between single quotes, such as `'a'`, and a *string literal* consists of any number of characters between double quotes, such as `""` or `"abc"`. Character and string literals take precedence with comments over other tokenization rules, so that `#` between quotes does not start a comment and whitespace between quotes is not removed, but a quote within a comment does not start a character literal. Almost any character can be included directly in a character or string literal without escaping. The only exception is the double quote character `"`, which must be written twice to include it in a string, as otherwise it would end the string instead. Character literals require no escaping at all, as the length is fixed. In particular, literals for the double and single quote characters are written `'''` and `'"'`, while length-1 strings containing these characters are `"'"` and `""""`. -A comment consists of the lamp character `⍝` and any following text until (not including) the next newline character. The initial `⍝` must not be part of a string literal started earlier. Comments are ignored entirely and do not form tokens. +A comment consists of the hash character `#` and any following text until (not including) the next newline character. The initial `#` must not be part of a string literal started earlier. Comments are ignored entirely and do not form tokens. Identifiers and numeric literals share the same token formation rule. These tokens are formed from the *numeric characters* `¯∞π.0123456789` and *alphabetic characters* `_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ` and the oddball `𝕣`. Any sequence of these characters adjacent to each other forms a single token, which is a *numeric literal* if it begins with a numeric character and an *identifier* if it begins with an alphabetic character. Numeric literals are also subject to [numeric literal rules](literal.md), which specify which numeric literals are valid and which numbers they represent. If the token contains `𝕣` it must be either `𝕣`, `_𝕣`, or `_𝕣_` and is considered a special name (see below). As the value taken by this identifier can only be a modifier or composition, the uppercase character `ℝ` is not allowed. |
