From db8a8639bc1ecb6834b829370e3aba874b00d95b Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Tue, 5 Nov 2024 22:54:29 +0100 Subject: Default to left associative applications --- index.html | 197 ++++++++++++++++++++++++++++++------------------------------- main.js | 32 +++++++--- 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 @@ -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!", ); } -- cgit v1.2.3