diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-09-05 22:51:15 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-09-05 22:58:40 -0400 |
| commit | 9327d48ba01c4d44f38745b6b907b93f49b54622 (patch) | |
| tree | 11639538cb3267a701029afec4e94ec6cd11e3b8 | |
| parent | 01b2c731cda913f78955024137c0468a03622358 (diff) | |
Separate WebAssembly prototype wc.bqn from dzaima/BQN backend dc.bqn
| -rwxr-xr-x | dc.bqn | 92 | ||||
| -rw-r--r-- | docs/running.html | 5 | ||||
| -rw-r--r-- | running.md | 6 | ||||
| -rwxr-xr-x | test/tw.js (renamed from test/t.js) | 2 | ||||
| -rw-r--r-- | wc.bqn | 86 | ||||
| -rwxr-xr-x | wcshim.bqn | 3 |
6 files changed, 103 insertions, 91 deletions
@@ -1,15 +1,13 @@ #! ./dzref -i←"⟨charGroups,Tokenize,ReadNum,Compile⟩" -⟨charGroups,Tokenize,ReadNum,Compile⟩ ← ⟨•path∾"src/c.bqn",i⟩ •EX •path∾"dzref" +# dzaima/BQN block headers are a little different from the version used +# in the Javascript implementation: +# - Types are f/m/d instead of 0/1/2 +# - dzaima/BQN uses variable names instead of counts (but we make the +# names up anyway, except for special names). -chF←"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!" -bF‿bM‿bC‿bS‿bG‿bB‿bL‿bO‿bI‿bU‿bD‿bN‿bA‿bP‿bW←≍¨˜⟜(+`≠↑0∾⊢)≠¨charGroups -M←1⊸⊑(0⊸≤∧>)-⟜⊑ -vi←+´≠¨9↑charGroups +compile ← ⟨•path∾"src/c.bqn","Compile"⟩ •EX •path∾"dzref" - -# Targetting dzaima/BQN bytecode: prims←⟨ +,-,×,÷,⋆,√,⌊,⌈,|,¬,∧,∨,<,>,≠,=,≤,≥,≡,≢,⊣,⊢,⥊,∾,≍,↑,↓,↕,⌽,⍉,/,⍋,⍒,⊏,⊑,⊐,⊒,∊,⍷,⊔,! ˙,˜,˘,¨,⌜,⁼,´,˝,` @@ -25,81 +23,3 @@ DRun←{ }¨blk •COMP ⟨bc,o,⟨⟩,blk⟩ } - - -# Targetting WebAssembly (very incomplete) -WParse←{ - a←𝕩M(2≍˜⊑bG)⋄at←1⌽a⋄𝕩/˜↩¬a⋄a/˜↩¬at - l←≠𝕩⋄sep←𝕩M bS⋄𝕩↩(bF⊑⊸+⊑chF⊐<'⊣')¨⌾(sep⊸/)𝕩⋄sep∨↩𝕩=2+⊑bB - o←𝕩=⊑bB⋄c←𝕩=1+⊑bB⋄v←a-˜𝕩≥vi⋄f←¬o∨c∨v∨sep - na←(2×sep)+f×1+l↑0∾c∨v - d←+`o-c⋄fe←(+`⌾((⍋d)⊸⊏)o)⊏l∾(⍋⊏⟜d)⊸⊏/c - fe⌊↩l-l↑⌽⌈`↕∘≠⊸×⌽1∾˜sep - sel←¬∘⊏⟜(o∨c)⊸/⍋((f×fe)⌈↕l)-+`f-l↑/⁼∧f/fe - sel⊸⊏¨𝕩‿na -} - -Base←{+⟜(𝕨⊸×)´𝕩} -Enc2←{2|⌊∘÷⟜2⍟(↕𝕨)𝕩} - -Hex←16 Base⟜⌽ (∾"0A"+⟜↕¨10‿6)⊸⊐ - -GenF64←{ - 0:8⥊0; - l←2(⌊⋆⁼)𝕩 - (Hex"44")∾2 Base˘8‿8⥊∾⟨¯52↑(0⌈l)Enc2𝕩,11 Enc2 1023+l,⥊0⟩ -} -MakeTab←{{⊑∘(∾⟜0)¨¯1↓(chF⊐𝕨)⊔○(∾⟜(≠chF))𝕩}○∾⟜(⥊¨∘⥊¨)˝⍉(2(÷˜∾⊣)≢)⊸⥊𝕩} -tab1←MakeTab⟨ - "⊣⊢" , 2⥊<⟨⟩ - "|-⌈⌊√" , (Hex"99")+(↕4)∾6 - "÷" , <(Hex"10")∾0 - "¬" , <∾⥊¨⟨Hex"9A",GenF64 1,Hex"A0"⟩ -⟩ -tab2←MakeTab⟨ - "⊣" , Hex"1A" - "+-×÷⌊⌈∧", (Hex"A0")+(↕6)∾2 - "¬" , <∾⥊¨⟨Hex"A1",GenF64 1,Hex"A0"⟩ - "∨" , <(Hex"10")∾1 -⟩ -fntab←⍉(0¨tab1)∾tab1≍tab2 -f64←127-3 - -GenFn←{ - ⟨t,r,nVar,lits⟩←Tokenize𝕩 - nLoc←nVar-𝕨⊢0 - t⊏˜↩⍋+`-˝(2‿3+⊑bB)=⌜t - nd←+´c←t=3+⊑bB - t↩((vi+nVar+≠lits)+↕∘≠)⌾(c⊸/)t - ⟨a,na⟩←WParse t - ops←⥊∾⟨ - ∾⟜(0⥊˜3∾˜vi-≠)fntab - ⍉(Hex¨"20"‿"22"‿"21")∾⌜↕nVar - ⊣⌜⟜(↕3)(GenF64∘ReadNum¨lits)∾(Hex"10")∾¨3+↕nd - ⟩ - (((≠∾∾)⟨nLoc∾f64⟩)∾(Hex"0B")∾˜∾)¨((⊢-˜¬×+`)a=2+⊑bB)⊔(na+3×a)⊏ops -} - -Gen←{ - LEB←{0:⥊0;128⊸+⌾(¯1⊸↓) 2 Base˘ (∨`⌾⌽∨˝˘)⊸/ 10‿7(⊣⥊×´⊸↑) 64 Enc2 𝕩} - C←LEB∘≠⊸∾ - S←∾⟜C - V←≠∾∾ - I←C-⟜@ - t‿n‿b←𝕩 - ∾⟨ - 0∾("asm"-@)∾4↑1 - 1 S V (96∾⟜∾C¨)¨t - 3 S V ⥊¨↕≠b - 7 S V ⥊<"fn"I⊸(⊣∾0∾⊢)n - 10 S V C¨ b - ⟩ -} - -rcp←1 GenFn "1÷x" -or ←2 GenFn "(w+x)-w∧x" -WCompile←{ - body←GenFn 𝕩 - f←⟨rcp,or,body⟩ - Gen ⟨(≠¨f)/(1‿2‿0∾¨1)⥊¨¨f64 ⋄ 2 ⋄ ∾f⟩ -} diff --git a/docs/running.html b/docs/running.html index c5c3771b..f199925b 100644 --- a/docs/running.html +++ b/docs/running.html @@ -7,8 +7,9 @@ <h1 id="how-to-run-bqn">How to run BQN</h1> <p>BQN is in an early stage of development, and no implementation is complete yet. However, it's a relatively simple language to implement, and a few implementations come close. At the moment, dzaima/BQN is the most usable version, with good performance and error reporting.</p> <h3 id="bqn">BQN</h3> -<p>This repository contains a BQN implementation written mainly in BQN: the bytecode <a href="https://github.com/mlochbaum/BQN/blob/master/src/c.bqn">compiler</a> is completely self-hosted, and the <a href="https://github.com/mlochbaum/BQN/blob/master/src/r.bqn">majority of the runtime</a> is written in BQN except that it is allowed to define primitives; some preprocessing turns the primitives into identifiers. The remaining part, a VM, can be implemented in any language to obtain a version of BQN running in that language. A <a href="https://github.com/mlochbaum/BQN/blob/master/docs/bqn.js">Javascript implementation</a> allows BQN to be run as a REPL (running locally) from <a href="https://mlochbaum.github.io/BQN/try.html">this webpage</a> or in Node.js as a library. The bytecode is also the same as dzaima/BQN's format, and <a href="https://github.com/mlochbaum/BQN/blob/master/dc.bqn">an extension</a> to the compiler adjusts the slightly different block declarations to target dzaima+reference BQN. This version also contains an earlier experiment targetting <a href="https://en.wikipedia.org/wiki/WebAssembly">WebAssembly</a> that works only on a very small subset of BQN.</p> -<p>This version is not yet suitable for serious programming. The runtime checks for errors but the compiler does not, so syntax errors go unreported. It does not yet support function headers or multiple bodies. The Javascript-based compiler is also slow, taking about 0.05 seconds plus 1 second per kilobyte of source (this is purely due to the slow runtime, as dzaima+reference achieves 3ms/kB with the same compiler once warmed up).</p> +<p>This repository contains a BQN implementation written mainly in BQN: the bytecode <a href="https://github.com/mlochbaum/BQN/blob/master/src/c.bqn">compiler</a> is completely self-hosted, and the <a href="https://github.com/mlochbaum/BQN/blob/master/src/r.bqn">majority of the runtime</a> is written in BQN except that it is allowed to define primitives; some preprocessing turns the primitives into identifiers. The remaining part, a VM, can be implemented in any language to obtain a version of BQN running in that language. A <a href="https://github.com/mlochbaum/BQN/blob/master/docs/bqn.js">Javascript implementation</a> allows BQN to be run as a <a href="https://mlochbaum.github.io/BQN/try.html">client-side REPL</a> or in Node.js as a library.</p> +<p>The bytecode is also the same as dzaima/BQN's format, and <a href="https://github.com/mlochbaum/BQN/blob/master/dc.bqn">an extension</a> to the compiler adjusts the slightly different block declarations to target dzaima+reference BQN. There is also <a href="https://github.com/mlochbaum/BQN/blob/master/wc.bqn">an earlier experiment</a> targetting <a href="https://en.wikipedia.org/wiki/WebAssembly">WebAssembly</a> that works only on a very small subset of BQN.</p> +<p>This version is not yet suitable for serious programming. The runtime has full error checking but the compiler does not, so syntax errors can go unreported. It does not yet support function headers or multiple bodies. The Javascript-based compiler is also slow, taking about 0.05 seconds plus 1 second per kilobyte of source (this is purely due to the slow runtime, as dzaima+reference achieves 3ms/kB with the same compiler once warmed up).</p> <p>All versions have automated tests in the <a href="https://github.com/mlochbaum/BQN/blob/master/test/">test</a> directory, with the self-hosted version (<a href="https://github.com/mlochbaum/BQN/blob/master/test/tj.js">test/tj.js</a>) and WebAssembly backend (<a href="https://github.com/mlochbaum/BQN/blob/master/test/t.js">test/t.js</a>) tested with Javascript using Node and the dzaima/BQN backend tested with BQN itself (<a href="https://github.com/mlochbaum/BQN/blob/master/test/bt">test/bt</a>).</p> <h3 id="dzaimabqn">dzaima/BQN</h3> <p><a href="https://github.com/dzaima/BQN/">dzaima/BQN</a> is an implementation in Java created by modifying the existing dzaima/APL. It should be easy to run on desktop Linux and Android. It is still in development and has almost complete syntax support but incomplete primitive support.</p> @@ -6,9 +6,11 @@ BQN is in an early stage of development, and no implementation is complete yet. ### BQN -This repository contains a BQN implementation written mainly in BQN: the bytecode [compiler](src/c.bqn) is completely self-hosted, and the [majority of the runtime](src/r.bqn) is written in BQN except that it is allowed to define primitives; some preprocessing turns the primitives into identifiers. The remaining part, a VM, can be implemented in any language to obtain a version of BQN running in that language. A [Javascript implementation](docs/bqn.js) allows BQN to be run as a REPL (running locally) from [this webpage](https://mlochbaum.github.io/BQN/try.html) or in Node.js as a library. The bytecode is also the same as dzaima/BQN's format, and [an extension](dc.bqn) to the compiler adjusts the slightly different block declarations to target dzaima+reference BQN. This version also contains an earlier experiment targetting [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly) that works only on a very small subset of BQN. +This repository contains a BQN implementation written mainly in BQN: the bytecode [compiler](src/c.bqn) is completely self-hosted, and the [majority of the runtime](src/r.bqn) is written in BQN except that it is allowed to define primitives; some preprocessing turns the primitives into identifiers. The remaining part, a VM, can be implemented in any language to obtain a version of BQN running in that language. A [Javascript implementation](docs/bqn.js) allows BQN to be run as a [client-side REPL](https://mlochbaum.github.io/BQN/try.html) or in Node.js as a library. -This version is not yet suitable for serious programming. The runtime checks for errors but the compiler does not, so syntax errors go unreported. It does not yet support function headers or multiple bodies. The Javascript-based compiler is also slow, taking about 0.05 seconds plus 1 second per kilobyte of source (this is purely due to the slow runtime, as dzaima+reference achieves 3ms/kB with the same compiler once warmed up). +The bytecode is also the same as dzaima/BQN's format, and [an extension](dc.bqn) to the compiler adjusts the slightly different block declarations to target dzaima+reference BQN. There is also [an earlier experiment](wc.bqn) targetting [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly) that works only on a very small subset of BQN. + +This version is not yet suitable for serious programming. The runtime has full error checking but the compiler does not, so syntax errors can go unreported. It does not yet support function headers or multiple bodies. The Javascript-based compiler is also slow, taking about 0.05 seconds plus 1 second per kilobyte of source (this is purely due to the slow runtime, as dzaima+reference achieves 3ms/kB with the same compiler once warmed up). All versions have automated tests in the [test](test/) directory, with the self-hosted version ([test/tj.js](test/tj.js)) and WebAssembly backend ([test/t.js](test/t.js)) tested with Javascript using Node and the dzaima/BQN backend tested with BQN itself ([test/bt](test/bt)). @@ -10,7 +10,7 @@ const t=load('cases.bqn').split('\n').filter(x=>x).map(x=>x.split(' % ')) , expt=t.map(e=>+e[0]) var compiler = execFile( - __dirname+'/../cshim.bqn', + __dirname+'/../wcshim.bqn', [ '{•←WCompile𝕩}¨⟨'+test+'⟩' ], function (error, stdout, stderr) { const rslt=stdout.split('\n').filter(a=>a.length) @@ -0,0 +1,86 @@ +#! ./dzref + +# WebAssembly backend (very incomplete) + +i←"⟨charGroups,Tokenize,ReadNum⟩" +⟨charGroups,Tokenize,ReadNum⟩ ← ⟨•path∾"src/c.bqn",i⟩ •EX •path∾"dzref" +chF←"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!" +bF‿bM‿bC‿bS‿bG‿bB‿bL‿bO‿bI‿bU‿bD‿bN‿bA‿bP‿bW←≍¨˜⟜(+`≠↑0∾⊢)≠¨charGroups +M←1⊸⊑(0⊸≤∧>)-⟜⊑ +vi←+´≠¨9↑charGroups + +WParse←{ + a←𝕩M(2≍˜⊑bG)⋄at←1⌽a⋄𝕩/˜↩¬a⋄a/˜↩¬at + l←≠𝕩⋄sep←𝕩M bS⋄𝕩↩(bF⊑⊸+⊑chF⊐<'⊣')¨⌾(sep⊸/)𝕩⋄sep∨↩𝕩=2+⊑bB + o←𝕩=⊑bB⋄c←𝕩=1+⊑bB⋄v←a-˜𝕩≥vi⋄f←¬o∨c∨v∨sep + na←(2×sep)+f×1+l↑0∾c∨v + d←+`o-c⋄fe←(+`⌾((⍋d)⊸⊏)o)⊏l∾(⍋⊏⟜d)⊸⊏/c + fe⌊↩l-l↑⌽⌈`↕∘≠⊸×⌽1∾˜sep + sel←¬∘⊏⟜(o∨c)⊸/⍋((f×fe)⌈↕l)-+`f-l↑/⁼∧f/fe + sel⊸⊏¨𝕩‿na +} + +Base←{+⟜(𝕨⊸×)´𝕩} +Enc2←{2|⌊∘÷⟜2⍟(↕𝕨)𝕩} + +Hex←16 Base⟜⌽ (∾"0A"+⟜↕¨10‿6)⊸⊐ + +GenF64←{ + 0:8⥊0; + l←2(⌊⋆⁼)𝕩 + (Hex"44")∾2 Base˘8‿8⥊∾⟨¯52↑(0⌈l)Enc2𝕩,11 Enc2 1023+l,⥊0⟩ +} +MakeTab←{{⊑∘(∾⟜0)¨¯1↓(chF⊐𝕨)⊔○(∾⟜(≠chF))𝕩}○∾⟜(⥊¨∘⥊¨)˝⍉(2(÷˜∾⊣)≢)⊸⥊𝕩} +tab1←MakeTab⟨ + "⊣⊢" , 2⥊<⟨⟩ + "|-⌈⌊√" , (Hex"99")+(↕4)∾6 + "÷" , <(Hex"10")∾0 + "¬" , <∾⥊¨⟨Hex"9A",GenF64 1,Hex"A0"⟩ +⟩ +tab2←MakeTab⟨ + "⊣" , Hex"1A" + "+-×÷⌊⌈∧", (Hex"A0")+(↕6)∾2 + "¬" , <∾⥊¨⟨Hex"A1",GenF64 1,Hex"A0"⟩ + "∨" , <(Hex"10")∾1 +⟩ +fntab←⍉(0¨tab1)∾tab1≍tab2 +f64←127-3 + +GenFn←{ + ⟨t,r,nVar,lits⟩←Tokenize𝕩 + nLoc←nVar-𝕨⊢0 + t⊏˜↩⍋+`-˝(2‿3+⊑bB)=⌜t + nd←+´c←t=3+⊑bB + t↩((vi+nVar+≠lits)+↕∘≠)⌾(c⊸/)t + ⟨a,na⟩←WParse t + ops←⥊∾⟨ + ∾⟜(0⥊˜3∾˜vi-≠)fntab + ⍉(Hex¨"20"‿"22"‿"21")∾⌜↕nVar + ⊣⌜⟜(↕3)(GenF64∘ReadNum¨lits)∾(Hex"10")∾¨3+↕nd + ⟩ + (((≠∾∾)⟨nLoc∾f64⟩)∾(Hex"0B")∾˜∾)¨((⊢-˜¬×+`)a=2+⊑bB)⊔(na+3×a)⊏ops +} + +Gen←{ + LEB←{0:⥊0;128⊸+⌾(¯1⊸↓) 2 Base˘ (∨`⌾⌽∨˝˘)⊸/ 10‿7(⊣⥊×´⊸↑) 64 Enc2 𝕩} + C←LEB∘≠⊸∾ + S←∾⟜C + V←≠∾∾ + I←C-⟜@ + t‿n‿b←𝕩 + ∾⟨ + 0∾("asm"-@)∾4↑1 + 1 S V (96∾⟜∾C¨)¨t + 3 S V ⥊¨↕≠b + 7 S V ⥊<"fn"I⊸(⊣∾0∾⊢)n + 10 S V C¨ b + ⟩ +} + +rcp←1 GenFn "1÷x" +or ←2 GenFn "(w+x)-w∧x" +WCompile←{ + body←GenFn 𝕩 + f←⟨rcp,or,body⟩ + Gen ⟨(≠¨f)/(1‿2‿0∾¨1)⥊¨¨f64 ⋄ 2 ⋄ ∾f⟩ +} diff --git a/wcshim.bqn b/wcshim.bqn new file mode 100755 index 00000000..97b85cfd --- /dev/null +++ b/wcshim.bqn @@ -0,0 +1,3 @@ +#! /usr/bin/env dbqn + +((<•path∾"wc.bqn")∾•args) •EX •path∾"dzref" |
