diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-07-17 07:28:21 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-07-17 08:06:17 -0400 |
| commit | 357a9ab4e25a0101121761c503e14ba38d32093c (patch) | |
| tree | 0cdaedd3eca6f3854a82f86ea50bb231e68ad2dc | |
| parent | 5c4a7106dc47e2e1849eddf4d87fb0e107461d74 (diff) | |
Move some files around
| -rw-r--r-- | README.md | 2 | ||||
| -rwxr-xr-x | c.bqn | 160 | ||||
| -rwxr-xr-x | cshim.bqn | 3 | ||||
| -rwxr-xr-x | dc.bqn | 177 | ||||
| -rwxr-xr-x | dcshim.bqn | 3 | ||||
| -rwxr-xr-x | doc/gen | 2 | ||||
| -rw-r--r-- | doc/md.bqn | 2 | ||||
| -rwxr-xr-x | dzref (renamed from spec/dzref) | 0 | ||||
| -rwxr-xr-x | nc.bqn | 124 | ||||
| -rw-r--r-- | running.md | 2 | ||||
| -rwxr-xr-x | test/bt | 2 | ||||
| -rwxr-xr-x | test/dt.js | 26 | ||||
| -rwxr-xr-x | test/nt.js | 19 | ||||
| -rwxr-xr-x | test/t.js | 29 |
14 files changed, 277 insertions, 274 deletions
@@ -30,7 +30,7 @@ Rather strange, most likely: ⊑+`∘⌽⍟12↕2 # The 12th Fibonacci number -For longer samples, you can [gaze into the abyss](dc.bqn) that is the (incomplete) self-hosted compiler, or take a look at [some translations](examples/fifty.bqn) from ["A History of APL in 50 Functions"](https://www.jsoftware.com/papers/50/). While it's certainly possible to write BQN in a more spread-out and better commented style, nobody has done that to date. +For longer samples, you can [gaze into the abyss](c.bqn) that is the (incomplete) self-hosted compiler, or take a look at [some translations](examples/fifty.bqn) from ["A History of APL in 50 Functions"](https://www.jsoftware.com/papers/50/). While it's certainly possible to write BQN in a more spread-out and better commented style, nobody has done that to date. ## Array model @@ -1,71 +1,85 @@ -#!/usr/bin/env bqn +#! ./dzref -reduce←{r←𝕩⋄{(>𝔽¨_r)⍠(><⊸(𝔽¨_r))}}⊑⟨´⟩ -´↩_reduce -⊔↩((↕1+⌈´)=¨<)∘⊣ /¨⟜< ↕∘≠⍠⊢ -⍷↩∪ - -Base←{+⟜(𝕨⊸×)´⌽𝕩} -Enc2←{𝕨⥊2(|∾˜(𝕨-1)Enc2⌊∘÷˜)⍟(0<𝕨)𝕩} - -lf‿tab←•UCS 10‿9 +nl‿tab←•UCS 10‿9 charSet←∾charGroups←⟨ - chF←"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔" ⍝ Function - "˜˘¨⌜⁼´`" ⍝ Modifier - "∘○⊸⟜⌾⊘◶⎉⚇⍟" ⍝ Composition - "𝕨𝕎𝕩𝕏𝕗𝔽𝕘𝔾" ⍝ Input - lf∾"⋄," ⍝ Separator - "←↩→" ⍝ Gets - "(){}⟨⟩" ⍝ Bracket - "‿" ⍝ Ligature - •d ⍝ +⟜(↕10)⌾•UCS'0' ⍝ Digit - "¯.π∞" ⍝ Numeric - "_"∾' '(⊢∾+)⌾•UCS•a ⍝ Alphabetic - " "∾tab ⍝ Whitespace -⍝ #'" eliminated during tokenization + chF←"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!" # Function + "˜˘¨⌜⁼´`" # Modifier + "∘○⊸⟜⌾⊘◶⎉⚇⍟" # Composition + ¯1⊏˘10‿2⥊"𝕨𝕎𝕩𝕏𝕗𝔽𝕘𝔾𝕤𝕊" # Input (𝕣 pending; ℝ not allowed) + nl∾"⋄," # Separator + "←↩→" # Gets + "(){}⟨⟩" # Bracket + "‿" # Ligature + "·" # nOthing + •d # +⟜(↕10)⌾•UCS'0' # Digit + "¯.π∞" # Numeric + "_"∾˜' '(+∾⊢)⌾•UCS•a # Alphabetic + 1↑"𝕨" # Prefix for input (hack around UTF-16) + " "∾tab # Whitespace +# #'" eliminated during tokenization ⟩ -bF‿bM‿bC‿bI‿bS‿bG‿bB‿bL‿bD‿bN‿bA‿bW←⊔/≠¨charGroups -vi←+´≠¨8↑charGroups +bF‿bM‿bC‿bI‿bS‿bG‿bB‿bL‿bO‿bD‿bN‿bA‿bP‿bW←⊔/≠¨charGroups +vi←+´≠¨9↑charGroups +charRole←(vi+1)↑(/0∾≠¨3↑charGroups)∾10⥊↕2 Tokenize←{ - r←𝕩='#'⋄s←/(≠↑2⊸↓)⊸∧𝕩=⊑"'"⋄d←/𝕩='"' + r←𝕩='#'⋄s←/(≠↑2⊸↓)⊸∧𝕩='''⋄d←/𝕩='"' g←⍋q←∾⟨ s⋄¯1↓d⋄/r⟩ ⋄q↩g⊏q - e← g⊏∾⟨2+s⋄ 1↓d⋄(⊢-¯1↓0∾⊢)∘⊏⟜(0∾+`r)⊸//(𝕩=lf)∾1⟩ + e← g⊏∾⟨2+s⋄ 1↓d⋄(⊢-¯1↓0∾⊢)∘⊏⟜(0∾+`r)⊸//(𝕩=nl)∾1⟩ Se←{(⊏˜𝕨)Se 1¨⌾((𝕩/𝕨)⊸⊏)𝕩}⍟{0=⊑⌽𝕩} st←¯1↓Se⟜(1↑˜≠)∾⟜≠q⍋e⋄b←st/q∾˘e - ToI←(≠𝕩)↑/⁼∘⥊⋄f←¬≠`ToI b + ToI←¯1↓·/⁼(≠𝕩)∾˜⥊⋄f←¬≠`ToI b cb←(¬(st/q)⊏r)/b - nl←≠lu←⍷lit←𝕩⊔˜1-˜(+`ToI⊑˘cb)×≠`ToI cb + lu←⍷lit←𝕩⊔˜1-˜(+`ToI⊑˘cb)×≠`ToI cb cl←f/ToI⊑∘⌽˘cb + args←charSet⊸⊐¨𝕨⋄c←charSet⊐f/𝕩 - w←(<´≠↕0∾⊢)l←c∊∾bD‿bN‿bA - id←⍷args∾(bA∊˜w/c)⍒⊸⊏i←(1-˜l×+`w)⊔c - nv←+´bA∊˜⊑¨id - c↩(w∨¬l∨c∊bW)/(vi+id⊐i)⌾(w⊸/)(vi+(≠id)+lu⊐lit)⌾(cl⊸/)c - c(/˜)↩¬(1⌾⊑1⌽1⌾⊑)⊸∧c∊bS - ⟨c,nv,nv-≠args,(nv↓id)∾lu⟩ + w←(≠↑0∾⊢)⊸<l←c∊∾bD‿bN‿bA + i←(1-˜l×+`w)⊔c + na←≠•a⋄us←¯1⊑bA + in←us⊸≠⊸/¨na(⊢-⊣×+⟜(⊑bA)⊸≤)i + id←⍷args∾(bA∊˜w/c)⍒⊸⊏in⋄nv←+´bA∊˜⊑¨id + + c↩(w∨¬l∨c∊bP∾bW)/(vi+id⊐in)⌾(w⊸/)(vi+(≠id)+lu⊐lit)⌾(cl⊸/)c + c/˜↩¬(≠↑1∾(c∊2‿4⊏bB)∨⊢)⊸∧c∊bS⋄c/˜↩¬(1↓1∾˜c∊3‿5⊏bB)∧c∊bS + ti←(us=¯1⊸⊑¨i)(⊢+∧⟜(2⊸=))0⌈na⌊∘÷˜(⊑bA)-˜⊑¨i + t←ti⌾(((0⊸≤∧<⟜(≠id))c-vi)⊸/)(vi⌊c)⊏charRole + ⟨c,t,nv,nv-≠args,(nv↓id)∾lu⟩ } Parse←{ - a←𝕩∊(2↑bG)⋄at←1⌽a⋄𝕩(/˜)↩¬a⋄a(/˜)↩¬at - l←≠𝕩⋄sep←𝕩∊bS⋄𝕩↩(bF⊑˜chF⊐<'⊣')¨⌾(sep⊸/)𝕩⋄sep∨↩𝕩=2⊑bB + a←𝕩∊(2↑bG)⋄at←1⌽a⋄𝕩/˜↩¬a⋄a/˜↩¬at + l←≠𝕩⋄sep←𝕩∊bS⋄𝕩↩(bF⊑˜⥊chF⊐<'⊣')¨⌾(sep⊸/)𝕩⋄sep∨↩𝕩=2⊑bB o←𝕩=0⊑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 + fe⌊↩l-l↑⌽⌈`↕∘≠⊸×⌽1∾˜sep sel←¬∘⊏⟜(o∨c)⊸/⍋((f×fe)⌈↕l)-+`f-l↑/⁼∧f/fe sel⊸⊏¨𝕩‿na } -Hex←16 Base (•d∾"ABCDEF")⊸⊐ +Base←{+⟜(𝕨⊸×)´𝕩} +Enc2←{2|⌊∘÷⟜2⍟(↕𝕨)𝕩} -ReadNum←10 Base bD⊸⊐ +Hex←16 Base⟜⌽ (•d∾"ABCDEF")⊸⊐ + +ReadNum←{ + n‿d‿p‿i←bN # ¯.π∞ + Nat←10 Base⟜⌽ -⟜(⊑bD) + Int←(n=⊑)◶⟨Nat,-·Nat 1⊸↓⟩ + Dec←⊐⟜(<d)⊸(Nat∘↑ + ·(0<≠)◶⟨0,Nat÷10⋆≠⟩+⟜1⊸↓) + Pos←(⊑p‿i⊐⊏)◶⟨π,∞,Dec⟩ + e←⊑𝕩⊐charSet⊐<'e' + m←(n=⊑)◶⟨Pos,-·Pos 1⊸↓⟩e↑𝕩 + 𝕩×⟜(10⋆·Int(e+1)↓⊣)˜⍟(e<≠𝕩)m +} +LitVal←(⊑"'"""⊐⊏)◶⟨1⊸⊑,1⊸↓,ReadNum⟩ GenF64←{ - 𝕩=0:8⥊0 + 0:8⥊0; l←2(⌊⋆⁼)𝕩 - (Hex"44")∾2 Base˘⌽8‿8(⊣⥊×´⊸↑)∾⟨⥊0,11 Enc2 1023+l,(0⌈l)Enc2𝕩⟩ + (Hex"44")∾2 Base˘8‿8⥊∾⟨¯52↑(0⌈l)Enc2𝕩,11 Enc2 1023+l,⥊0⟩ } -MakeTab←{{(≠chF)↑⊑¨(chF⊐𝕨)⊔𝕩}○∾⟜(⥊¨∘⥊¨)´<˘⍉(2(÷˜∾⊣)≢)⊸⥊𝕩} +MakeTab←{{⊑∘(∾⟜0)¨¯1↓(chF⊐𝕨)⊔○(∾⟜(≠chF))𝕩}○∾⟜(⥊¨∘⥊¨)´<˘⍉(2(÷˜∾⊣)≢)⊸⥊𝕩} tab1←MakeTab⟨ "⊣⊢" , 2⥊<⟨⟩ "|-⌈⌊√" , (Hex"99")+(↕4)∾6 @@ -78,26 +92,26 @@ tab2←MakeTab⟨ "¬" , <∾⥊¨⟨Hex"A1",GenF64 1,Hex"A0"⟩ "∨" , <(Hex"10")∾1 ⟩ -fntab←⍉¯3↑tab1≍tab2 +fntab←⍉(0¨tab1)∾tab1≍tab2 f64←127-3 GenFn←{ ⟨⟩GenFn𝕩; - ⟨t,nVar,nLoc,lits⟩←𝕨Tokenize𝕩 - t(⊏˜)↩⍋+`-´<˘(2‿3⊏bB)=⌜t + ⟨t,r,nVar,nLoc,lits⟩←𝕨Tokenize𝕩 + t⊏˜↩⍋+`-´<˘(2‿3⊏bB)=⌜t nd←+´c←t=3⊑bB t↩((vi+nVar+≠lits)+↕∘≠)⌾(c⊸/)t ⟨a,na⟩←Parse t ops←⥊∾⟨ - vi↑fntab - ⍉3↑(Hex¨"20"‿"22")∾⌜↕nVar + ∾⟜(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 𝕩} + LEB←{0:⥊0;128⊸+⌾(¯1⊸↓) 2 Base˘ (⌽·∨`·⌽∨´˘)⊸/ 10‿7(⊣⥊×´⊸↑) 64 Enc2 𝕩} C←LEB∘≠⊸∾ S←∾⟜C V←≠∾∾ @@ -112,10 +126,52 @@ Gen←{ ⟩ } +rcp←⟨"x"⟩ GenFn "1÷x" +or←⟨"w","x"⟩ GenFn "(w+x)-w∧x" Compile←{ body←GenFn 𝕩 - rcp←⟨"x"⟩ GenFn "1÷x" - or←⟨"w","x"⟩ GenFn "(w+x)-w∧x" f←⟨rcp,or,body⟩ - Gen ⟨(≠¨f)/⟨1‿1,2‿1,0‿1⟩/¨¨f64 ⋄ 2 ⋄ ∾f⟩ + Gen ⟨(≠¨f)/(1‿2‿0∾¨1)⥊¨¨f64 ⋄ 2 ⋄ ∾f⟩ +} + + +# Targetting dzaima/BQN bytecode: + +DParse ← {nv‿r𝕊𝕩: + g←⍋+`p←bB(⊣(≠⊸>ׯ1⋆2|⊢)⊐)𝕩 + sl←1⊸⌽⊸∨𝕩∊bL⋄sr←¯1⊸⌽⌾(g⊸⊏)sl⋄sa←sl∨sr + g⊏˜↩⍋g⊏sl⋄r×↩¬sa⋄o←p>0 + r+↩(sa<𝕩=1⊑bB)(⊣∧¬⊸∨=○(⌈`(1+↕∘≠)⊸×)⊢)(¯1⊸⌽⌾(g⊸⊏)3=r)∨1≤r + rev←⍋+`1+¯1↓g((¯1∾⊣)(⊣⍋⊸⊏⊏˜-⊏˜⟜⍋)⟜⍋1(+`∘∾-∾˜)⊏)o∨sl∨𝕩∊bS + g↩⍋+`rev⊏p⋄gr←g⊏rev⋄sll←1+2÷˜0(<-○/>)gr⊏sr-sl + g⊏˜↩⍋gr⊏sl⋄gr↩g⊏rev⋄𝕩⊏˜↩gr⋄r⊏˜↩gr⋄o⊏˜↩gr⋄si←/gr⊏sr>sl + s←𝕩∊bS⋄ps←s∨o∨gr⊏sl⋄a←𝕩∊2↑bG + r-↩ps∨a⋄op←r≥2⋄ro←op∨1⌽r=3 + tr←(⌈`↕∘≠⊸ׯ1⌽ps)⊏ro∨r≥1 + tf←(a≤○(⌈`(1+↕∘≠)⊸×)ps)∧(⊢∧2(|<≤)ps(⊢-⌈`∘×)+`)¬ro + opa←op>1↓0∾˜ps∨a⋄os←⌽↕∘≠⊸(⊣-⌈`∘×)⌽¬ro + oa←⌽/opa⋄fa←/(tf∨¬tr)∧(ro∧1⌽opa)<(r=1)∨op<¯1⌽opa + dy←fa⊏1↓0∾˜(𝕩≠⊑bO)∧(tr∧r≥0)∨r=0 + n←𝕩≥vi+nv⋄id←/n<𝕩≥vi⋄cn←/n∨𝕩≤¯1⊑bC⋄u←⍷ob←cn⊏𝕩 + lo←(o/𝕩)=4⊑bB⋄l←/𝕩=5⊑bB⋄ll←1+lo/1(↓--⊸↓)(o∾1)/+`(s∾0)-(1∾o)∧ps∾1 + dr←/s>o+`⊸⊏0∾lo + or←⍋g⊏˜∾⟨cn,cn,id,id,1+/a,dr,l,l,si,si,oa+1⌈oa⊏os,(dy×⊏⟜os)⊸+fa+dy⟩ + bc←or⊏∾⟨0¨cn,u⊐ob,1+(id-1)⊏a,vi-˜id⊏𝕩,(11-⊑bG)+a/𝕩 + 14¨dr,3¨l,ll,3¨si,sll,5+oa⊏r,5+dy+4×fa⊏tr⟩ + bc‿u +} + +prims←⟨ + +,-,×,÷,⋆,√,⌊,⌈,|,¬,∧,∨,<,>,≠,=,≤,≥,≡,≢,⊣,⊢,⥊,∾,≍,↑,↓,↕,⌽,⍉,/,⍋,⍒,⊏,⊑,⊐,⊒,∊,⍷,⊔,! + ˜,˘,¨,⌜,⁼,´,` + ∘,○,⊸,⟜,⌾,⊘,◶,⎉,⚇,⍟ +⟩ +DGenFn←{ + ⟨t,r,nVar,nLoc,lits⟩←⟨⟩Tokenize𝕩 + ⟨bc,u⟩←nVar‿r DParse t + o←(u-(vi+nVar-≠prims)×u≥vi)⊏prims∾LitVal¨lits + ⟨bc,o,nVar↑•a,⟨⟩⟩ +} +DRun←{ + 'a' •COMP DGenFn 𝕩 } diff --git a/cshim.bqn b/cshim.bqn new file mode 100755 index 00000000..18396541 --- /dev/null +++ b/cshim.bqn @@ -0,0 +1,3 @@ +#! /usr/bin/env dbqn + +((<•path∾"c.bqn")∾•args) •EX •path∾"dzref" diff --git a/dc.bqn b/dc.bqn deleted file mode 100755 index 2660f63d..00000000 --- a/dc.bqn +++ /dev/null @@ -1,177 +0,0 @@ -#! ./spec/dzref - -nl‿tab←•UCS 10‿9 -charSet←∾charGroups←⟨ - chF←"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!" # Function - "˜˘¨⌜⁼´`" # Modifier - "∘○⊸⟜⌾⊘◶⎉⚇⍟" # Composition - ¯1⊏˘10‿2⥊"𝕨𝕎𝕩𝕏𝕗𝔽𝕘𝔾𝕤𝕊" # Input (𝕣 pending; ℝ not allowed) - nl∾"⋄," # Separator - "←↩→" # Gets - "(){}⟨⟩" # Bracket - "‿" # Ligature - "·" # nOthing - •d # +⟜(↕10)⌾•UCS'0' # Digit - "¯.π∞" # Numeric - "_"∾˜' '(+∾⊢)⌾•UCS•a # Alphabetic - 1↑"𝕨" # Prefix for input (hack around UTF-16) - " "∾tab # Whitespace -# #'" eliminated during tokenization -⟩ -bF‿bM‿bC‿bI‿bS‿bG‿bB‿bL‿bO‿bD‿bN‿bA‿bP‿bW←⊔/≠¨charGroups -vi←+´≠¨9↑charGroups -charRole←(vi+1)↑(/0∾≠¨3↑charGroups)∾10⥊↕2 - -Tokenize←{ - r←𝕩='#'⋄s←/(≠↑2⊸↓)⊸∧𝕩='''⋄d←/𝕩='"' - g←⍋q←∾⟨ s⋄¯1↓d⋄/r⟩ ⋄q↩g⊏q - e← g⊏∾⟨2+s⋄ 1↓d⋄(⊢-¯1↓0∾⊢)∘⊏⟜(0∾+`r)⊸//(𝕩=nl)∾1⟩ - Se←{(⊏˜𝕨)Se 1¨⌾((𝕩/𝕨)⊸⊏)𝕩}⍟{0=⊑⌽𝕩} - st←¯1↓Se⟜(1↑˜≠)∾⟜≠q⍋e⋄b←st/q∾˘e - ToI←¯1↓·/⁼(≠𝕩)∾˜⥊⋄f←¬≠`ToI b - cb←(¬(st/q)⊏r)/b - lu←⍷lit←𝕩⊔˜1-˜(+`ToI⊑˘cb)×≠`ToI cb - cl←f/ToI⊑∘⌽˘cb - - args←charSet⊸⊐¨𝕨⋄c←charSet⊐f/𝕩 - w←(≠↑0∾⊢)⊸<l←c∊∾bD‿bN‿bA - i←(1-˜l×+`w)⊔c - na←≠•a⋄us←¯1⊑bA - in←us⊸≠⊸/¨na(⊢-⊣×+⟜(⊑bA)⊸≤)i - id←⍷args∾(bA∊˜w/c)⍒⊸⊏in⋄nv←+´bA∊˜⊑¨id - - c↩(w∨¬l∨c∊bP∾bW)/(vi+id⊐in)⌾(w⊸/)(vi+(≠id)+lu⊐lit)⌾(cl⊸/)c - c/˜↩¬(≠↑1∾(c∊2‿4⊏bB)∨⊢)⊸∧c∊bS⋄c/˜↩¬(1↓1∾˜c∊3‿5⊏bB)∧c∊bS - ti←(us=¯1⊸⊑¨i)(⊢+∧⟜(2⊸=))0⌈na⌊∘÷˜(⊑bA)-˜⊑¨i - t←ti⌾(((0⊸≤∧<⟜(≠id))c-vi)⊸/)(vi⌊c)⊏charRole - ⟨c,t,nv,nv-≠args,(nv↓id)∾lu⟩ -} - -Parse←{ - a←𝕩∊(2↑bG)⋄at←1⌽a⋄𝕩/˜↩¬a⋄a/˜↩¬at - l←≠𝕩⋄sep←𝕩∊bS⋄𝕩↩(bF⊑˜⥊chF⊐<'⊣')¨⌾(sep⊸/)𝕩⋄sep∨↩𝕩=2⊑bB - o←𝕩=0⊑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⟜⌽ (•d∾"ABCDEF")⊸⊐ - -ReadNum←{ - n‿d‿p‿i←bN # ¯.π∞ - Nat←10 Base⟜⌽ -⟜(⊑bD) - Int←(n=⊑)◶⟨Nat,-·Nat 1⊸↓⟩ - Dec←⊐⟜(<d)⊸(Nat∘↑ + ·(0<≠)◶⟨0,Nat÷10⋆≠⟩+⟜1⊸↓) - Pos←(⊑p‿i⊐⊏)◶⟨π,∞,Dec⟩ - e←⊑𝕩⊐charSet⊐<'e' - m←(n=⊑)◶⟨Pos,-·Pos 1⊸↓⟩e↑𝕩 - 𝕩×⟜(10⋆·Int(e+1)↓⊣)˜⍟(e<≠𝕩)m -} -LitVal←(⊑"'"""⊐⊏)◶⟨1⊸⊑,1⊸↓,ReadNum⟩ -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←{ - ⟨⟩GenFn𝕩; - ⟨t,r,nVar,nLoc,lits⟩←𝕨Tokenize𝕩 - t⊏˜↩⍋+`-´<˘(2‿3⊏bB)=⌜t - nd←+´c←t=3⊑bB - t↩((vi+nVar+≠lits)+↕∘≠)⌾(c⊸/)t - ⟨a,na⟩←Parse 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∘•UCS - t‿n‿b←𝕩 - ∾⟨ - 0∾(•UCS"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←⟨"x"⟩ GenFn "1÷x" -or←⟨"w","x"⟩ GenFn "(w+x)-w∧x" -Compile←{ - body←GenFn 𝕩 - f←⟨rcp,or,body⟩ - Gen ⟨(≠¨f)/(1‿2‿0∾¨1)⥊¨¨f64 ⋄ 2 ⋄ ∾f⟩ -} - - -# Targetting dzaima/BQN bytecode: - -DParse ← {nv‿r𝕊𝕩: - g←⍋+`p←bB(⊣(≠⊸>ׯ1⋆2|⊢)⊐)𝕩 - sl←1⊸⌽⊸∨𝕩∊bL⋄sr←¯1⊸⌽⌾(g⊸⊏)sl⋄sa←sl∨sr - g⊏˜↩⍋g⊏sl⋄r×↩¬sa⋄o←p>0 - r+↩(sa<𝕩=1⊑bB)(⊣∧¬⊸∨=○(⌈`(1+↕∘≠)⊸×)⊢)(¯1⊸⌽⌾(g⊸⊏)3=r)∨1≤r - rev←⍋+`1+¯1↓g((¯1∾⊣)(⊣⍋⊸⊏⊏˜-⊏˜⟜⍋)⟜⍋1(+`∘∾-∾˜)⊏)o∨sl∨𝕩∊bS - g↩⍋+`rev⊏p⋄gr←g⊏rev⋄sll←1+2÷˜0(<-○/>)gr⊏sr-sl - g⊏˜↩⍋gr⊏sl⋄gr↩g⊏rev⋄𝕩⊏˜↩gr⋄r⊏˜↩gr⋄o⊏˜↩gr⋄si←/gr⊏sr>sl - s←𝕩∊bS⋄ps←s∨o∨gr⊏sl⋄a←𝕩∊2↑bG - r-↩ps∨a⋄op←r≥2⋄ro←op∨1⌽r=3 - tr←(⌈`↕∘≠⊸ׯ1⌽ps)⊏ro∨r≥1 - tf←(a≤○(⌈`(1+↕∘≠)⊸×)ps)∧(⊢∧2(|<≤)ps(⊢-⌈`∘×)+`)¬ro - opa←op>1↓0∾˜ps∨a⋄os←⌽↕∘≠⊸(⊣-⌈`∘×)⌽¬ro - oa←⌽/opa⋄fa←/(tf∨¬tr)∧(ro∧1⌽opa)<(r=1)∨op<¯1⌽opa - dy←fa⊏1↓0∾˜(𝕩≠⊑bO)∧(tr∧r≥0)∨r=0 - n←𝕩≥vi+nv⋄id←/n<𝕩≥vi⋄cn←/n∨𝕩≤¯1⊑bC⋄u←⍷ob←cn⊏𝕩 - lo←(o/𝕩)=4⊑bB⋄l←/𝕩=5⊑bB⋄ll←1+lo/1(↓--⊸↓)(o∾1)/+`(s∾0)-(1∾o)∧ps∾1 - dr←/s>o+`⊸⊏0∾lo - or←⍋g⊏˜∾⟨cn,cn,id,id,1+/a,dr,l,l,si,si,oa+1⌈oa⊏os,(dy×⊏⟜os)⊸+fa+dy⟩ - bc←or⊏∾⟨0¨cn,u⊐ob,1+(id-1)⊏a,vi-˜id⊏𝕩,(11-⊑bG)+a/𝕩 - 14¨dr,3¨l,ll,3¨si,sll,5+oa⊏r,5+dy+4×fa⊏tr⟩ - bc‿u -} - -prims←⟨ - +,-,×,÷,⋆,√,⌊,⌈,|,¬,∧,∨,<,>,≠,=,≤,≥,≡,≢,⊣,⊢,⥊,∾,≍,↑,↓,↕,⌽,⍉,/,⍋,⍒,⊏,⊑,⊐,⊒,∊,⍷,⊔,! - ˜,˘,¨,⌜,⁼,´,` - ∘,○,⊸,⟜,⌾,⊘,◶,⎉,⚇,⍟ -⟩ -DGenFn←{ - ⟨t,r,nVar,nLoc,lits⟩←⟨⟩Tokenize𝕩 - ⟨bc,u⟩←nVar‿r DParse t - o←(u-(vi+nVar-≠prims)×u≥vi)⊏prims∾LitVal¨lits - ⟨bc,o,nVar↑•a,⟨⟩⟩ -} -DRun←{ - 'a' •COMP DGenFn 𝕩 -} diff --git a/dcshim.bqn b/dcshim.bqn deleted file mode 100755 index 1762c342..00000000 --- a/dcshim.bqn +++ /dev/null @@ -1,3 +0,0 @@ -#! /usr/bin/env dbqn - -((<•path∾"dc.bqn")∾•args) •EX •path∾"spec/dzref" @@ -1,3 +1,3 @@ #! /usr/bin/env bash -for f in *.md; do ../spec/dzref md.bqn "•←ConvertFile \"$PWD/$f\"" > ../doc/${f%md}html; done +for f in *.md; do ../dzref md.bqn "•←ConvertFile \"$PWD/$f\"" > ../docs/${f%md}html; done @@ -254,7 +254,7 @@ Markdown ← { # since Github doesn't seem to have published theirs TestSections ← { doHighlight ↩ 0 - tests ← ¯2 ↓˘ 8⊸(÷˜⟜≠∾⊣)⊸⥊2↓•LNS •path∾"../spec.json" + tests ← ¯2 ↓˘ 8⊸(÷˜⟜≠∾⊣)⊸⥊2↓•LNS •path∾"spec.json" tests ↩ ((⊑2+⊐⟜':')¨∘⊏ ((-','=¯1⊑⊢)↓↓)¨⎉1 ⊢) tests testSection ← (1↓¯1↓⊢)¨ 5⊏˘tests UnEsc ← { @@ -0,0 +1,124 @@ +#!/usr/bin/env bqn + +⍝ This version of the compiler uses the old BQN prototype and is no +⍝ longer in development. See c.bqn instead. + +reduce←{r←𝕩⋄{(>𝔽¨_r)⍠(><⊸(𝔽¨_r))}}⊑⟨´⟩ +´↩_reduce +⊔↩((↕1+⌈´)=¨<)∘⊣ /¨⟜< ↕∘≠⍠⊢ +⍷↩∪ + +Base←{+⟜(𝕨⊸×)´⌽𝕩} +Enc2←{𝕨⥊2(|∾˜(𝕨-1)Enc2⌊∘÷˜)⍟(0<𝕨)𝕩} + +lf‿tab←•UCS 10‿9 +charSet←∾charGroups←⟨ + chF←"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔" ⍝ Function + "˜˘¨⌜⁼´`" ⍝ Modifier + "∘○⊸⟜⌾⊘◶⎉⚇⍟" ⍝ Composition + "𝕨𝕎𝕩𝕏𝕗𝔽𝕘𝔾" ⍝ Input + lf∾"⋄," ⍝ Separator + "←↩→" ⍝ Gets + "(){}⟨⟩" ⍝ Bracket + "‿" ⍝ Ligature + •d ⍝ +⟜(↕10)⌾•UCS'0' ⍝ Digit + "¯.π∞" ⍝ Numeric + "_"∾' '(⊢∾+)⌾•UCS•a ⍝ Alphabetic + " "∾tab ⍝ Whitespace +⍝ #'" eliminated during tokenization +⟩ +bF‿bM‿bC‿bI‿bS‿bG‿bB‿bL‿bD‿bN‿bA‿bW←⊔/≠¨charGroups +vi←+´≠¨8↑charGroups + +Tokenize←{ + r←𝕩='#'⋄s←/(≠↑2⊸↓)⊸∧𝕩=⊑"'"⋄d←/𝕩='"' + g←⍋q←∾⟨ s⋄¯1↓d⋄/r⟩ ⋄q↩g⊏q + e← g⊏∾⟨2+s⋄ 1↓d⋄(⊢-¯1↓0∾⊢)∘⊏⟜(0∾+`r)⊸//(𝕩=lf)∾1⟩ + Se←{(⊏˜𝕨)Se 1¨⌾((𝕩/𝕨)⊸⊏)𝕩}⍟{0=⊑⌽𝕩} + st←¯1↓Se⟜(1↑˜≠)∾⟜≠q⍋e⋄b←st/q∾˘e + ToI←(≠𝕩)↑/⁼∘⥊⋄f←¬≠`ToI b + cb←(¬(st/q)⊏r)/b + nl←≠lu←⍷lit←𝕩⊔˜1-˜(+`ToI⊑˘cb)×≠`ToI cb + cl←f/ToI⊑∘⌽˘cb + args←charSet⊸⊐¨𝕨⋄c←charSet⊐f/𝕩 + w←(<´≠↕0∾⊢)l←c∊∾bD‿bN‿bA + id←⍷args∾(bA∊˜w/c)⍒⊸⊏i←(1-˜l×+`w)⊔c + nv←+´bA∊˜⊑¨id + c↩(w∨¬l∨c∊bW)/(vi+id⊐i)⌾(w⊸/)(vi+(≠id)+lu⊐lit)⌾(cl⊸/)c + c(/˜)↩¬(1⌾⊑1⌽1⌾⊑)⊸∧c∊bS + ⟨c,nv,nv-≠args,(nv↓id)∾lu⟩ +} + +Parse←{ + a←𝕩∊(2↑bG)⋄at←1⌽a⋄𝕩(/˜)↩¬a⋄a(/˜)↩¬at + l←≠𝕩⋄sep←𝕩∊bS⋄𝕩↩(bF⊑˜chF⊐<'⊣')¨⌾(sep⊸/)𝕩⋄sep∨↩𝕩=2⊑bB + o←𝕩=0⊑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 +} + +Hex←16 Base (•d∾"ABCDEF")⊸⊐ + +ReadNum←10 Base bD⊸⊐ +GenF64←{ + 𝕩=0:8⥊0 + l←2(⌊⋆⁼)𝕩 + (Hex"44")∾2 Base˘⌽8‿8(⊣⥊×´⊸↑)∾⟨⥊0,11 Enc2 1023+l,(0⌈l)Enc2𝕩⟩ +} +MakeTab←{{(≠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←⍉¯3↑tab1≍tab2 +f64←127-3 + +GenFn←{ + ⟨⟩GenFn𝕩; + ⟨t,nVar,nLoc,lits⟩←𝕨Tokenize𝕩 + t(⊏˜)↩⍋+`-´<˘(2‿3⊏bB)=⌜t + nd←+´c←t=3⊑bB + t↩((vi+nVar+≠lits)+↕∘≠)⌾(c⊸/)t + ⟨a,na⟩←Parse t + ops←⥊∾⟨ + vi↑fntab + ⍉3↑(Hex¨"20"‿"22")∾⌜↕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∘•UCS + t‿n‿b←𝕩 + ∾⟨ + 0∾(•UCS"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 + ⟩ +} + +Compile←{ + body←GenFn 𝕩 + rcp←⟨"x"⟩ GenFn "1÷x" + or←⟨"w","x"⟩ GenFn "(w+x)-w∧x" + f←⟨rcp,or,body⟩ + Gen ⟨(≠¨f)/⟨1‿1,2‿1,0‿1⟩/¨¨f64 ⋄ 2 ⋄ ∾f⟩ +} @@ -26,6 +26,6 @@ The left argument for `•EX` or the shell arguments can contain up to two argum ### BQN -This repository contains the beginnings of a self-hosted compiler for BQN, which is not yet complete enough to do any real programming with. There are currently several versions of the compiler: [c.bqn](c.bqn) is run with BQN2NGN, while [dc.bqn](dc.bqn) is run with dzaima+reference. Both compilers have a backend targetting [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly), and dc.bqn additionally has a backend that targets dzaima/BQN's own bytecode, so that the compiler uses only BQN, but the runtime uses the Java implementations of BQN primitives from dzaima/BQN. +This repository contains the beginnings of a self-hosted compiler for BQN, which is not yet complete enough to do any real programming with. There are currently several versions of the compiler: [nc.bqn](nc.bqn) is run with BQN2NGN, while [c.bqn](c.bqn) is run with dzaima+reference. Both compilers have a backend targetting [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly), and c.bqn additionally has a backend that targets dzaima/BQN's own bytecode, so that the compiler uses only BQN, but the runtime uses the Java implementations of BQN primitives from dzaima/BQN. All versions have automated tests in the [test](test/) directory, with the WebAssembly versions tested with Javascript using Node ([test/t.js](test/t.js) and [test/dt.js](test/dt.js) for BQN2NGN and dzaima/BQN respectively) and the dzaima/BQN backend tested with BQN itself ([test/bt](test/bt)). @@ -1,6 +1,6 @@ #! /usr/bin/env dbqn -dRun ← ⟨"dRun"⟩ •EX •path∾"../dcshim.bqn" +dRun ← ⟨"dRun"⟩ •EX •path∾"../cshim.bqn" l ← ∾(•LNS •path∾∾⟜"cases.bqn")¨""‿"b" { l ∾↩ "1 %"⊸∾¨ (3≤≠)◶0‿(('#'≠2⊸⊑)∧" "≡2⊸↑)¨⊸/ •LNS •path∾"testref.bqn" }⍟⊢(<"-ref")∊•args c ← (¬"{"⊑∘∊⊢)¨⊸/ l diff --git a/test/dt.js b/test/dt.js deleted file mode 100755 index 49636a66..00000000 --- a/test/dt.js +++ /dev/null @@ -1,26 +0,0 @@ -//usr/bin/env node "$0" $@;exit $? -const execFile = require('child_process').execFile - , load=f=>require('fs').readFileSync(__dirname+'/'+f,'utf8') - , runWasm=w=>new WebAssembly.Instance(new WebAssembly.Module(Uint8Array.from(w))) - .exports.fn() - -const t=load('cases.bqn').split('\n').filter(x=>x).map(x=>x.split(' % ')) - , test=t.map(e=>'"'+e[1]+'"').join('\n') - , expt=t.map(e=>+e[0]) - -var compiler = execFile( - __dirname+'/../dcshim.bqn', - [ '{•←Compile𝕩}¨⟨'+test+'⟩' ], - function (error, stdout, stderr) { - const rslt=stdout.split('\n').filter(a=>a.length) - .map(a=>runWasm(a.split("‿").map(n=>+n))) - , pass=rslt.map((r,i)=>r===expt[i]) - , fail=pass.map((p,i)=>p?-1:i).filter(i=>i>=0) - console.log( - fail.length - ? fail.map(i=>'"'+t[i][1]+'": expected '+expt[i]+' but received '+rslt[i]) - : "All passed!" - ) - process.exit(+(fail.length>0)) - } -); diff --git a/test/nt.js b/test/nt.js new file mode 100755 index 00000000..5cd38556 --- /dev/null +++ b/test/nt.js @@ -0,0 +1,19 @@ +//usr/bin/env node "$0" $@;exit $? +const bqn=require(require('os').homedir+'/bin/bqn') + , load=f=>require('fs').readFileSync(__dirname+'/'+f,'utf8') + , runWasm=w=>new WebAssembly.Instance(new WebAssembly.Module(Uint8Array.from(w))) + .exports.fn() + +const t=load('cases.bqn').split('\n').filter(x=>x).map(x=>x.split(' % ')) + , test=t.map(e=>'"'+e[1]+'"').join('\n') + , expt=t.map(e=>+e[0]) + , rslt=bqn(load('../nc.bqn','utf8').concat('Compile¨⟨'+test+'⟩')) + .a.map((a,i)=>runWasm(a.a)) + , pass=rslt.map((r,i)=>r===expt[i]) + , fail=pass.map((p,i)=>p?-1:i).filter(i=>i>=0) +console.log( + fail.length + ? fail.map(i=>'"'+t[i][1]+'": expected '+expt[i]+' but received '+rslt[i]) + : "All passed!" +) +process.exit(+(fail.length>0)) @@ -1,5 +1,5 @@ //usr/bin/env node "$0" $@;exit $? -const bqn=require(require('os').homedir+'/bin/bqn') +const execFile = require('child_process').execFile , load=f=>require('fs').readFileSync(__dirname+'/'+f,'utf8') , runWasm=w=>new WebAssembly.Instance(new WebAssembly.Module(Uint8Array.from(w))) .exports.fn() @@ -7,13 +7,20 @@ const bqn=require(require('os').homedir+'/bin/bqn') const t=load('cases.bqn').split('\n').filter(x=>x).map(x=>x.split(' % ')) , test=t.map(e=>'"'+e[1]+'"').join('\n') , expt=t.map(e=>+e[0]) - , rslt=bqn(load('../c.bqn','utf8').concat('Compile¨⟨'+test+'⟩')) - .a.map((a,i)=>runWasm(a.a)) - , pass=rslt.map((r,i)=>r===expt[i]) - , fail=pass.map((p,i)=>p?-1:i).filter(i=>i>=0) -console.log( - fail.length - ? fail.map(i=>'"'+t[i][1]+'": expected '+expt[i]+' but received '+rslt[i]) - : "All passed!" -) -process.exit(+(fail.length>0)) + +var compiler = execFile( + __dirname+'/../cshim.bqn', + [ '{•←Compile𝕩}¨⟨'+test+'⟩' ], + function (error, stdout, stderr) { + const rslt=stdout.split('\n').filter(a=>a.length) + .map(a=>runWasm(a.split("‿").map(n=>+n))) + , pass=rslt.map((r,i)=>r===expt[i]) + , fail=pass.map((p,i)=>p?-1:i).filter(i=>i>=0) + console.log( + fail.length + ? fail.map(i=>'"'+t[i][1]+'": expected '+expt[i]+' but received '+rslt[i]) + : "All passed!" + ) + process.exit(+(fail.length>0)) + } +); |
