diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-10-30 16:08:14 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2020-10-30 16:44:38 -0400 |
| commit | ff1453f2e2d086a984905bbb85a89712ea3c78bb (patch) | |
| tree | 22fda7a1a1e79b72d284ef404ce8631c781c9cd4 /tutorial | |
| parent | ce0172e50c173b4415bed89997603b09e158105f (diff) | |
Generate expression displays from compiled bytecode, not an ad-hoc parser
Diffstat (limited to 'tutorial')
| -rw-r--r-- | tutorial/evalexp.bqn | 46 | ||||
| -rw-r--r-- | tutorial/expression.md | 4 |
2 files changed, 34 insertions, 16 deletions
diff --git a/tutorial/evalexp.bqn b/tutorial/evalexp.bqn index 17c8c0db..f25144ac 100644 --- a/tutorial/evalexp.bqn +++ b/tutorial/evalexp.bqn @@ -15,25 +15,39 @@ Shadow ← { } DrawEval←{ - ix←𝕩⊏˜i←/𝕩≠' ' - f←0=b←(op←'('=ix)-')'=ix - l←op<<⟜«fn←ix∊"+-×÷⋆√" - g←⍋+`b - ei←¯1∾˜b{((𝕨<0)/𝕩)⌾((𝕨>0)⊸/)𝕩}○(g⊸⊏)»+`f - o←ei⊏˜f/↕∘≠⊸-⌾(g⊸⊏)(1+»l)(⊢+fn×-)1-2×l - g⊏˜↩⍋g⊏l - rev←⍋+`¯1↓(¯1∾g)(⊣⍋⊸⊏⊏˜⟜⍋¬⊏˜)⍋+`⊸+1∾g⊏l∨op - m←1+⌈´d←+`⊸×⌾(rev⊸⊏)fn + b‿const‿blk‿i ← Compile 𝕩 + ba‿bc‿bo‿bp ← '0'-˜⟨ # For each instruction, number of: + "11111000000000010000022000" # Arguments + "000//232323223102303200121" # Stack values consumed + "11111111111111011101111111" # Stack values output + "00000110101000001101000100" # Position determiner + ⟩ + m ← { # Mask of instruction starts + a ← ba(⊣⊏˜≠⊸>×⊢)b + na← ∾⟜≠ (≠-(1+↕∘≠)⊸(»·⌈`×)⌾⌽) <⟜128 b + n ← 1+{(𝕩=⌜a) +˝∘× >⊏⟜na⍟𝕩↕≠a}↕3 + ! ∧´ ↕∘≠⊸< n + Se←{(⊏˜𝕨)Se 1¨⌾((𝕩/𝕨)⊸⊏)𝕩}⍟(0=¯1⊑⊢) + (≠↑∾⟜≠Se 1∾0¨) n + } + mb‿mi ← m⊸/¨ b‿i + mi↓˜↩¯1 + + r←+`(mb⊏bo)-na←mb⊏bc + ! 1=¯1⊑r + p←((¯1↓r)⍋⊸⊏○⍋(⊏⟜r+⊒))⊸⊏/na + j←¯1↓mi⊏˜⊏˜⍟≠{s←𝕩⊏˜g←⍋𝕩⋄(g/˜(⊒s)=s⊏mb⊏bp)⌾((⍷s)⊸⊏)↕≠mb}p + je←j∾¯1.25 + d←+`⊸×f←0<na + f↑˜↩≠p + q←(/f∨j≠p⊏je) (⊏≍⊣) p - pt ← f/⍉> wh×⟨i,d⟩ - off← (o ⊏ ∾⟜(whׯ1.25‿m))⊸- pt - pd ← pt (<(wh×0.6‿0.1)⊸+)⊸∾⟜⌽˘ off - dim← (wh×⟨≠𝕩,2+m⟩)+2‿0×pad - tp ← <˘pt+to+⎉1(0‿1×⌜˜f/¬fn)×off + pd ← <⊸∾⟜⌽˘˜˝ q ⊏ ⍉wh×0.6‿0.1+je≍d + dim← (wh×⟨≠𝕩,2+⌈´d⟩)+2‿0×pad (512‿0⊸⌈⊸(⊣∾˜(t+pad)-˜-˜÷2˙)dim+2×t) SVG gr Enc ∾⥊¨⟨ <"rect" Elt rc∾(Pos-pad)∾"width"‿"height"≍˘FmtNum¨dim <"text" Enc Highlight 𝕩 - (<"path" Elt ps∾"d"≍○<·∾"Mvh"∾⟜Fmt¨⊢)˘ pd - <tp Shadow f/ix + (<"path" Elt ps∾"d"≍○<·∾"MVH"∾⟜Fmt¨⊢)˘ pd + mi ((to+wh×≍)¨Shadow⊏⟜𝕩)⟜(⊏⟜d)○((¬f)⊸/) p ⟩ } diff --git a/tutorial/expression.md b/tutorial/expression.md index 19db15fc..018be7a8 100644 --- a/tutorial/expression.md +++ b/tutorial/expression.md @@ -197,6 +197,10 @@ It's past time we covered how the syntax for modifiers works. Remember how I tol ∘+ 3 4 +<!--GEN +DrawEval "3 ט∘+ 4" +--> + 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 `×(˜∘+)`, which uses `˜` as an operand to `∘`. 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. 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, `+˜ 3` has a subject to the right of the 1-modifier `˜`. Even worse, `+˜ ÷ 3` looks the same syntactically as `+∘ ÷ 3`, but it's two functions `+˜` and `÷` applied to `3` while the version with Atop is a single function `+∘÷` applied to `3`. 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. |
