aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2020-10-09 09:54:53 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2020-10-09 09:55:01 -0400
commite49851e8796f4e961946c9d9d886c7f14e1dd8cf (patch)
treebc13f378414b7b0bb43cdb51233455c538979e67 /docs
parent926936e92ec799c0697c20a8bb622fdc4965cf37 (diff)
Allow any statement as the last line of a namespace block or program
Diffstat (limited to 'docs')
-rw-r--r--docs/spec/grammar.html11
1 files changed, 6 insertions, 5 deletions
diff --git a/docs/spec/grammar.html b/docs/spec/grammar.html
index 8eabe899..42d5e817 100644
--- a/docs/spec/grammar.html
+++ b/docs/spec/grammar.html
@@ -8,8 +8,9 @@
<p>BQN's grammar is given below. Terms are defined in a <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">BNF</a> variant. However, handling special names properly is possible but difficult in BNF, so they are explained in text along with the braced block grammar.</p>
<p>The symbols <code><span class='Value'>s</span></code>, <code><span class='Function'>F</span></code>, <code><span class='Modifier'>_m</span></code>, and <code><span class='Modifier2'>_c_</span></code> are identifier tokens with subject, function, 1-modifier, and 2-modifier classes respectively. Similarly, <code><span class='Value'>sl</span></code>, <code><span class='Function'>Fl</span></code>, <code><span class='Modifier'>_ml</span></code>, and <code><span class='Modifier2'>_cl_</span></code> refer to literals and primitives of those classes. While names in the BNF here follow the identifier naming scheme, this is informative only: syntactic classes are no longer used after parsing and cannot be inspected in a running program.</p>
<p>A program is a list of statements. Almost all statements are expressions. Valueless results stemming from <code><span class='Nothing'>ยท</span></code>, or <code><span class='Value'>๐•จ</span></code> in a monadic brace function, can be used as statements but not expressions. &quot;Namespace statements&quot;, which import multiple values from a namespace block (immediate block containing <code><span class='Gets'>โ‡</span></code>), also cannot be expressions. An extension to BQN to allow first-class namespaces would extend ordinary expressions so that <code><span class='Function'>NS_STMT</span></code> would no longer be needed, as it would be a subset of <code><span class='Function'>EXPR</span></code>.</p>
-<pre><span class='Function'>PROGRAM</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Paren'>(</span> <span class='Function'>STMT</span> <span class='Function'>|</span> <span class='Function'>EXPORT</span> <span class='Separator'>โ‹„</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>STMT</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>)</span><span class='Value'>?</span>
-<span class='Function'>STMT</span> <span class='Function'>=</span> <span class='Function'>EXPR</span> <span class='Function'>|</span> <span class='Value'>nothing</span> <span class='Function'>|</span> <span class='Function'>NS_STMT</span>
+<pre><span class='Function'>PROGRAM</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Paren'>(</span> <span class='Function'>STMT</span> <span class='Separator'>โ‹„</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>STMT</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>)</span><span class='Value'>?</span>
+<span class='Function'>STMT</span> <span class='Function'>=</span> <span class='Function'>BSTMT</span> <span class='Function'>|</span> <span class='Function'>EXPORT</span>
+<span class='Function'>BSTMT</span> <span class='Function'>=</span> <span class='Function'>EXPR</span> <span class='Function'>|</span> <span class='Value'>nothing</span> <span class='Function'>|</span> <span class='Function'>NS_STMT</span>
<span class='Separator'>โ‹„</span> <span class='Function'>=</span> <span class='Paren'>(</span> <span class='String'>&quot;โ‹„&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;,&quot;</span> <span class='Function'>|</span> <span class='Value'>\n</span> <span class='Paren'>)</span><span class='Function'>+</span>
<span class='Function'>EXPR</span> <span class='Function'>=</span> <span class='Value'>subExpr</span> <span class='Function'>|</span> <span class='Function'>FuncExpr</span> <span class='Function'>|</span> <span class='Modifier'>_m1Expr</span> <span class='Function'>|</span> <span class='Modifier2'>_m2Expr_</span>
</pre>
@@ -75,7 +76,7 @@
<span class='Modifier2'>_m2Head_</span> <span class='Function'>=</span> <span class='Value'>headW?</span> <span class='Function'>Mod2H1</span> <span class='Value'>headX</span>
</pre>
<p>A braced block contains bodies, which are lists of statements, separated by semicolons and possibly preceded by headers, which are separated from the body with a colon. Multiple bodies allow different handling for various cases, which are pattern-matched by headers. For an immediate block there are no inputs, so there can only be one possible case and one body. Functions and modifiers allow any number of &quot;matched&quot; bodies, with headers that have arguments, followed by at most two &quot;main&quot; bodies with either no headers or headers without arguments. If there is one main body, it is ambivalent, but two main bodies refer to the monadic and dyadic cases.</p>
-<pre><span class='Function'>BODY</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Function'>STMT</span> <span class='Separator'>โ‹„</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>EXPR</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span>
+<pre><span class='Function'>BODY</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Function'>BSTMT</span> <span class='Separator'>โ‹„</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>EXPR</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span>
<span class='Function'>FCase</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Function'>FuncHead</span> <span class='String'>&quot;:&quot;</span> <span class='Function'>BODY</span>
<span class='Modifier'>_mCase</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Modifier'>_m1Head</span> <span class='String'>&quot;:&quot;</span> <span class='Function'>BODY</span>
<span class='Modifier2'>_cCase_</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Modifier2'>_m2Head_</span> <span class='String'>&quot;:&quot;</span> <span class='Function'>BODY</span>
@@ -87,13 +88,13 @@
<span class='Modifier'>_brMod1</span> <span class='Function'>=</span> <span class='String'>&quot;{&quot;</span> <span class='Paren'>(</span> <span class='Modifier'>_mCase</span> <span class='String'>&quot;;&quot;</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Paren'>(</span> <span class='Modifier'>_mCase</span> <span class='Function'>|</span> <span class='Modifier'>_mMain</span> <span class='Paren'>(</span> <span class='String'>&quot;;&quot;</span> <span class='Modifier'>_mMain</span> <span class='Paren'>)</span><span class='Value'>?</span> <span class='Paren'>)</span> <span class='String'>&quot;}&quot;</span>
<span class='Modifier2'>_brMod2_</span> <span class='Function'>=</span> <span class='String'>&quot;{&quot;</span> <span class='Paren'>(</span> <span class='Modifier2'>_cCase_</span> <span class='String'>&quot;;&quot;</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Paren'>(</span> <span class='Modifier2'>_cCase_</span> <span class='Function'>|</span> <span class='Modifier2'>_cMan_</span> <span class='Paren'>(</span> <span class='String'>&quot;;&quot;</span> <span class='Modifier2'>_cMan_</span> <span class='Paren'>)</span><span class='Value'>?</span> <span class='Paren'>)</span> <span class='String'>&quot;}&quot;</span>
</pre>
-<p>A namespace block is very similar in grammar to an ordinary immediate block, but allows export declarations with <code><span class='Gets'>โ‡</span></code>, either in place of the ordinary definition <code><span class='Gets'>โ†</span></code> or in the special <code><span class='Function'>EXPORT</span></code> statement. The arrow <code><span class='Gets'>โ‡</span></code> can also be placed in the header to mark a namespace block.</p>
+<p>A namespace block is very similar in grammar to an ordinary immediate block, but allows export declarations with <code><span class='Gets'>โ‡</span></code>, either in place of the ordinary definition <code><span class='Gets'>โ†</span></code> or in the special <code><span class='Function'>EXPORT</span></code> statement. The arrow <code><span class='Gets'>โ‡</span></code> can also be placed in the header to mark a namespace block. Since the block returns all exported values and not the result of the last line, the last line does not need to be an expression.</p>
<pre><span class='Function'>NS_STMT</span> <span class='Function'>=</span> <span class='Value'>nsLHS</span> <span class='Function'>ASGN</span> <span class='Value'>brNS</span>
<span class='Function'>NS_VAR</span> <span class='Function'>=</span> <span class='Function'>LHS_NAME</span> <span class='Paren'>(</span> <span class='String'>&quot;:&quot;</span> <span class='Value'>lhs</span> <span class='Paren'>)</span><span class='Value'>?</span>
<span class='Value'>nsLHS</span> <span class='Function'>=</span> <span class='Function'>LHS_NAME</span> <span class='Paren'>(</span> <span class='String'>&quot;โ€ฟ&quot;</span> <span class='Function'>LHS_NAME</span> <span class='Paren'>)</span><span class='Function'>+</span>
<span class='Function'>|</span> <span class='String'>&quot;โŸจ&quot;</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Paren'>(</span> <span class='Function'>NS_VAR</span> <span class='Separator'>โ‹„</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>NS_VAR</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>)</span><span class='Value'>?</span> <span class='String'>&quot;โŸฉ&quot;</span>
<span class='Function'>EXPORT</span> <span class='Function'>=</span> <span class='Paren'>(</span> <span class='Function'>LHS_NAME</span> <span class='Function'>|</span> <span class='Value'>lhsSub</span> <span class='Function'>|</span> <span class='Value'>lhsStr</span> <span class='Paren'>)</span> <span class='String'>&quot;โ‡&quot;</span>
-<span class='Function'>NS_BODY</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Paren'>(</span> <span class='Function'>STMT</span> <span class='Function'>|</span> <span class='Function'>EXPORT</span> <span class='Paren'>)</span> <span class='Separator'>โ‹„</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>EXPR</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span>
+<span class='Function'>NS_BODY</span> <span class='Function'>=</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Function'>STMT</span> <span class='Separator'>โ‹„</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>STMT</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span>
<span class='Value'>brNS</span> <span class='Function'>=</span> <span class='String'>&quot;{&quot;</span> <span class='Paren'>(</span> <span class='Separator'>โ‹„</span><span class='Value'>?</span> <span class='String'>&quot;โ‡&quot;</span><span class='Value'>?</span> <span class='Value'>s</span> <span class='String'>&quot;:&quot;</span> <span class='Paren'>)</span><span class='Value'>?</span> <span class='Function'>NS_BODY</span> <span class='String'>&quot;}&quot;</span>
</pre>
<p>Two additional rules apply to blocks, based on the special name associations in the table below. First, each block allows the special names in its column to be used as the given token types within <code><span class='Function'>BODY</span></code> terms (not headers). Except for the spaces labelled &quot;None&quot;, each column is cumulative and a given entry also includes all the entries above it up to the next &quot;None&quot;. Second, for <code><span class='Function'>BrFunc</span></code>, <code><span class='Modifier'>_brMod1</span></code>, <code><span class='Modifier2'>_brMod2_</span></code>, and <code><span class='Value'>brNS</span></code> terms, if no header is given (or, for <code><span class='Value'>brNS</span></code>, if the header does not contain <code><span class='String'>&quot;โ‡&quot;</span></code>), then at least one <code><span class='Function'>BODY</span></code> term in it <em>must</em> contain one of the tokens on, and not above, the corresponding row. Otherwise the syntax would be ambiguous, since for example a simple <code><span class='String'>&quot;{&quot;</span> <span class='Function'>BODY</span> <span class='String'>&quot;}&quot;</span></code> sequence could have any type.</p>