From 3505732afad89870286d2c0083887375c62e6b44 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 20 Mar 2025 09:34:47 +0100 Subject: [PATCH] mondo: add .. operator --- packages/mondo/mondo.mjs | 2 +- packages/mondo/test/mondo.test.mjs | 1 + packages/mondough/mondough.mjs | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index 5997feb40..70c58aa6d 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -17,9 +17,9 @@ export class MondoParser { open_seq: /^\[/, close_seq: /^\]/, number: /^-?[0-9]*\.?[0-9]+/, // before pipe! + op: /^[*\/:]|^\.{2}/, // * / : .. pipe: /^\./, stack: /^[,$]/, - op: /^[*/:]/, plain: /^[a-zA-Z0-9-~_^]+/, }; // matches next token diff --git a/packages/mondo/test/mondo.test.mjs b/packages/mondo/test/mondo.test.mjs index e21ec75b0..aadbafbeb 100644 --- a/packages/mondo/test/mondo.test.mjs +++ b/packages/mondo/test/mondo.test.mjs @@ -102,6 +102,7 @@ describe('mondo sugar', () => { it('should desugar x:y', () => expect(desguar('x:y')).toEqual('(: x y)')); it('should desugar x:y:z', () => expect(desguar('x:y:z')).toEqual('(: (: x y) z)')); it('should desugar x:y*x', () => expect(desguar('bd:0*2')).toEqual('(* (: bd 0) 2)')); + it('should desugar a..b', () => expect(desguar('0..2')).toEqual('(.. 0 2)')); it('should desugar README example', () => expect(desguar('s [bd hh*2 cp.(crush 4) ] . speed .8')).toEqual( diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index 33e0116df..e69ea0994 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -21,7 +21,7 @@ strudelScope.leaf = (token, scope) => { strudelScope.call = (fn, args, name) => { const [pat, ...rest] = args; - if (!['seq', 'cat', 'stack', ':'].includes(name)) { + if (!['seq', 'cat', 'stack', ':', '..'].includes(name)) { args = [...rest, pat]; } return fn(...args); @@ -30,9 +30,18 @@ strudelScope.call = (fn, args, name) => { strudelScope['*'] = fast; strudelScope['/'] = slow; +// : operator const tail = (pat, friend) => pat.fmap((a) => (b) => (Array.isArray(a) ? [...a, b] : [a, b])).appLeft(friend); strudelScope[':'] = tail; +// .. operator +const arrayRange = (start, stop, step = 1) => + Array.from({ length: Math.abs(stop - start) / step + 1 }, (_, index) => + start < stop ? start + index * step : start - index * step, + ); +const range = (min, max) => min.squeezeBind((a) => max.bind((b) => seq(...arrayRange(a, b)))); +strudelScope['..'] = range; + export function mondo(code, offset = 0) { if (Array.isArray(code)) { code = code.join('');