aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarvin Borner2024-11-05 22:54:29 +0100
committerMarvin Borner2024-11-05 22:54:29 +0100
commitdb8a8639bc1ecb6834b829370e3aba874b00d95b (patch)
tree714de7ae1b9a13f14ad6753dc8a5858453c0240c
parent0041afc9c49e1e82def7850c38056a354b24de6f (diff)
Default to left associative applications
-rw-r--r--index.html197
-rw-r--r--main.js32
2 files changed, 122 insertions, 107 deletions
diff --git a/index.html b/index.html
index ec4788e..d10825b 100644
--- a/index.html
+++ b/index.html
@@ -28,13 +28,13 @@ bl = \\0
br = \\0
-- two abstractions to ignore the screen state and replace the entire screen
-\\((((0 tl) tr) bl) br)"
+\\(0 tl tr bl br)"
>
Just black
</option>
<option
- value="map = \\(0 \\\\\((((0 (6 4)) (6 3)) (6 2)) (6 1)))
-invert = \\\((2 0) 1)
+ value="map = \\(0 \\\\\(0 (6 4) (6 3) (6 2) (6 1)))
+invert = \\\(2 0 1)
-- the first argument is the empty screen, therefore we can use point-free style
(map invert)"
@@ -42,152 +42,152 @@ invert = \\\((2 0) 1)
Invert
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-\(y \\((((0 1) \\1) \\0) 1))"
+ value="y = \(\(0 0) \(1 (0 0)))
+\(y \\(0 1 \\1 \\0 1))"
>
Diagonal
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-tl = (y \\((((0 1) \\0) \\0) 1))
+ value="y = \(\(0 0) \(1 (0 0)))
+tl = (y \\(0 1 \\0 \\0 1))
tr = \\0
-bl = (y \\((((0 \\0) 1) 1) \\0))
-br = (y \\((((0 1) \\0) \\0) 1))
-\\((((0 tl) tr) bl) br)"
+bl = (y \\(0 \\0 1 1 \\0))
+br = (y \\(0 1 \\0 \\0 1))
+\\(0 tl tr bl br)"
>
Lambda
</option>
<option
value="-- note how no white gets drawn since the highlighted parts would be infinitely detailed
-y = \(\(1 (0 0)) \(1 (0 0)))
-\(y \\((((0 1) \\0) 1) 1))"
+y = \(\(0 0) \(1 (0 0)))
+\(y \\(0 1 \\0 1 1))"
>
Sierpiński triangle
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-tl = (y \\((((0 \\0) 1) 1) 1))
-tr = (y \\((((0 1) \\0) 1) 1))
-bl = (y \\((((0 1) 1) \\0) 1))
-br = (y \\((((0 1) 1) 1) \\0))
-\\((((0 tl) tr) bl) br)"
+ value="y = \(\(0 0) \(1 (0 0)))
+tl = (y \\(0 \\0 1 1 1))
+tr = (y \\(0 1 \\0 1 1))
+bl = (y \\(0 1 1 \\0 1))
+br = (y \\(0 1 1 1 \\0))
+\\(0 tl tr bl br)"
>
Sierpiński square
</option>
<option
value="y = \(\(0 0) \(1 (0 0)))
-sa = (y \\((((0 \\0) 1) 1) 1))
-sb = (y \\((((0 1) \\0) 1) 1))
-sc = (y \\((((0 1) 1) \\0) 1))
-sd = (y \\((((0 1) 1) 1) \\0))
-tl = \\\\\((((0 4) 3) 2) sd)
-tr = \\\\\((((0 4) 3) sc) 1)
-bl = \\\\\((((0 4) sb) 2) 1)
-br = \\\\\((((0 sa) 3) 2) 1)
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+sa = (y \\(0 \\0 1 1 1))
+sb = (y \\(0 1 \\0 1 1))
+sc = (y \\(0 1 1 \\0 1))
+sd = (y \\(0 1 1 1 \\0))
+tl = \\\\\(0 4 3 2 sd)
+tr = \\\\\(0 4 3 sc 1)
+bl = \\\\\(0 4 sb 2 1)
+br = \\\\\(0 sa 3 2 1)
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
Sierpiń-T-square v1
</option>
<option
value="y = \(\(0 0) \(1 (0 0)))
-oncesa = (y \\((((0 \\0) 1) 1) 1))
-oncesb = (y \\((((0 1) \\0) 1) 1))
-oncesc = (y \\((((0 1) 1) \\0) 1))
-oncesd = (y \\((((0 1) 1) 1) \\0))
-sa = (y \\((((0 \\0) 1) 1) oncesd))
-sb = (y \\((((0 1) \\0) oncesc) 1))
-sc = (y \\((((0 1) oncesb) \\0) 1))
-sd = (y \\((((0 oncesa) 1) 1) \\0))
-tl = \\\\\((((0 4) 3) 2) sd)
-tr = \\\\\((((0 4) 3) sc) 1)
-bl = \\\\\((((0 4) sb) 2) 1)
-br = \\\\\((((0 sa) 3) 2) 1)
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+oncesa = (y \\(0 \\0 1 1 1))
+oncesb = (y \\(0 1 \\0 1 1))
+oncesc = (y \\(0 1 1 \\0 1))
+oncesd = (y \\(0 1 1 1 \\0))
+sa = (y \\(0 \\0 1 1 oncesd))
+sb = (y \\(0 1 \\0 oncesc 1))
+sc = (y \\(0 1 oncesb \\0 1))
+sd = (y \\(0 oncesa 1 1 \\0))
+tl = \\\\\(0 4 3 2 sd)
+tr = \\\\\(0 4 3 sc 1)
+bl = \\\\\(0 4 sb 2 1)
+br = \\\\\(0 sa 3 2 1)
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
Sierpiń-T-square v2
</option>
<option
value="y = \(\(0 0) \(1 (0 0)))
-oncesa = (y \\((((0 \\0) 1) 1) 1))
-oncesb = (y \\((((0 1) \\0) 1) 1))
-oncesc = (y \\((((0 1) 1) \\0) 1))
-oncesd = (y \\((((0 1) 1) 1) \\0))
-sa = ((y \\((((0 \\0) 1) 1) 1)) \\\\\((((0 oncesd) 3) 2) 1))
-sb = ((y \\((((0 1) \\0) 1) 1)) \\\\\((((0 4) oncesc) 2) 1))
-sc = ((y \\((((0 1) 1) \\0) 1)) \\\\\((((0 4) 3) oncesb) 1))
-sd = ((y \\((((0 1) 1) 1) \\0)) \\\\\((((0 4) 3) 2) oncesa))
-tl = \\\\\((((0 4) 3) 2) sa)
-tr = \\\\\((((0 4) 3) sb) 1)
-bl = \\\\\((((0 4) sc) 2) 1)
-br = \\\\\((((0 sd) 3) 2) 1)
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+oncesa = (y \\(0 \\0 1 1 1))
+oncesb = (y \\(0 1 \\0 1 1))
+oncesc = (y \\(0 1 1 \\0 1))
+oncesd = (y \\(0 1 1 1 \\0))
+sa = (y \\(0 \\0 1 1 1) \\\\\(0 oncesd 3 2 1))
+sb = (y \\(0 1 \\0 1 1) \\\\\(0 4 oncesc 2 1))
+sc = (y \\(0 1 1 \\0 1) \\\\\(0 4 3 oncesb 1))
+sd = (y \\(0 1 1 1 \\0) \\\\\(0 4 3 2 oncesa))
+tl = \\\\\(0 4 3 2 sa)
+tr = \\\\\(0 4 3 sb 1)
+bl = \\\\\(0 4 sc 2 1)
+br = \\\\\(0 sd 3 2 1)
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
Sierpiń-T-square v3
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-tl = \\\\\((((0 4) 3) 2) \((((0 \((((0 \\0) \\1) \\1) \\1)) \\1) \\1) \\0))
-tr = \\\\\((((0 4) 3) \((((0 \\1) \((((0 \\1) \\0) \\1) \\1)) \\0) \\1)) 1)
-bl = \\\\\((((0 4) \((((0 \\1) \\0) \((((0 \\1) \\1) \\0) \\1)) \\1)) 2) 1)
-br = \\\\\((((0 \((((0 \\0) \\1) \\1) \((((0 \\1) \\1) \\1) \\0))) 3) 2) 1)
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+ value="y = \(\(0 0) \(1 (0 0)))
+tl = \\\\\(0 4 3 2 \(0 \(0 \\0 \\1 \\1 \\1) \\1 \\1 \\0))
+tr = \\\\\(0 4 3 \(0 \\1 \(0 \\1 \\0 \\1 \\1) \\0 \\1) 1)
+bl = \\\\\(0 4 \(0 \\1 \\0 \(0 \\1 \\1 \\0 \\1) \\1) 2 1)
+br = \\\\\(0 \(0 \\0 \\1 \\1 \(0 \\1 \\1 \\1 \\0)) 3 2 1)
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
Sierpiński carpet (variant)
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-tl = \\\\\((((0 4) 3) 2) \\0)
-tr = \\\\\((((0 4) 3) \\0) 1)
-bl = \\\\\((((0 4) \\0) 2) 1)
-br = \\\\\((((0 \\0) 3) 2) 1)
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+ value="y = \(\(0 0) \(1 (0 0)))
+tl = \\\\\(0 4 3 2 \\0)
+tr = \\\\\(0 4 3 \\0 1)
+bl = \\\\\(0 4 \\0 2 1)
+br = \\\\\(0 \\0 3 2 1)
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
T-square
</option>
<option
value="-- variation of T-Square, mostly unrelated to Koch snowflakes
-y = \(\(1 (0 0)) \(1 (0 0)))
-tl = \\\\\((((0 \\1) 3) 2) 1)
-tr = \\\\\((((0 4) \\1) 2) 1)
-bl = \\\\\((((0 4) 3) \\1) 1)
-br = \\\\\((((0 4) 3) 2) \\1)
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+y = \(\(0 0) \(1 (0 0)))
+tl = \\\\\(0 \\1 3 2 1)
+tr = \\\\\(0 4 \\1 2 1)
+bl = \\\\\(0 4 3 \\1 1)
+br = \\\\\(0 4 3 2 \\1)
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
Snowflake
</option>
<option
value="s=\\0
-quad = \\((((0 1) 1) 1) 1)
-y = \(\(1 (0 0)) \(1 (0 0)))
-\(y \\((((0 (quad \((((0 2) s) s) s))) (quad \((((0 s) 2) s) s))) (quad \((((0 s) s) 2) s))) (quad \((((0 s) s) s) 2))))"
+quad = \\(0 1 1 1 1)
+y = \(\(0 0) \(1 (0 0)))
+\(y \\(0 (quad \(0 2 s s s)) (quad \(0 s 2 s s)) (quad \(0 s s 2 s)) (quad \(0 s s s 2))))"
>
Cantor dust
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-tl = \\\\\(y \((((1 \\1) 2) \\0) 5))
-tr = \\\\\(y \((((1 3) \\0) 4) \\1))
-bl = \\\\\(y \((((1 \\1) 3) \\0) 4))
-br = \\\\\(y \((((1 2) \\0) 5) \\1))
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+ value="y = \(\(0 0) \(1 (0 0)))
+tl = \\\\\(y \(1 \\1 2 \\0 5))
+tr = \\\\\(y \(1 3 \\0 4 \\1))
+bl = \\\\\(y \(1 \\1 3 \\0 4))
+br = \\\\\(y \(1 2 \\0 5 \\1))
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
Squiggly Cross
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-tl = \\\\(y \\((((0 \((((0 \\0) 4) 5) 6)) 1) 1) \\1))
-tr = \\\\(y \\((((0 1) \((((0 3) \\0) 5) 6)) \\1) 1))
-bl = \\\\(y \\((((0 1) \\1) \((((0 3) 4) \\0) 6)) 1))
-br = \\\\(y \\((((0 \\1) 1) 1) \((((0 3) 4) 5) \\0)))
-\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))"
+ value="y = \(\(0 0) \(1 (0 0)))
+tl = \\\\(y \\(0 \(0 \\0 4 5 6) 1 1 \\1))
+tr = \\\\(y \\(0 1 \(0 3 \\0 5 6) \\1 1))
+bl = \\\\(y \\(0 1 \\1 \(0 3 4 \\0 6) 1))
+br = \\\\(y \\(0 \\1 1 1 \(0 3 4 5 \\0)))
+\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))"
>
Sunrise
</option>
<option
- value="y = \(\(1 (0 0)) \(1 (0 0)))
-a = \\\\(y \\((((0 \((((0 \\0) 4) 5) 6)) 1) 1) \((((0 3) 4) 5) \\0)))
-b = \\\\(y \\((((0 1) \((((0 3) \\0) 5) 6)) \((((0 3) 4) \\0) 6)) 1))
-\(y \\((((0 (1 a)) (1 b)) (1 b)) (1 a)))"
+ value="y = \(\(0 0) \(1 (0 0)))
+a = \\\\(y \\(0 \(0 \\0 4 5 6) 1 1 \(0 3 4 5 \\0)))
+b = \\\\(y \\(0 1 \(0 3 \\0 5 6) \(0 3 4 \\0 6) 1))
+\(y \\(0 (1 a) (1 b) (1 b) (1 a))"
>
Recursive Nonsense
</option>
@@ -196,21 +196,20 @@ b = \\\\(y \\((((0 1) \((((0 3) \\0) 5) 6)) \((((0 3) 4) \\0) 6)) 1))
w = \\1
b = \\0
isw = \0
-isb = \((0 b) w)
-invert = \\\((2 0) 1)
+isb = \(0 b w)
+invert = \\\(2 0 1)
build = \\\\\((((0 4) 3) 2) 1)
-empty = ((((build b) b) b) b)
+empty = (build b b b b)
tl = \\\\3
tr = \\\\2
bl = \\\\1
br = \\\\0
get = \\(0 1)
-settl = \\(1 \\\\\((((0 5) 3) 2) 1))
-settr = \\(1 \\\\\((((0 4) 5) 2) 1))
-setbl = \\(1 \\\\\((((0 4) 3) 5) 1))
-setbr = \\(1 \\\\\((((0 4) 3) 2) 5))
-map = \\(0 \\\\\((((0 (6 4)) (6 3)) (6 2)) (6 1)))
-qsplit = \(0 \\\\\((((0 ((4 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0))) ((3 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0))) ((2 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0))) ((1 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0))))
+settl = \\(1 \\\\\(0 5 3 2 1))
+settr = \\(1 \\\\\(0 4 5 2 1))
+setbl = \\(1 \\\\\(0 4 3 5 1))
+setbr = \\(1 \\\\\(0 4 3 2 5))
+map = \\(0 \\\\\(0 (6 4) (6 3) (6 2) (6 1)))
\0"
>
Template
diff --git a/main.js b/main.js
index 44d132d..cb2a159 100644
--- a/main.js
+++ b/main.js
@@ -137,6 +137,20 @@ const isOpen = (t) => {
};
const parseLam = (str) => {
+ // default to left-associative application
+ const folded = (s) => {
+ const init = parseLam(s);
+ if (!init[1] || ")]".includes(init[1][0])) return init;
+
+ const go = (acc, rst) => {
+ const parsed = parseLam(rst);
+ const chain = app(acc)(parsed[0]);
+ if (!parsed[1] || ")]".includes(parsed[1][0])) return [chain, parsed[1]];
+ return go(chain, parsed[1]);
+ };
+ return go(init[0], init[1]);
+ };
+
if (!str) {
error("in parseLam");
return [{}, ""];
@@ -148,17 +162,19 @@ const parseLam = (str) => {
case "\\":
case "[": // bruijn
const [body, _tail] = parseLam(tail.trim());
- return [abs(body), head == "[" ? _tail.trim().slice(1) : _tail.trim()];
+ return [
+ abs(body),
+ head == "[" ? _tail.trim().slice(1).trim() : _tail.trim(),
+ ];
case "(":
- const [left, tail1] = parseLam(tail);
- const [right, tail2] = parseLam(tail1.trim());
- return [app(left)(right), tail2.trim().slice(1)];
+ const [chain, _tail1] = folded(tail.trim());
+ return [chain, _tail1.trim().slice(1).trim()];
case ")":
case "]":
error("in parseLam");
return [];
default:
- if (head == " ") return parseLam(tail);
+ if (head == " ") return folded(tail);
if (head >= "a" && head <= "z") {
// substitution
let name = "";
@@ -166,7 +182,7 @@ const parseLam = (str) => {
name += str[0];
str = str.slice(1);
}
- return [def(name), str];
+ return [def(name), str.trim()];
} else {
// de Bruijn index
let num = "";
@@ -174,7 +190,7 @@ const parseLam = (str) => {
num += str[0];
str = str.slice(1);
}
- return [idx(parseInt(num)), str];
+ return [idx(parseInt(num)), str.trim()];
}
}
};
@@ -511,6 +527,6 @@ const reduceLoop = (worker, root, _t) => {
function helpSyntax() {
alert(
- "The syntax uses standard notations for de Bruijn indexed lambda calculus. The de Bruijn indices start at 0. You can use `\\`, `λ`, or `[..]` for abstractions. Applications use parenthesis and currently do *not* assume left associativity by default. All terms can also be replaced by a string of binary lambda calculus (BLC) - useful if you're not comfortable with de Bruijn indices (e.g. by using John Tromp's `lam` compiler).\nYou can define substitutions (like in the presets) using `=`.\n\nHave fun!",
+ "The syntax uses standard notations for de Bruijn indexed lambda calculus. The de Bruijn indices start at 0. You can use `\\`, `λ`, or `[..]` for abstractions. Applications use parenthesis and assume left associativity by default. All terms can also be replaced by a string of binary lambda calculus (BLC) - useful if you're not comfortable with de Bruijn indices (e.g. by using John Tromp's `lam` compiler).\nYou can define substitutions (like in the presets) using `=`.\n\nHave fun!",
);
}