From bd93e441546cd4a9a28dc4b121413f149fbf9b61 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 21 Mar 2025 22:34:53 +0100 Subject: [PATCH] mondo: fix combination of | and , --- packages/mondo/mondo.mjs | 36 +++++++++++++++--------------- packages/mondo/test/mondo.test.mjs | 3 +++ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index 815450263..ba1b3c568 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -107,11 +107,7 @@ export class MondoParser { return children; } // Token[] => Token[][] . returns empty list if type not found - split_children(children, split_type, sequence_type) { - if (sequence_type) { - // if given, the first child is ignored - children = children.slice(1); - } + split_children(children, split_type) { const chunks = []; while (true) { let commaIndex = children.findIndex((child) => child.type === split_type); @@ -126,11 +122,10 @@ export class MondoParser { chunks.push(children); return chunks; } - desugar_split(children, split_type, sequence_type) { - // children is expected to contain square or angle as first item - const chunks = this.split_children(children, split_type, sequence_type); + desugar_split(children, split_type, next) { + const chunks = this.split_children(children, split_type); if (!chunks.length) { - return this.desugar_children(children); + return next(children); } // collect args of stack function const args = chunks.map((chunk) => { @@ -139,12 +134,7 @@ export class MondoParser { return chunk[0]; } else { // chunks of multiple args - if (sequence_type) { - // if given, each chunk needs to be prefixed - // [a b, c d] => (stack (square a b) (square c d)) - chunk = [{ type: 'plain', value: sequence_type }, ...chunk]; - } - chunk = this.desugar_children(chunk); + chunk = next(chunk); return { type: 'list', children: chunk }; } }); @@ -241,9 +231,19 @@ export class MondoParser { return children; } desugar(children, type) { - // not really needed but more readable and might be extended in the future - children = this.desugar_split(children, 'or', type); - children = this.desugar_split(children, 'stack', type); + // if type is given, the first element is expected to contain it as plain value + // e.g. with (square a b, c), we want to split (a b, c) and ignore "square" + children = type ? children.slice(1) : children; + children = this.desugar_split(children, 'stack', (children) => + this.desugar_split(children, 'or', (children) => { + // chunks of multiple args + if (type) { + // the type we've removed before splitting needs to be added back + children = [{ type: 'plain', value: type }, ...children]; + } + return this.desugar_children(children); + }), + ); return children; } parse_list() { diff --git a/packages/mondo/test/mondo.test.mjs b/packages/mondo/test/mondo.test.mjs index 1b9a41e3d..c51844be0 100644 --- a/packages/mondo/test/mondo.test.mjs +++ b/packages/mondo/test/mondo.test.mjs @@ -90,6 +90,9 @@ describe('mondo sugar', () => { it('should desugar . ()', () => expect(desguar('[jazz hh.(fast 2)]')).toEqual('(square jazz (fast hh 2))')); + it('should desugar , |', () => expect(desguar('[bd, hh | oh]')).toEqual('(stack bd (or hh oh))')); + it('should desugar , | of []', () => + expect(desguar('[bd, hh | [oh rim]]')).toEqual('(stack bd (or hh (square oh rim)))')); it('should desugar , square', () => expect(desguar('[bd, hh]')).toEqual('(stack bd hh)')); it('should desugar , square 2', () => expect(desguar('[bd, hh oh]')).toEqual('(stack bd (square hh oh))')); it('should desugar , square 3', () =>