diff --git a/documentation/BUILTIN.md b/documentation/BUILTIN.md index 0842f18..848823b 100644 --- a/documentation/BUILTIN.md +++ b/documentation/BUILTIN.md @@ -791,9 +791,6 @@ Generate a vertically aligned object i.e. a subset of the harmonic series that s ### vbool(*value*) Convert value to a boolean. Vectorizes over arrays. -### void() -Get rid of expression results. `void(++i)` increments the value but doesn't push anything onto the scale. - ### weilHeight(*x*) Calculate the Weil height of the interval. Natural logarithm of the maximum of numerator or denominator. diff --git a/documentation/advanced-dsl.md b/documentation/advanced-dsl.md index cfb0306..a4f8bfa 100644 --- a/documentation/advanced-dsl.md +++ b/documentation/advanced-dsl.md @@ -576,7 +576,7 @@ Associating two values like `3/2 "fif"` invokes intrinsic behavior between the i Semantics of the expression `left right` follow this matrix depending on the types of the operands. Booleans are converted to `0` or `1` and follow interval semantics. Question marks indicate undefined behavior. Exclamation marks indicate that previous behavior has been depracated. | left↓ right→ | Niente | String | Color | Interval | Val | Basis | Function | | ------------ | ------------- | ------------- | ------------- | -------------- | -------------- | ------------- | ------------- | -| **Niente** | ? | ? | ? | bleach | ? | ? | `right(left)` | +| **Niente** | `niente` | `niente` | `niente` | `niente` | `niente` | `niente` | `niente` | | **String** | ? | concatenate | ? | label | ? | ? | `right(left)` | | **Color** | ? | ? | ? | paint | ? | ? | `right(left)` | | **Interval** | bleach | label | paint | ?! | ?! | rebase | `right(left)` | @@ -584,6 +584,8 @@ Semantics of the expression `left right` follow this matrix depending on the typ | **Basis** | ? | ? | ? | rebase | rebase | ? | `right(left)` | | **Function** | `left(right)` | `left(right)` | `left(right)` | `left(right)` | `left(right)` | `left(right)` | `left(right)` | +The behavior for `niente` is designed so that `niente(++i)` works like `void(++i)` in JavaScript and that `niente 3/2 white "fif"` absorbs everything like a `//` comment would in JS. + Intrinsic behavior vectorizes and broadcasts like other binary operations. Intrinsic behavior may be evoked explicitly by simply calling a value e.g. `3/2("fif")` and `"fif"(3/2)` both work. diff --git a/examples/hexany.sw b/examples/hexany.sw index 7930815..c3b7b51 100644 --- a/examples/hexany.sw +++ b/examples/hexany.sw @@ -30,7 +30,7 @@ sort() (* Shift out the 3/3 because the unison should be implicit *) (* Voiding is required to avoid pushing the first element on top instead *) -void(shift()) +niente shift() (* Add the octave to finish off *) 2 diff --git a/src/parser/__tests__/source.spec.ts b/src/parser/__tests__/source.spec.ts index a95615d..ac8c965 100644 --- a/src/parser/__tests__/source.spec.ts +++ b/src/parser/__tests__/source.spec.ts @@ -2275,4 +2275,36 @@ describe('SonicWeave parser', () => { const scale = expand('sort(3/2 ^ [-2..2] rdc 2)'); expect(scale).toEqual(['9/8', '4/3', '3/2', '16/9', '2/1']); }); + + it('has an unpaired comment of sorts', () => { + const scale = expand(` + 9/8 red "tone" + niente 5/4 green "blue" + 3/2 white + 2/1 + niente FJS + `); + expect(scale).toEqual(['9/8 "tone" red', '3/2 white', '2/1']); + }); + + it('has a void', () => { + const scale = expand(` + let i = 2 + ++i + niente(++i) + ++i + 2 + `); + expect(scale).toEqual(['let i = 5', '3', '5', '2']); + }); + + it('has a hard unpaired comment of sorts', () => { + const scale = expand(` + 5 + 3 + 2 + niente and reduce() + `); + expect(scale).toEqual(['5', '3', '2']); + }); }); diff --git a/src/parser/__tests__/stdlib.spec.ts b/src/parser/__tests__/stdlib.spec.ts index 90e671f..39f6218 100644 --- a/src/parser/__tests__/stdlib.spec.ts +++ b/src/parser/__tests__/stdlib.spec.ts @@ -349,10 +349,8 @@ describe('SonicWeave standard library', () => { }); it('can access docstrings', () => { - const doc = evaluateExpression('doc(void)'); - expect(doc).toBe( - "Get rid of expression results. `void(++i)` increments the value but doesn't push anything onto the scale." - ); + const doc = evaluateExpression('doc(vbool)'); + expect(doc).toBe('Convert value to a boolean. Vectorizes over arrays.'); }); it('can generate the marveldene without irrational stretching', () => { @@ -674,7 +672,7 @@ describe('SonicWeave standard library', () => { }); it('pops a specific index', () => { - const scale = expand('6::12;void(pop($, 4))'); + const scale = expand('6::12;niente(pop($, 4))'); expect(scale).toEqual(['7/6', '8/6', '9/6', '10/6', '12/6']); }); diff --git a/src/parser/expression.ts b/src/parser/expression.ts index 3c8631c..173a65d 100644 --- a/src/parser/expression.ts +++ b/src/parser/expression.ts @@ -1818,7 +1818,7 @@ export class ExpressionVisitor { case 'string': return this.intrinsicStringCall(left, right); case 'undefined': - return this.intrinsicNoneCall(right); + return undefined; // Absorb everything from the left case 'boolean': return this.intrinsicIntervalCall(upcastBool(left), right); case 'function': @@ -1883,16 +1883,6 @@ export class ExpressionVisitor { return unaryBroadcast.bind(this)(caller, c => ic(callee, c)); } - protected intrinsicNoneCall(caller: SonicWeaveValue): SonicWeaveValue { - if (typeof caller === 'boolean' || caller instanceof Interval) { - caller = upcastBool(caller).shallowClone(); - caller.color = undefined; - return caller; - } - const n = this.intrinsicNoneCall.bind(this); - return unaryBroadcast.bind(this)(caller, n); - } - protected intrinsicIntervalCall( callee: Interval, caller: SonicWeaveValue diff --git a/src/stdlib/prelude.ts b/src/stdlib/prelude.ts index b32fb6d..9c15f3e 100644 --- a/src/stdlib/prelude.ts +++ b/src/stdlib/prelude.ts @@ -232,11 +232,6 @@ riff ftom(freq) { return freq/440Hz /_ 2 * 12 + 69; } -riff void() { - "Get rid of expression results. \`void(++i)\` increments the value but doesn't push anything onto the scale."; - return; -} - riff sum(terms = $$) { "Calculate the (linear) sum of the terms or the current scale."; return arrayReduce((total, element) => total +~ element, terms); @@ -644,7 +639,7 @@ riff csgs(generators, ordinal = 1, period = niente, numPeriods = 1, maxSize = 10 } sortInPlace($$); if (hasConstantStructure($$)) { - void(--ordinal); + niente(--ordinal); } } return repeat(numPeriods); @@ -870,7 +865,7 @@ riff mergeOffset(offsets, overflow = 'drop', scale = ££) { unshift(equave ~^ 0); const copies = $ tns~ offsets; - void(shift()); + niente shift(); if (overflow == 'drop') { remap(copy => copy[copy > 1 vand copy < equave], copies); @@ -937,15 +932,15 @@ riff coalesce(tolerance = 3.5, action = 'simplest', preserveBoundary = false, sc } if (not preserveBoundary) { while ($$ and labs~$$[0] <= tolerance) - void(shift($$)); + niente shift($$); while ($$ and labs~($$[-1] %~ scale[-1]) <= tolerance) - void(pop($$)); + niente pop($$); } scale[-1]; if (length($) <= 1) return $; while (length($) > 1 and $[-1] ~= $[-2]) - void(pop($, -2)); + niente pop($, -2); } riff replace(interval, replacement, scale = ££) {