From 6273b34254dfbcfb5339c1257c06949f5c1b27a5 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 2 May 2022 09:40:06 +0100 Subject: [PATCH] Support string concatenation for add() and variants --- packages/core/pattern.mjs | 141 ++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 67 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index bfc358df..2483001c 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -832,82 +832,89 @@ function _composeOp(a, b, func) { return func(a, b); } -// pattern composers -const composers = { - set: [(a, b) => b], - keep: [(a, b) => a], - keepif: [(a, b) => (b ? a : undefined)], +// Make composers +(function() { + const num = (pat) => pat._asNumber(); + const numOrString = (pat) => pat._asNumber(false, true); - // numerical functions - add: [(a, b) => a + b, true], - sub: [(a, b) => a - b, true], - mul: [(a, b) => a * b, true], - div: [(a, b) => a / b, true], - mod: [mod, true], - pow: [Math.pow, true], - _and: [(a, b) => a & b, true], - _or: [(a, b) => a | b, true], - _xor: [(a, b) => a ^ b, true], - _lshift: [(a, b) => a << b, true], - _rshift: [(a, b) => a >> b, true], + // pattern composers + const composers = { + set: [(a, b) => b], + keep: [(a, b) => a], + keepif: [(a, b) => (b ? a : undefined)], - lt: [(a, b) => a < b], - gt: [(a, b) => a > b], - lte: [(a, b) => a <= b], - gte: [(a, b) => a >= b], - eq: [(a, b) => a == b], - eqt: [(a, b) => a === b], - ne: [(a, b) => a != b], - net: [(a, b) => a !== b], - and: [(a, b) => a && b], - or: [(a, b) => a || b], + // numerical functions + add: [(a, b) => a + b, numOrString], // support string concatenation + sub: [(a, b) => a - b, num], + mul: [(a, b) => a * b, num], + div: [(a, b) => a / b, num], + mod: [mod, num], + pow: [Math.pow, num], + _and: [(a, b) => a & b, num], + _or: [(a, b) => a | b, num], + _xor: [(a, b) => a ^ b, num], + _lshift: [(a, b) => a << b, num], + _rshift: [(a, b) => a >> b, num], - // bitwise ops - func: [(a, b) => b(a)], -}; + // TODO - force numerical comparison if both look like numbers? + lt: [(a, b) => a < b], + gt: [(a, b) => a > b], + lte: [(a, b) => a <= b], + gte: [(a, b) => a >= b], + eq: [(a, b) => a == b], + eqt: [(a, b) => a === b], + ne: [(a, b) => a != b], + net: [(a, b) => a !== b], + and: [(a, b) => a && b], + or: [(a, b) => a || b], -// generate methods to do what and how -for (const [what, [op, numerical]] of Object.entries(composers)) { - for (const how of ['In', 'Out', 'Mix', 'Squeeze', 'SqueezeOut', 'Trig', 'Trigzero']) { - Pattern.prototype[what + how] = function (...other) { - var pat = this; - other = sequence(other); - if (numerical) { - pat = pat._asNumber(); - other = other._asNumber(); + // bitwise ops + func: [(a, b) => b(a)], + }; + + // generate methods to do what and how + for (const [what, [op, preprocess]] of Object.entries(composers)) { + for (const how of ['In', 'Out', 'Mix', 'Squeeze', 'SqueezeOut', 'Trig', 'Trigzero']) { + Pattern.prototype[what + how] = function (...other) { + var pat = this; + other = sequence(other); + if (preprocess) { + pat = preprocess(pat); + other = preprocess(other); + } + var result = pat['_op' + how](other, (a) => (b) => _composeOp(a, b, op)); + // hack to remove undefs when doing 'keepif' + if (what === 'keepif') { + result = result._removeUndefineds(); + } + return result; + }; + if (how === 'Squeeze') { + // support 'squeezeIn' longhand + Pattern.prototype[what + 'SqueezeIn'] = Pattern.prototype[what + how]; } - var result = pat['_op' + how](other, (a) => (b) => _composeOp(a, b, op)); - // hack to remove undefs when doing 'keepif' - if (what === 'keepif') { - result = result._removeUndefineds(); - } - return result; - }; - if (how === 'Squeeze') { - // support 'squeezeIn' longhand - Pattern.prototype[what + 'SqueezeIn'] = Pattern.prototype[what + how]; - } - if (how === 'In') { - // default how to 'in', e.g. add == addIn - Pattern.prototype[what] = Pattern.prototype[what + how]; - } else { - // default what to 'set', e.g. squeeze = setSqueeze - if (what === 'set') { - Pattern.prototype[how.toLowerCase()] = Pattern.prototype[what + how]; + if (how === 'In') { + // default how to 'in', e.g. add == addIn + Pattern.prototype[what] = Pattern.prototype[what + how]; + } else { + // default what to 'set', e.g. squeeze = setSqueeze + if (what === 'set') { + Pattern.prototype[how.toLowerCase()] = Pattern.prototype[what + how]; + } } } } -} -// binary composers -Pattern.prototype.struct = Pattern.prototype.keepifOut; -Pattern.prototype.structAll = Pattern.prototype.keepOut; -Pattern.prototype.mask = Pattern.prototype.keepifIn; -Pattern.prototype.maskAll = Pattern.prototype.keepIn; -Pattern.prototype.reset = Pattern.prototype.keepifTrig; -Pattern.prototype.resetAll = Pattern.prototype.keepTrig; -Pattern.prototype.restart = Pattern.prototype.keepifTrigzero; -Pattern.prototype.restartAll = Pattern.prototype.keepTrigzero; + // binary composers + Pattern.prototype.struct = Pattern.prototype.keepifOut; + Pattern.prototype.structAll = Pattern.prototype.keepOut; + Pattern.prototype.mask = Pattern.prototype.keepifIn; + Pattern.prototype.maskAll = Pattern.prototype.keepIn; + Pattern.prototype.reset = Pattern.prototype.keepifTrig; + Pattern.prototype.resetAll = Pattern.prototype.keepTrig; + Pattern.prototype.restart = Pattern.prototype.keepifTrigzero; + Pattern.prototype.restartAll = Pattern.prototype.keepTrigzero; +})(); // methods of Pattern that get callable factories Pattern.prototype.patternified = [