aboutsummaryrefslogtreecommitdiff
path: root/tutorial
diff options
context:
space:
mode:
Diffstat (limited to 'tutorial')
-rw-r--r--tutorial/evalexp.bqn46
-rw-r--r--tutorial/expression.md4
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.