aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-12-27 21:22:26 -0500
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-12-27 21:22:32 -0500
commit1a5d020366463e8f1514f7ee9d181a0510593a51 (patch)
tree6c2fb768ee704946db02e030e5d3531355339fc5
parent9a3b5a1d5f711cf4762921be79cbf7df56d36323 (diff)
Compiler requires a complete Decompose implementation to run
-rw-r--r--docs/implementation/vm.html9
-rw-r--r--implementation/vm.md9
2 files changed, 8 insertions, 10 deletions
diff --git a/docs/implementation/vm.html b/docs/implementation/vm.html
index 6d6df758..07fd6e95 100644
--- a/docs/implementation/vm.html
+++ b/docs/implementation/vm.html
@@ -711,7 +711,7 @@
</tr>
</tbody>
</table>
-<p>To define the final two functions, call the second returned element as a function, with argument <code><span class='Function'>Decompose</span><span class='Ligature'>‿</span><span class='Function'>PrimInd</span></code>. The function <code><span class='Function'>PrimInd</span></code> gives the index of <code><span class='Value'>𝕩</span></code> in the list of all primitives (defined as <code><span class='Value'>glyphs</span></code> in pr.bqn), or the length of the runtime if <code><span class='Value'>𝕩</span></code> is not a primitive. The two functions are only needed for computing inferred properties, and are defined by default so that every value is assumed to be a primitive, and <code><span class='Function'>PrimInd</span></code> performs a linear search over the returned runtime. If the runtime is used directly, then this means that without setting <code><span class='Function'>Decompose</span><span class='Ligature'>‿</span><span class='Function'>PrimInd</span></code>, function inferred properties will work slowly and for primitives only; if values from the runtime are wrapped then function inferred properties will not work at all.</p>
+<p>To define the final two functions, call the second returned element as a function, with argument <code><span class='Function'>Decompose</span><span class='Ligature'>‿</span><span class='Function'>PrimInd</span></code>. The function <code><span class='Function'>PrimInd</span></code> gives the index of <code><span class='Value'>𝕩</span></code> in the list of all primitives (defined as <code><span class='Value'>glyphs</span></code> in pr.bqn), or the length of the runtime if <code><span class='Value'>𝕩</span></code> is not a primitive. The two functions are only needed for computing inferred properties, and are defined by default so that every value is assumed to be a primitive, and <code><span class='Function'>PrimInd</span></code> performs a linear search over the returned runtime. If the runtime is used directly, then this means that without setting <code><span class='Function'>Decompose</span><span class='Ligature'>‿</span><span class='Function'>PrimInd</span></code>, function inferred properties will work slowly and for primitives only; if values from the runtime are wrapped then function inferred properties will not work at all. The compiler uses Under with compound right operands, so <code><span class='Function'>Decompose</span></code> is needed to self-host.</p>
<p>Remember that <code><span class='Function'>+</span></code> and <code><span class='Function'>-</span></code> can also work on characters in some circumstances, under the rules of affine characters. Other arithmetic functions should only accept numbers. <code><span class='Function'>=</span></code> must work on any atoms including functions and modifiers. <code><span class='Function'>≤</span></code> must work on numbers and characters.</p>
<h3 id="grouplen-and-groupord"><a class="header" href="#grouplen-and-groupord">GroupLen and GroupOrd</a></h3>
<p>GroupLen and GroupOrd, short for Group length and Group order, are used to implement <a href="../doc/group.html">Group</a> (<code><span class='Function'>⊔</span></code>) and also to grade small-range lists and invert permutations (the inverse of a permutation <code><span class='Value'>p</span></code> is <code><span class='Number'>1</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>GroupOrd</span> <span class='Value'>p</span></code>). Each of these only needs to work on lists of integers. Shown below are efficient implementations using BQN extended with the notation <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>l</span><span class='Paren'>)</span> <span class='Function'>Fn</span><span class='Gets'>↩</span> <span class='Value'>x</span></code> meaning <code><span class='Value'>l</span> <span class='Gets'>↩</span> <span class='Function'>Fn</span><span class='Modifier2'>⟜</span><span class='Value'>x</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>i</span><span class='Modifier2'>⊸</span><span class='Function'>⊑</span><span class='Paren'>)</span> <span class='Value'>l</span></code>, where <code><span class='Function'>Fn</span></code> is <code><span class='Function'>⊢</span></code> if omitted. Since these special assignments only change one element of <code><span class='Value'>l</span></code>, each can be a fast constant-time operation.</p>
@@ -748,7 +748,7 @@
<p>The following steps give a working BQN system, assuming a working VM and core runtime:</p>
<ul>
<li>Evaluate the bytecode <code><span class='Value'>$</span> <span class='Value'>src</span><span class='Function'>/</span><span class='Value'>cjs.bqn</span> <span class='Value'>r</span></code>, passing the core runtime <code><span class='Value'>provide</span></code> in the constants array. The result is a BQN list of a full runtime, a function <code><span class='Function'>SetPrims</span></code>, and a function <code><span class='Function'>SetInv</span></code>.</li>
-<li>Optionally, call <code><span class='Function'>SetPrims</span></code> on a two-element list <code><span class='Bracket'>⟨</span><span class='Function'>Decompose</span><span class='Separator'>,</span> <span class='Function'>PrimInd</span><span class='Bracket'>⟩</span></code>.</li>
+<li>Call <code><span class='Function'>SetPrims</span></code> on a two-element list <code><span class='Bracket'>⟨</span><span class='Function'>Decompose</span><span class='Separator'>,</span> <span class='Function'>PrimInd</span><span class='Bracket'>⟩</span></code>.</li>
<li>Optionally, call <code><span class='Function'>SetInv</span></code> with a function <code><span class='Value'>𝕩</span></code> that updates <code><span class='Function'>Inverse</span></code> and (more optionally) a function <code><span class='Value'>𝕨</span></code> that updates <code><span class='Function'>SwapInverse</span></code>.</li>
<li>Evaluate the bytecode <code><span class='Value'>$</span> <span class='Value'>src</span><span class='Function'>/</span><span class='Value'>cjs.bqn</span> <span class='Value'>c</span></code>, which uses primitives from the runtime in its constants array. This is the compiler.</li>
<li>Evaluate the bytecode <code><span class='Value'>$</span> <span class='Value'>src</span><span class='Function'>/</span><span class='Value'>cjs.bqn</span> <span class='Value'>f</span></code>. This returns a function. Then call it on a four-element list <code><span class='Bracket'>⟨</span><span class='Function'>Type</span><span class='Separator'>,</span> <span class='Function'>Decompose</span><span class='Separator'>,</span> <span class='Function'>Glyph</span><span class='Separator'>,</span> <span class='Function'>FmtNum</span><span class='Bracket'>⟩</span></code> to obtain the two-element list <code><span class='Bracket'>⟨</span><span class='Function'>•Fmt</span><span class='Separator'>,</span> <span class='Function'>•Repr</span><span class='Bracket'>⟩</span></code>.</li>
@@ -762,8 +762,7 @@
<li>Test the virtual machine with the output of <code><span class='Value'>src</span><span class='Function'>/</span><span class='Value'>cjs.bqn</span></code> on the primitive-less test expressions in <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../test/cases/bytecode.bqn">test/cases/bytecode.bqn</a>.</li>
<li>There isn't currently a test suite for provided functions (although <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../test/cases/simple.bqn">test/cases/simple.bqn</a> has some suitable tests for arithmetic): your options are to write tests based on knowledge of these functions and primitive tests, or try to load the runtime and work backwards from any failures. The r1 runtime runs code to initialize some primitive lookup tables so failures are likely.</li>
<li>Once the runtime is loaded, begin working through the tests in <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../test/cases/prim.bqn">test/cases/prim.bqn</a> with the full runtime but no self-hosted compiler.</li>
-<li>After primitive tests pass, try to load the compiler, and run it on a short expression. If it runs, you have a complete (not necessarily correct) system, and remaining tests can be run end-to-end!</li>
<li>Now, if you haven't already, add a call to <code><span class='Function'>SetPrims</span></code>. Test for inferred properties: identity, under, and undo.</li>
-<li>If all tests pass you can probably compile the compiler.</li>
-<li>Headers and namespace support aren't required to support the runtime or compiler, but they can be tested as you add them with the header and namespace tests.</li>
+<li>After primitive and inferred tests pass, try to load the compiler, and run it on a short expression. If it runs, you have a complete (not necessarily correct) system, and remaining tests can be run end-to-end!</li>
+<li>Headers and namespace support aren't required to support the runtime or compiler, but they can be tested as you add them with the header and namespace tests. Undo headers are tested with the unhead tests.</li>
</ul>
diff --git a/implementation/vm.md b/implementation/vm.md
index 32da6f88..89f2ef17 100644
--- a/implementation/vm.md
+++ b/implementation/vm.md
@@ -210,7 +210,7 @@ The contents of a core runtime are given below. The names given are those used i
| — | `Decompose`| `•Decompose`
| — | `PrimInd` | Index for primitive `𝕩`
-To define the final two functions, call the second returned element as a function, with argument `Decompose‿PrimInd`. The function `PrimInd` gives the index of `𝕩` in the list of all primitives (defined as `glyphs` in pr.bqn), or the length of the runtime if `𝕩` is not a primitive. The two functions are only needed for computing inferred properties, and are defined by default so that every value is assumed to be a primitive, and `PrimInd` performs a linear search over the returned runtime. If the runtime is used directly, then this means that without setting `Decompose‿PrimInd`, function inferred properties will work slowly and for primitives only; if values from the runtime are wrapped then function inferred properties will not work at all.
+To define the final two functions, call the second returned element as a function, with argument `Decompose‿PrimInd`. The function `PrimInd` gives the index of `𝕩` in the list of all primitives (defined as `glyphs` in pr.bqn), or the length of the runtime if `𝕩` is not a primitive. The two functions are only needed for computing inferred properties, and are defined by default so that every value is assumed to be a primitive, and `PrimInd` performs a linear search over the returned runtime. If the runtime is used directly, then this means that without setting `Decompose‿PrimInd`, function inferred properties will work slowly and for primitives only; if values from the runtime are wrapped then function inferred properties will not work at all. The compiler uses Under with compound right operands, so `Decompose` is needed to self-host.
Remember that `+` and `-` can also work on characters in some circumstances, under the rules of affine characters. Other arithmetic functions should only accept numbers. `=` must work on any atoms including functions and modifiers. `≤` must work on numbers and characters.
@@ -257,7 +257,7 @@ BQN sources are compiled with [cjs.bqn](../src/cjs.bqn), which runs under [dzaim
The following steps give a working BQN system, assuming a working VM and core runtime:
* Evaluate the bytecode `$ src/cjs.bqn r`, passing the core runtime `provide` in the constants array. The result is a BQN list of a full runtime, a function `SetPrims`, and a function `SetInv`.
-* Optionally, call `SetPrims` on a two-element list `⟨Decompose, PrimInd⟩`.
+* Call `SetPrims` on a two-element list `⟨Decompose, PrimInd⟩`.
* Optionally, call `SetInv` with a function `𝕩` that updates `Inverse` and (more optionally) a function `𝕨` that updates `SwapInverse`.
* Evaluate the bytecode `$ src/cjs.bqn c`, which uses primitives from the runtime in its constants array. This is the compiler.
* Evaluate the bytecode `$ src/cjs.bqn f`. This returns a function. Then call it on a four-element list `⟨Type, Decompose, Glyph, FmtNum⟩` to obtain the two-element list `⟨•Fmt, •Repr⟩`.
@@ -275,7 +275,6 @@ Because the compiler works almost entirely with lists of numbers, a correct fill
* Test the virtual machine with the output of `src/cjs.bqn` on the primitive-less test expressions in [test/cases/bytecode.bqn](../test/cases/bytecode.bqn).
* There isn't currently a test suite for provided functions (although [test/cases/simple.bqn](../test/cases/simple.bqn) has some suitable tests for arithmetic): your options are to write tests based on knowledge of these functions and primitive tests, or try to load the runtime and work backwards from any failures. The r1 runtime runs code to initialize some primitive lookup tables so failures are likely.
* Once the runtime is loaded, begin working through the tests in [test/cases/prim.bqn](../test/cases/prim.bqn) with the full runtime but no self-hosted compiler.
-* After primitive tests pass, try to load the compiler, and run it on a short expression. If it runs, you have a complete (not necessarily correct) system, and remaining tests can be run end-to-end!
* Now, if you haven't already, add a call to `SetPrims`. Test for inferred properties: identity, under, and undo.
-* If all tests pass you can probably compile the compiler.
-* Headers and namespace support aren't required to support the runtime or compiler, but they can be tested as you add them with the header and namespace tests.
+* After primitive and inferred tests pass, try to load the compiler, and run it on a short expression. If it runs, you have a complete (not necessarily correct) system, and remaining tests can be run end-to-end!
+* Headers and namespace support aren't required to support the runtime or compiler, but they can be tested as you add them with the header and namespace tests. Undo headers are tested with the unhead tests.