From fd316c81c0b9529a25c8d08ede3f4f2c3ccce6c2 Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Sun, 1 Oct 2023 13:20:49 +0100 Subject: [PATCH] support mininotation '..' range operator, fixes #715 (#716) * support mininotation .. range operator, fixes #715 * remove logs --- packages/mini/krill-parser.js | 345 ++++++++++++++++++------------- packages/mini/krill.pegjs | 8 +- packages/mini/mini.mjs | 11 + packages/mini/test/mini.test.mjs | 6 + 4 files changed, 224 insertions(+), 146 deletions(-) diff --git a/packages/mini/krill-parser.js b/packages/mini/krill-parser.js index e85e33630..7831087b0 100644 --- a/packages/mini/krill-parser.js +++ b/packages/mini/krill-parser.js @@ -200,20 +200,21 @@ function peg$parse(input, options) { var peg$c23 = "*"; var peg$c24 = "?"; var peg$c25 = ":"; - var peg$c26 = "struct"; - var peg$c27 = "target"; - var peg$c28 = "euclid"; - var peg$c29 = "slow"; - var peg$c30 = "rotL"; - var peg$c31 = "rotR"; - var peg$c32 = "fast"; - var peg$c33 = "scale"; - var peg$c34 = "//"; - var peg$c35 = "cat"; - var peg$c36 = "$"; - var peg$c37 = "setcps"; - var peg$c38 = "setbpm"; - var peg$c39 = "hush"; + var peg$c26 = ".."; + var peg$c27 = "struct"; + var peg$c28 = "target"; + var peg$c29 = "euclid"; + var peg$c30 = "slow"; + var peg$c31 = "rotL"; + var peg$c32 = "rotR"; + var peg$c33 = "fast"; + var peg$c34 = "scale"; + var peg$c35 = "//"; + var peg$c36 = "cat"; + var peg$c37 = "$"; + var peg$c38 = "setcps"; + var peg$c39 = "setbpm"; + var peg$c40 = "hush"; var peg$r0 = /^[1-9]/; var peg$r1 = /^[eE]/; @@ -255,64 +256,67 @@ function peg$parse(input, options) { var peg$e30 = peg$literalExpectation("*", false); var peg$e31 = peg$literalExpectation("?", false); var peg$e32 = peg$literalExpectation(":", false); - var peg$e33 = peg$literalExpectation("struct", false); - var peg$e34 = peg$literalExpectation("target", false); - var peg$e35 = peg$literalExpectation("euclid", false); - var peg$e36 = peg$literalExpectation("slow", false); - var peg$e37 = peg$literalExpectation("rotL", false); - var peg$e38 = peg$literalExpectation("rotR", false); - var peg$e39 = peg$literalExpectation("fast", false); - var peg$e40 = peg$literalExpectation("scale", false); - var peg$e41 = peg$literalExpectation("//", false); - var peg$e42 = peg$classExpectation(["\n"], true, false); - var peg$e43 = peg$literalExpectation("cat", false); - var peg$e44 = peg$literalExpectation("$", false); - var peg$e45 = peg$literalExpectation("setcps", false); - var peg$e46 = peg$literalExpectation("setbpm", false); - var peg$e47 = peg$literalExpectation("hush", false); + var peg$e33 = peg$literalExpectation("..", false); + var peg$e34 = peg$literalExpectation("struct", false); + var peg$e35 = peg$literalExpectation("target", false); + var peg$e36 = peg$literalExpectation("euclid", false); + var peg$e37 = peg$literalExpectation("slow", false); + var peg$e38 = peg$literalExpectation("rotL", false); + var peg$e39 = peg$literalExpectation("rotR", false); + var peg$e40 = peg$literalExpectation("fast", false); + var peg$e41 = peg$literalExpectation("scale", false); + var peg$e42 = peg$literalExpectation("//", false); + var peg$e43 = peg$classExpectation(["\n"], true, false); + var peg$e44 = peg$literalExpectation("cat", false); + var peg$e45 = peg$literalExpectation("$", false); + var peg$e46 = peg$literalExpectation("setcps", false); + var peg$e47 = peg$literalExpectation("setbpm", false); + var peg$e48 = peg$literalExpectation("hush", false); var peg$f0 = function() { return parseFloat(text()); }; - var peg$f1 = function(chars) { return new AtomStub(chars.join("")) }; - var peg$f2 = function(s) { return s }; - var peg$f3 = function(s, stepsPerCycle) { s.arguments_.stepsPerCycle = stepsPerCycle ; return s; }; - var peg$f4 = function(a) { return a }; - var peg$f5 = function(s) { s.arguments_.alignment = 'slowcat'; return s; }; - var peg$f6 = function(a) { return x => x.options_['weight'] = a }; - var peg$f7 = function(a) { return x => x.options_['reps'] = a }; - var peg$f8 = function(p, s, r) { return x => x.options_['ops'].push({ type_: "bjorklund", arguments_ :{ pulse: p, step:s, rotation:r }}) }; - var peg$f9 = function(a) { return x => x.options_['ops'].push({ type_: "stretch", arguments_ :{ amount:a, type: 'slow' }}) }; - var peg$f10 = function(a) { return x => x.options_['ops'].push({ type_: "stretch", arguments_ :{ amount:a, type: 'fast' }}) }; - var peg$f11 = function(a) { return x => x.options_['ops'].push({ type_: "degradeBy", arguments_ :{ amount:a, seed: seed++ } }) }; - var peg$f12 = function(s) { return x => x.options_['ops'].push({ type_: "tail", arguments_ :{ element:s } }) }; - var peg$f13 = function(s, ops) { const result = new ElementStub(s, {ops: [], weight: 1, reps: 1}); + var peg$f1 = function() { return parseInt(text()); }; + var peg$f2 = function(chars) { return new AtomStub(chars.join("")) }; + var peg$f3 = function(s) { return s }; + var peg$f4 = function(s, stepsPerCycle) { s.arguments_.stepsPerCycle = stepsPerCycle ; return s; }; + var peg$f5 = function(a) { return a }; + var peg$f6 = function(s) { s.arguments_.alignment = 'slowcat'; return s; }; + var peg$f7 = function(a) { return x => x.options_['weight'] = a }; + var peg$f8 = function(a) { return x => x.options_['reps'] = a }; + var peg$f9 = function(p, s, r) { return x => x.options_['ops'].push({ type_: "bjorklund", arguments_ :{ pulse: p, step:s, rotation:r }}) }; + var peg$f10 = function(a) { return x => x.options_['ops'].push({ type_: "stretch", arguments_ :{ amount:a, type: 'slow' }}) }; + var peg$f11 = function(a) { return x => x.options_['ops'].push({ type_: "stretch", arguments_ :{ amount:a, type: 'fast' }}) }; + var peg$f12 = function(a) { return x => x.options_['ops'].push({ type_: "degradeBy", arguments_ :{ amount:a, seed: seed++ } }) }; + var peg$f13 = function(s) { return x => x.options_['ops'].push({ type_: "tail", arguments_ :{ element:s } }) }; + var peg$f14 = function(s) { return x => x.options_['ops'].push({ type_: "range", arguments_ :{ element:s } }) }; + var peg$f15 = function(s, ops) { const result = new ElementStub(s, {ops: [], weight: 1, reps: 1}); for (const op of ops) { op(result); } return result; }; - var peg$f14 = function(s) { return new PatternStub(s, 'fastcat'); }; - var peg$f15 = function(tail) { return { alignment: 'stack', list: tail }; }; - var peg$f16 = function(tail) { return { alignment: 'rand', list: tail, seed: seed++ }; }; - var peg$f17 = function(head, tail) { if (tail && tail.list.length > 0) { return new PatternStub([head, ...tail.list], tail.alignment, tail.seed); } else { return head; } }; - var peg$f18 = function(head, tail) { return new PatternStub(tail ? [head, ...tail.list] : [head], 'polymeter'); }; - var peg$f19 = function(sc) { return sc; }; - var peg$f20 = function(s) { return { name: "struct", args: { mini:s }}}; - var peg$f21 = function(s) { return { name: "target", args : { name:s}}}; - var peg$f22 = function(p, s, r) { return { name: "bjorklund", args :{ pulse: p, step:parseInt(s) }}}; - var peg$f23 = function(a) { return { name: "stretch", args :{ amount: a}}}; - var peg$f24 = function(a) { return { name: "shift", args :{ amount: "-"+a}}}; - var peg$f25 = function(a) { return { name: "shift", args :{ amount: a}}}; - var peg$f26 = function(a) { return { name: "stretch", args :{ amount: "1/"+a}}}; - var peg$f27 = function(s) { return { name: "scale", args :{ scale: s.join("")}}}; - var peg$f28 = function(s, v) { return v}; - var peg$f29 = function(s, ss) { ss.unshift(s); return new PatternStub(ss, 'slowcat'); }; - var peg$f30 = function(sg) {return sg}; - var peg$f31 = function(o, soc) { return new OperatorStub(o.name,o.args,soc)}; - var peg$f32 = function(sc) { return sc }; - var peg$f33 = function(c) { return c }; - var peg$f34 = function(v) { return new CommandStub("setcps", { value: v})}; - var peg$f35 = function(v) { return new CommandStub("setcps", { value: (v/120/2)})}; - var peg$f36 = function() { return new CommandStub("hush")}; + var peg$f16 = function(s) { return new PatternStub(s, 'fastcat'); }; + var peg$f17 = function(tail) { return { alignment: 'stack', list: tail }; }; + var peg$f18 = function(tail) { return { alignment: 'rand', list: tail, seed: seed++ }; }; + var peg$f19 = function(head, tail) { if (tail && tail.list.length > 0) { return new PatternStub([head, ...tail.list], tail.alignment, tail.seed); } else { return head; } }; + var peg$f20 = function(head, tail) { return new PatternStub(tail ? [head, ...tail.list] : [head], 'polymeter'); }; + var peg$f21 = function(sc) { return sc; }; + var peg$f22 = function(s) { return { name: "struct", args: { mini:s }}}; + var peg$f23 = function(s) { return { name: "target", args : { name:s}}}; + var peg$f24 = function(p, s, r) { return { name: "bjorklund", args :{ pulse: p, step:parseInt(s) }}}; + var peg$f25 = function(a) { return { name: "stretch", args :{ amount: a}}}; + var peg$f26 = function(a) { return { name: "shift", args :{ amount: "-"+a}}}; + var peg$f27 = function(a) { return { name: "shift", args :{ amount: a}}}; + var peg$f28 = function(a) { return { name: "stretch", args :{ amount: "1/"+a}}}; + var peg$f29 = function(s) { return { name: "scale", args :{ scale: s.join("")}}}; + var peg$f30 = function(s, v) { return v}; + var peg$f31 = function(s, ss) { ss.unshift(s); return new PatternStub(ss, 'slowcat'); }; + var peg$f32 = function(sg) {return sg}; + var peg$f33 = function(o, soc) { return new OperatorStub(o.name,o.args,soc)}; + var peg$f34 = function(sc) { return sc }; + var peg$f35 = function(c) { return c }; + var peg$f36 = function(v) { return new CommandStub("setcps", { value: v})}; + var peg$f37 = function(v) { return new CommandStub("setcps", { value: (v/120/2)})}; + var peg$f38 = function() { return new CommandStub("hush")}; var peg$currPos = 0; var peg$savedPos = 0; var peg$posDetailsCache = [{ line: 1, column: 1 }]; @@ -651,6 +655,26 @@ function peg$parse(input, options) { return s0; } + function peg$parseintneg() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = peg$parseminus(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parseint(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f1(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + function peg$parseminus() { var s0; @@ -884,7 +908,7 @@ function peg$parse(input, options) { if (s2 !== peg$FAILED) { s3 = peg$parsews(); peg$savedPos = s0; - s0 = peg$f1(s2); + s0 = peg$f2(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -920,7 +944,7 @@ function peg$parse(input, options) { if (s6 !== peg$FAILED) { s7 = peg$parsews(); peg$savedPos = s0; - s0 = peg$f2(s4); + s0 = peg$f3(s4); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -968,7 +992,7 @@ function peg$parse(input, options) { } s8 = peg$parsews(); peg$savedPos = s0; - s0 = peg$f3(s4, s7); + s0 = peg$f4(s4, s7); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1000,7 +1024,7 @@ function peg$parse(input, options) { s2 = peg$parseslice(); if (s2 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f4(s2); + s0 = peg$f5(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1040,7 +1064,7 @@ function peg$parse(input, options) { if (s6 !== peg$FAILED) { s7 = peg$parsews(); peg$savedPos = s0; - s0 = peg$f5(s4); + s0 = peg$f6(s4); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1090,6 +1114,9 @@ function peg$parse(input, options) { s0 = peg$parseop_degrade(); if (s0 === peg$FAILED) { s0 = peg$parseop_tail(); + if (s0 === peg$FAILED) { + s0 = peg$parseop_range(); + } } } } @@ -1115,7 +1142,7 @@ function peg$parse(input, options) { s2 = peg$parsenumber(); if (s2 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f6(s2); + s0 = peg$f7(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1143,7 +1170,7 @@ function peg$parse(input, options) { s2 = peg$parsenumber(); if (s2 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f7(s2); + s0 = peg$f8(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1197,7 +1224,7 @@ function peg$parse(input, options) { } if (s13 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f8(s3, s7, s11); + s0 = peg$f9(s3, s7, s11); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1237,7 +1264,7 @@ function peg$parse(input, options) { s2 = peg$parseslice(); if (s2 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f9(s2); + s0 = peg$f10(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1265,7 +1292,7 @@ function peg$parse(input, options) { s2 = peg$parseslice(); if (s2 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f10(s2); + s0 = peg$f11(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1295,7 +1322,7 @@ function peg$parse(input, options) { s2 = null; } peg$savedPos = s0; - s0 = peg$f11(s2); + s0 = peg$f12(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1319,7 +1346,35 @@ function peg$parse(input, options) { s2 = peg$parseslice(); if (s2 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f12(s2); + s0 = peg$f13(s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseop_range() { + var s0, s1, s2; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c26) { + s1 = peg$c26; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e33); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseslice(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f14(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1345,7 +1400,7 @@ function peg$parse(input, options) { s3 = peg$parseslice_op(); } peg$savedPos = s0; - s0 = peg$f13(s1, s2); + s0 = peg$f15(s1, s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1370,7 +1425,7 @@ function peg$parse(input, options) { } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f14(s1); + s1 = peg$f16(s1); } s0 = s1; @@ -1419,7 +1474,7 @@ function peg$parse(input, options) { } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f15(s1); + s1 = peg$f17(s1); } s0 = s1; @@ -1468,7 +1523,7 @@ function peg$parse(input, options) { } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f16(s1); + s1 = peg$f18(s1); } s0 = s1; @@ -1489,7 +1544,7 @@ function peg$parse(input, options) { s2 = null; } peg$savedPos = s0; - s0 = peg$f17(s1, s2); + s0 = peg$f19(s1, s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1509,7 +1564,7 @@ function peg$parse(input, options) { s2 = null; } peg$savedPos = s0; - s0 = peg$f18(s1, s2); + s0 = peg$f20(s1, s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1532,7 +1587,7 @@ function peg$parse(input, options) { s6 = peg$parsequote(); if (s6 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f19(s4); + s0 = peg$f21(s4); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1582,19 +1637,19 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c26) { - s1 = peg$c26; + if (input.substr(peg$currPos, 6) === peg$c27) { + s1 = peg$c27; peg$currPos += 6; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } + if (peg$silentFails === 0) { peg$fail(peg$e34); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); s3 = peg$parsemini_or_operator(); if (s3 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f20(s3); + s0 = peg$f22(s3); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1611,12 +1666,12 @@ function peg$parse(input, options) { var s0, s1, s2, s3, s4, s5; s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c27) { - s1 = peg$c27; + if (input.substr(peg$currPos, 6) === peg$c28) { + s1 = peg$c28; peg$currPos += 6; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } + if (peg$silentFails === 0) { peg$fail(peg$e35); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); @@ -1627,7 +1682,7 @@ function peg$parse(input, options) { s5 = peg$parsequote(); if (s5 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f21(s4); + s0 = peg$f23(s4); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1652,12 +1707,12 @@ function peg$parse(input, options) { var s0, s1, s2, s3, s4, s5, s6, s7; s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c28) { - s1 = peg$c28; + if (input.substr(peg$currPos, 6) === peg$c29) { + s1 = peg$c29; peg$currPos += 6; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } + if (peg$silentFails === 0) { peg$fail(peg$e36); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); @@ -1672,7 +1727,7 @@ function peg$parse(input, options) { s7 = null; } peg$savedPos = s0; - s0 = peg$f22(s3, s5, s7); + s0 = peg$f24(s3, s5, s7); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1693,19 +1748,19 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c29) { - s1 = peg$c29; + if (input.substr(peg$currPos, 4) === peg$c30) { + s1 = peg$c30; peg$currPos += 4; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } + if (peg$silentFails === 0) { peg$fail(peg$e37); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); s3 = peg$parsenumber(); if (s3 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f23(s3); + s0 = peg$f25(s3); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1722,19 +1777,19 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c30) { - s1 = peg$c30; + if (input.substr(peg$currPos, 4) === peg$c31) { + s1 = peg$c31; peg$currPos += 4; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } + if (peg$silentFails === 0) { peg$fail(peg$e38); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); s3 = peg$parsenumber(); if (s3 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f24(s3); + s0 = peg$f26(s3); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1751,19 +1806,19 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c31) { - s1 = peg$c31; + if (input.substr(peg$currPos, 4) === peg$c32) { + s1 = peg$c32; peg$currPos += 4; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e38); } + if (peg$silentFails === 0) { peg$fail(peg$e39); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); s3 = peg$parsenumber(); if (s3 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f25(s3); + s0 = peg$f27(s3); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1780,19 +1835,19 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c32) { - s1 = peg$c32; + if (input.substr(peg$currPos, 4) === peg$c33) { + s1 = peg$c33; peg$currPos += 4; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e39); } + if (peg$silentFails === 0) { peg$fail(peg$e40); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); s3 = peg$parsenumber(); if (s3 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f26(s3); + s0 = peg$f28(s3); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1809,12 +1864,12 @@ function peg$parse(input, options) { var s0, s1, s2, s3, s4, s5; s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c33) { - s1 = peg$c33; + if (input.substr(peg$currPos, 5) === peg$c34) { + s1 = peg$c34; peg$currPos += 5; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e40); } + if (peg$silentFails === 0) { peg$fail(peg$e41); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); @@ -1834,7 +1889,7 @@ function peg$parse(input, options) { s5 = peg$parsequote(); if (s5 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f27(s4); + s0 = peg$f29(s4); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -1859,12 +1914,12 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c34) { - s1 = peg$c34; + if (input.substr(peg$currPos, 2) === peg$c35) { + s1 = peg$c35; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e41); } + if (peg$silentFails === 0) { peg$fail(peg$e42); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1873,7 +1928,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e42); } + if (peg$silentFails === 0) { peg$fail(peg$e43); } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -1882,7 +1937,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e42); } + if (peg$silentFails === 0) { peg$fail(peg$e43); } } } s1 = [s1, s2]; @@ -1899,12 +1954,12 @@ function peg$parse(input, options) { var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c35) { - s1 = peg$c35; + if (input.substr(peg$currPos, 3) === peg$c36) { + s1 = peg$c36; peg$currPos += 3; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e43); } + if (peg$silentFails === 0) { peg$fail(peg$e44); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); @@ -1926,7 +1981,7 @@ function peg$parse(input, options) { s9 = peg$parsemini_or_operator(); if (s9 !== peg$FAILED) { peg$savedPos = s7; - s7 = peg$f28(s5, s9); + s7 = peg$f30(s5, s9); } else { peg$currPos = s7; s7 = peg$FAILED; @@ -1943,7 +1998,7 @@ function peg$parse(input, options) { s9 = peg$parsemini_or_operator(); if (s9 !== peg$FAILED) { peg$savedPos = s7; - s7 = peg$f28(s5, s9); + s7 = peg$f30(s5, s9); } else { peg$currPos = s7; s7 = peg$FAILED; @@ -1963,7 +2018,7 @@ function peg$parse(input, options) { } if (s8 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f29(s5, s6); + s0 = peg$f31(s5, s6); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -2009,7 +2064,7 @@ function peg$parse(input, options) { s4 = peg$parsecomment(); } peg$savedPos = s0; - s0 = peg$f30(s1); + s0 = peg$f32(s1); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -2020,18 +2075,18 @@ function peg$parse(input, options) { if (s1 !== peg$FAILED) { s2 = peg$parsews(); if (input.charCodeAt(peg$currPos) === 36) { - s3 = peg$c36; + s3 = peg$c37; peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e44); } + if (peg$silentFails === 0) { peg$fail(peg$e45); } } if (s3 !== peg$FAILED) { s4 = peg$parsews(); s5 = peg$parsemini_or_operator(); if (s5 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f31(s1, s5); + s0 = peg$f33(s1, s5); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -2056,7 +2111,7 @@ function peg$parse(input, options) { s1 = peg$parsemini_or_operator(); if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f32(s1); + s1 = peg$f34(s1); } s0 = s1; if (s0 === peg$FAILED) { @@ -2089,7 +2144,7 @@ function peg$parse(input, options) { if (s2 !== peg$FAILED) { s3 = peg$parsews(); peg$savedPos = s0; - s0 = peg$f33(s2); + s0 = peg$f35(s2); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -2102,19 +2157,19 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c37) { - s1 = peg$c37; + if (input.substr(peg$currPos, 6) === peg$c38) { + s1 = peg$c38; peg$currPos += 6; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e45); } + if (peg$silentFails === 0) { peg$fail(peg$e46); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); s3 = peg$parsenumber(); if (s3 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f34(s3); + s0 = peg$f36(s3); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -2131,19 +2186,19 @@ function peg$parse(input, options) { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c38) { - s1 = peg$c38; + if (input.substr(peg$currPos, 6) === peg$c39) { + s1 = peg$c39; peg$currPos += 6; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e46); } + if (peg$silentFails === 0) { peg$fail(peg$e47); } } if (s1 !== peg$FAILED) { s2 = peg$parsews(); s3 = peg$parsenumber(); if (s3 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f35(s3); + s0 = peg$f37(s3); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -2160,16 +2215,16 @@ function peg$parse(input, options) { var s0, s1; s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c39) { - s1 = peg$c39; + if (input.substr(peg$currPos, 4) === peg$c40) { + s1 = peg$c40; peg$currPos += 4; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e47); } + if (peg$silentFails === 0) { peg$fail(peg$e48); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f36(); + s1 = peg$f38(); } s0 = s1; diff --git a/packages/mini/krill.pegjs b/packages/mini/krill.pegjs index 72b453bea..f52743bfc 100644 --- a/packages/mini/krill.pegjs +++ b/packages/mini/krill.pegjs @@ -79,6 +79,9 @@ frac int = zero / (digit1_9 DIGIT*) +intneg + = minus? int { return parseInt(text()); } + minus = "-" @@ -123,7 +126,7 @@ slice = step / sub_cycle / polymeter / slow_sequence // slice modifier affects the timing/size of a slice (e.g. [a b c]@3) // at this point, we assume we can represent them as regular sequence operators -slice_op = op_weight / op_bjorklund / op_slow / op_fast / op_replicate / op_degrade / op_tail +slice_op = op_weight / op_bjorklund / op_slow / op_fast / op_replicate / op_degrade / op_tail / op_range op_weight = "@" a:number { return x => x.options_['weight'] = a } @@ -146,6 +149,9 @@ op_degrade = "?"a:number? op_tail = ":" s:slice { return x => x.options_['ops'].push({ type_: "tail", arguments_ :{ element:s } }) } +op_range = ".." s:slice + { return x => x.options_['ops'].push({ type_: "range", arguments_ :{ element:s } }) } + // a slice with an modifier applied i.e [bd@4 sd@3]@2 hh] slice_with_ops = s:slice ops:slice_op* { const result = new ElementStub(s, {ops: [], weight: 1, reps: 1}); diff --git a/packages/mini/mini.mjs b/packages/mini/mini.mjs index 3321e7bc6..8e6b844f0 100644 --- a/packages/mini/mini.mjs +++ b/packages/mini/mini.mjs @@ -45,6 +45,17 @@ const applyOptions = (parent, enter) => (pat, i) => { pat = pat.fmap((a) => (b) => Array.isArray(a) ? [...a, b] : [a, b]).appLeft(friend); break; } + case 'range': { + const friend = enter(op.arguments_.element); + pat = strudel.reify(pat); + const arrayRange = (start, stop, step = 1) => + Array.from({ length: Math.abs(stop - start) / step + 1 }, (value, index) => + start < stop ? start + index * step : start - index * step, + ); + let range = (apat, bpat) => apat.squeezeBind((a) => bpat.bind((b) => strudel.fastcat(...arrayRange(a, b)))); + pat = range(pat, friend); + break; + } default: { console.warn(`operator "${op.type_}" not implemented`); } diff --git a/packages/mini/test/mini.test.mjs b/packages/mini/test/mini.test.mjs index 0c7f381e9..6d9ac3671 100644 --- a/packages/mini/test/mini.test.mjs +++ b/packages/mini/test/mini.test.mjs @@ -184,6 +184,12 @@ describe('mini', () => { it('supports lists', () => { expect(minV('a:b c:d:[e:f] g')).toEqual([['a', 'b'], ['c', 'd', ['e', 'f']], 'g']); }); + it('supports ranges', () => { + expect(minV('0 .. 4')).toEqual([0, 1, 2, 3, 4]); + }); + it('supports patterned ranges', () => { + expect(minS('[<0 1> .. <2 4>]*2')).toEqual(minS('[0 1 2] [1 2 3 4]')); + }); }); describe('getLeafLocation', () => {