From dea3c83a140ccd3ee3373b9d853e31e3c005acf3 Mon Sep 17 00:00:00 2001 From: Lumi Pakkanen Date: Mon, 9 Dec 2024 16:46:52 +0200 Subject: [PATCH] Accept lone vals for commaBasis and mappingBasis ref #422 --- documentation/BUILTIN.md | 4 ++-- src/parser/__tests__/temper.spec.ts | 14 ++++++++++++++ src/stdlib/builtin/temper.ts | 11 +++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/documentation/BUILTIN.md b/documentation/BUILTIN.md index 8ad77f4..e11f9ee 100644 --- a/documentation/BUILTIN.md +++ b/documentation/BUILTIN.md @@ -73,7 +73,7 @@ Obtain a non-negative integer that is the Unicode code point value of the charac Return the color of the interval. ### commaBasis(*temperament*) -Obtain the comma basis (null space) of a temperament. +Obtain the comma basis (null space) of a temperament or a val. ### commaList(*commas*, *basisOrLimit*, *weights*, *pureEquaves*, *fullPrimeLimit*) Construct a Temperament instance from an array of commas. Optional weights are applied multiplicatively on top of Tenney weights. Optionally equaves are normalized to pure. Optionally the full prime limit is assumed based on the commas. @@ -280,7 +280,7 @@ Obtain a "best effort" short string representing a primitive value. Vectorizes o Map a riff over the given/current scale producing a new scale. ### mappingBasis(*temperament*) -Obtain the mapping generators (preimage) of a temperament with period first. See `generatorsOf` for the tempered generators. +Obtain the mapping generators (preimage) of a temperament or a val with period first. See `generatorsOf` for the tempered generators. ### maximum(*...args*) Obtain the argument with the maximum value. diff --git a/src/parser/__tests__/temper.spec.ts b/src/parser/__tests__/temper.spec.ts index 6367c2d..d6836cf 100644 --- a/src/parser/__tests__/temper.spec.ts +++ b/src/parser/__tests__/temper.spec.ts @@ -329,6 +329,20 @@ describe('Features related to tempering', () => { expect(scale).toEqual(['1901.783 "3"', '583.905 "7/5"', '1200. "2"']); }); + it('obtains the period of a single val', () => { + const scale = expand(`{ + const [period] = mappingBasis(11@.5) + period str(period) + 11@ + }`); + expect(scale).toEqual(['1\\11 "16/15"']); + }); + + it('breaks a val into its comma basis', () => { + const scale = expand('[...commaBasis(11@.5)]'); + expect(scale).toEqual(['144/125', '135/128']); + }); + it('knows miracle is miracle', () => { const yup = evaluate( 'Temperament([10@.7, 21@.7]) == commaList([S15, S7-S8])' diff --git a/src/stdlib/builtin/temper.ts b/src/stdlib/builtin/temper.ts index 5dadcd7..1673e03 100644 --- a/src/stdlib/builtin/temper.ts +++ b/src/stdlib/builtin/temper.ts @@ -299,22 +299,29 @@ periodsOf.__doc__ = 'Obtain the number of periods per equave in a temperament.'; periodsOf.__node__ = builtinNode(periodsOf); function mappingBasis(this: ExpressionVisitor, temperament: SonicWeaveValue) { + if (temperament instanceof Val) { + temperament = builtinTemperament.bind(this)(temperament); + } if (!(temperament instanceof Temperament)) { throw new Error('A temperament is required.'); } return temperament.preimage; } mappingBasis.__doc__ = - 'Obtain the mapping generators (preimage) of a temperament with period first. See `generatorsOf` for the tempered generators.'; + 'Obtain the mapping generators (preimage) of a temperament or a val with period first. See `generatorsOf` for the tempered generators.'; mappingBasis.__node__ = builtinNode(mappingBasis); function commaBasis(this: ExpressionVisitor, temperament: SonicWeaveValue) { + if (temperament instanceof Val) { + temperament = builtinTemperament.bind(this)(temperament); + } if (!(temperament instanceof Temperament)) { throw new Error('A temperament is required.'); } return temperament.commaBasis; } -commaBasis.__doc__ = 'Obtain the comma basis (null space) of a temperament.'; +commaBasis.__doc__ = + 'Obtain the comma basis (null space) of a temperament or a val.'; commaBasis.__node__ = builtinNode(commaBasis); function PrimeMapping(