aboutsummaryrefslogtreecommitdiff
path: root/docs/tutorial
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2020-10-30 16:08:14 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2020-10-30 16:44:38 -0400
commitff1453f2e2d086a984905bbb85a89712ea3c78bb (patch)
tree22fda7a1a1e79b72d284ef404ce8631c781c9cd4 /docs/tutorial
parentce0172e50c173b4415bed89997603b09e158105f (diff)
Generate expression displays from compiled bytecode, not an ad-hoc parser
Diffstat (limited to 'docs/tutorial')
-rw-r--r--docs/tutorial/expression.html150
1 files changed, 91 insertions, 59 deletions
diff --git a/docs/tutorial/expression.html b/docs/tutorial/expression.html
index cea81292..22da2272 100644
--- a/docs/tutorial/expression.html
+++ b/docs/tutorial/expression.html
@@ -119,37 +119,37 @@
<g font-family='BQN,monospace' font-size='18px'>
<rect class='code' stroke-width='1' rx='10' x='-21.5' y='-24' width='204.25' height='168'/>
<text><tspan class='Paren'>(</tspan><tspan class='Number'>4</tspan><tspan class='Function'>÷</tspan><tspan class='Number'>3</tspan><tspan class='Paren'>)</tspan> <tspan class='Function'>×</tspan> <tspan class='Number'>π</tspan> <tspan class='Function'>×</tspan> <tspan class='Number'>2</tspan><tspan class='Function'>⋆</tspan><tspan class='Number'>3</tspan></text>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M17.2 2.4v72h10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M27.95 74.4v24h43'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M38.7 2.4v72h-10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M70.95 98.4v24h-77.938'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M92.45 2.4v48h21.5'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M113.95 50.4v48h-43'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M135.45 2.4v24h10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M146.2 26.4v24h-32.25'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M156.95 2.4v24h-10.75'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M156.95 2.4V26.4H146.2'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M135.45 2.4V26.4H146.2'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M146.2 26.4V50.4H113.95'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M92.45 2.4V50.4H113.95'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M113.95 50.4V98.4H70.95'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M38.7 2.4V74.4H27.95'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M17.2 2.4V74.4H27.95'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M27.95 74.4V98.4H70.95'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M70.95 98.4V122.4H-6.987'/>
<g text-anchor='middle'>
<g class='codeCover' stroke-width='6' stroke-linejoin='round'>
- <text x='17.125' y='81'>4</text>
- <text x='27.875' y='81'>÷</text>
- <text x='38.625' y='81'>3</text>
- <text x='70.875' y='105'>×</text>
- <text x='92.375' y='57'>π</text>
- <text x='113.875' y='57'>×</text>
- <text x='135.375' y='33'>2</text>
- <text x='146.125' y='33'>⋆</text>
<text x='156.875' y='33'>3</text>
+ <text x='146.125' y='33'>⋆</text>
+ <text x='135.375' y='33'>2</text>
+ <text x='113.875' y='57'>×</text>
+ <text x='92.375' y='57'>π</text>
+ <text x='70.875' y='105'>×</text>
+ <text x='38.625' y='81'>3</text>
+ <text x='27.875' y='81'>÷</text>
+ <text x='17.125' y='81'>4</text>
</g>
<g font-size='15px' opacity='0.9'>
- <text x='17.125' y='79'><tspan class='Number'>4</tspan></text>
- <text x='27.875' y='79'><tspan class='Function'>÷</tspan></text>
- <text x='38.625' y='79'><tspan class='Number'>3</tspan></text>
- <text x='70.875' y='103'><tspan class='Function'>×</tspan></text>
- <text x='92.375' y='55'><tspan class='Number'>π</tspan></text>
- <text x='113.875' y='55'><tspan class='Function'>×</tspan></text>
- <text x='135.375' y='31'><tspan class='Number'>2</tspan></text>
- <text x='146.125' y='31'><tspan class='Function'>⋆</tspan></text>
<text x='156.875' y='31'><tspan class='Number'>3</tspan></text>
+ <text x='146.125' y='31'><tspan class='Function'>⋆</tspan></text>
+ <text x='135.375' y='31'><tspan class='Number'>2</tspan></text>
+ <text x='113.875' y='55'><tspan class='Function'>×</tspan></text>
+ <text x='92.375' y='55'><tspan class='Number'>π</tspan></text>
+ <text x='70.875' y='103'><tspan class='Function'>×</tspan></text>
+ <text x='38.625' y='79'><tspan class='Number'>3</tspan></text>
+ <text x='27.875' y='79'><tspan class='Function'>÷</tspan></text>
+ <text x='17.125' y='79'><tspan class='Number'>4</tspan></text>
</g>
</g>
</g>
@@ -172,46 +172,46 @@
<g font-family='BQN,monospace' font-size='18px'>
<rect class='code' stroke-width='1' rx='10' x='-21.5' y='-24' width='236.5' height='190'/>
<text><tspan class='Paren'>(</tspan><tspan class='Function'>√</tspan><tspan class='Number'>3</tspan> <tspan class='Function'>+</tspan> <tspan class='Number'>2</tspan><tspan class='Function'>×√</tspan><tspan class='Number'>2</tspan><tspan class='Paren'>)</tspan> <tspan class='Function'>-</tspan> <tspan class='Number'>1</tspan><tspan class='Function'>+√</tspan><tspan class='Number'>2</tspan></text>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M17.2 115.9v19h118.25'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M27.95 1.9v95h21.5'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M49.45 96.9v19h-32.25'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M70.95 1.9v76h10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M81.7 77.9v19h-32.25'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M92.45 58.9v19h-10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M103.2 1.9v57h-10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M135.45 134.9v19h-142.437'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M156.95 1.9v38h10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M167.7 39.9v95h-32.25'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M178.45 20.9v19h-10.75'/>
- <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M189.2 1.9v19h-10.75'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M189.2 1.9V20.9H178.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M178.45 20.9V39.9H167.7'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M156.95 1.9V39.9H167.7'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M167.7 39.9V134.9H135.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M103.2 1.9V58.9H92.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M92.45 58.9V77.9H81.7'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M70.95 1.9V77.9H81.7'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M81.7 77.9V96.9H49.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M27.95 1.9V96.9H49.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M49.45 96.9V115.9H17.2'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M17.2 115.9V134.9H135.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M135.45 134.9V153.9H-6.987'/>
<g text-anchor='middle'>
<g class='codeCover' stroke-width='6' stroke-linejoin='round'>
- <text x='17.125' y='123'>√</text>
- <text x='27.875' y='104'>3</text>
- <text x='49.375' y='104'>+</text>
- <text x='70.875' y='85'>2</text>
- <text x='81.625' y='85'>×</text>
- <text x='92.375' y='66'>√</text>
- <text x='103.125' y='66'>2</text>
- <text x='135.375' y='142'>-</text>
- <text x='156.875' y='47'>1</text>
- <text x='167.625' y='47'>+</text>
- <text x='178.375' y='28'>√</text>
<text x='189.125' y='28'>2</text>
+ <text x='178.375' y='28'>√</text>
+ <text x='167.625' y='47'>+</text>
+ <text x='156.875' y='47'>1</text>
+ <text x='135.375' y='142'>-</text>
+ <text x='103.125' y='66'>2</text>
+ <text x='92.375' y='66'>√</text>
+ <text x='81.625' y='85'>×</text>
+ <text x='70.875' y='85'>2</text>
+ <text x='49.375' y='104'>+</text>
+ <text x='27.875' y='104'>3</text>
+ <text x='17.125' y='123'>√</text>
</g>
<g font-size='15px' opacity='0.9'>
- <text x='17.125' y='121'><tspan class='Function'>√</tspan></text>
- <text x='27.875' y='102'><tspan class='Number'>3</tspan></text>
- <text x='49.375' y='102'><tspan class='Function'>+</tspan></text>
- <text x='70.875' y='83'><tspan class='Number'>2</tspan></text>
- <text x='81.625' y='83'><tspan class='Function'>×</tspan></text>
- <text x='92.375' y='64'><tspan class='Function'>√</tspan></text>
- <text x='103.125' y='64'><tspan class='Number'>2</tspan></text>
- <text x='135.375' y='140'><tspan class='Function'>-</tspan></text>
- <text x='156.875' y='45'><tspan class='Number'>1</tspan></text>
- <text x='167.625' y='45'><tspan class='Function'>+</tspan></text>
- <text x='178.375' y='26'><tspan class='Function'>√</tspan></text>
<text x='189.125' y='26'><tspan class='Number'>2</tspan></text>
+ <text x='178.375' y='26'><tspan class='Function'>√</tspan></text>
+ <text x='167.625' y='45'><tspan class='Function'>+</tspan></text>
+ <text x='156.875' y='45'><tspan class='Number'>1</tspan></text>
+ <text x='135.375' y='140'><tspan class='Function'>-</tspan></text>
+ <text x='103.125' y='64'><tspan class='Number'>2</tspan></text>
+ <text x='92.375' y='64'><tspan class='Function'>√</tspan></text>
+ <text x='81.625' y='83'><tspan class='Function'>×</tspan></text>
+ <text x='70.875' y='83'><tspan class='Number'>2</tspan></text>
+ <text x='49.375' y='102'><tspan class='Function'>+</tspan></text>
+ <text x='27.875' y='102'><tspan class='Number'>3</tspan></text>
+ <text x='17.125' y='121'><tspan class='Function'>√</tspan></text>
</g>
</g>
</g>
@@ -351,6 +351,38 @@
<span class='Modifier2'>∘</span><span class='Function'>+</span>
<span class='Number'>3</span> <span class='Number'>4</span>
</pre>
+<svg viewBox='-213 -34 512 134'>
+ <g font-family='BQN,monospace' font-size='18px'>
+ <rect class='code' stroke-width='1' rx='10' x='-21.5' y='-24' width='129' height='114'/>
+ <text><tspan class='Number'>3</tspan> <tspan class='Function'>×</tspan><tspan class='Modifier'>˜</tspan><tspan class='Modifier2'>∘</tspan><tspan class='Function'>+</tspan> <tspan class='Number'>4</tspan></text>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M81.7 1.9V58.9H49.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M60.2 1.9V39.9H49.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M27.95 1.9V20.9H38.7'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M38.7 20.9V39.9H49.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M49.45 39.9V58.9H49.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M6.45 1.9V58.9H49.45'/>
+ <path class='Paren' stroke='currentColor' fill='none' stroke-width='1' d='M49.45 58.9V77.9H-6.987'/>
+ <g text-anchor='middle'>
+ <g class='codeCover' stroke-width='6' stroke-linejoin='round'>
+ <text x='81.625' y='66'>4</text>
+ <text x='60.125' y='47'>+</text>
+ <text x='49.375' y='47'>∘</text>
+ <text x='38.625' y='28'>˜</text>
+ <text x='27.875' y='28'>×</text>
+ <text x='6.375' y='66'>3</text>
+ </g>
+ <g font-size='15px' opacity='0.9'>
+ <text x='81.625' y='64'><tspan class='Number'>4</tspan></text>
+ <text x='60.125' y='45'><tspan class='Function'>+</tspan></text>
+ <text x='49.375' y='45'><tspan class='Modifier2'>∘</tspan></text>
+ <text x='38.625' y='26'><tspan class='Modifier'>˜</tspan></text>
+ <text x='27.875' y='26'><tspan class='Function'>×</tspan></text>
+ <text x='6.375' y='64'><tspan class='Number'>3</tspan></text>
+ </g>
+ </g>
+ </g>
+</svg>
+
<p>This ordering is more consistent with the fact that the operand of a 1-modifier goes to its left. If we tried going from right to left we'd end up with <code><span class='Function'>×</span><span class='Paren'>(</span><span class='Modifier'>˜</span><span class='Modifier2'>∘</span><span class='Function'>+</span><span class='Paren'>)</span></code>, which uses <code><span class='Modifier'>˜</span></code> as an operand to <code><span class='Modifier2'>∘</span></code>. But a modifier can't be used as an operand. To make it work we'd essentially have to give 1-modifiers a higher precedence than 2-modifiers.</p>
<p>In fact, the rules for modifiers are exactly the same as those for functions, but reversed. So why is there a distinction between 1- and 2-modifiers, when for functions we can look to the left to see whether there is a left argument? The reason is that it's natural to follow a 1-modifier by a subject or function that isn't supposed to be its operand. Using an example from the last section, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Number'>3</span></code> has a subject to the right of the 1-modifier <code><span class='Modifier'>˜</span></code>. Even worse, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Function'>÷</span> <span class='Number'>3</span></code> looks the same syntactically as <code><span class='Function'>+</span><span class='Modifier2'>∘</span> <span class='Function'>÷</span> <span class='Number'>3</span></code>, but it's two functions <code><span class='Function'>+</span><span class='Modifier'>˜</span></code> and <code><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code> while the version with Atop is a single function <code><span class='Function'>+</span><span class='Modifier2'>∘</span><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code>. So the two-layer system of functions and modifiers forces modifiers to have a fixed number of operands even every function (including those derived by applying modifiers) can be called with one or two arguments.</p>
<p>Remember that 1-modifiers are all superscripts? The characters for 2-modifiers use a different rule: each contains an <em>unbroken</em> circle (that is, lines might touch it but not go through it). The 2-modifiers in BQN are the combinators <code><span class='Modifier2'>∘○⊸⟜⌾</span></code>, the sort-of-combinators <code><span class='Modifier2'>⊘◶⍟</span></code>, and the not-at-all-combinators <code><span class='Modifier2'>⎉⚇⎊</span></code>. And the functions that make that unbroken circle rule necessary are written <code><span class='Function'>⌽⍉</span></code>. Since every primitive is a function, 1-modifier, or 2-modifier, you can always tell what type (and role) it has: a superscript is a 1-modifier, an unbroken circle makes it a 2-modifier, and otherwise it's a function.</p>