Skip to content

Commit

Permalink
Add support for re-assignment using arrays of indices
Browse files Browse the repository at this point in the history
  • Loading branch information
frostburn committed Apr 27, 2024
1 parent 83fbd5b commit a751d90
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/parser/__tests__/stdlib.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1356,4 +1356,20 @@ describe('SonicWeave standard library', () => {
`);
expect(major).toEqual(['9/8', '5/4', '4/3', '3/2', '5/3', '15/8', '2/1']);
});

it('parses Rage Todi (golfed)', () => {
const scale = expand(`
rank2(3/2 white, 1, 5, 2/1 white)
$[[2, 5]] *~= 135/128 black
`);
expect(scale).toEqual([
'256/243 white',
'32/27 white',
'45/32 black',
'3/2 white',
'128/81 white',
'15/8 black',
'2/1 white',
]);
});
});
26 changes: 26 additions & 0 deletions src/parser/statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,32 @@ export class StatementVisitor {
}
if (Array.isArray(object)) {
const index = subVisitor.visit(node.name.key);
if (Array.isArray(index)) {
if (!Array.isArray(value)) {
throw new Error('Unrecoverable error in array assignment.');
}
let j = 0;
for (let i = 0; i < index.length; ++i) {
const idx = index[i];
if (!(typeof idx === 'boolean' || idx instanceof Interval)) {
throw new Error(
'Only booleans and intervals can be used as indices.'
);
}
if (idx === true) {
object[i] = value[j++];
continue;
} else if (idx === false) {
continue;
}
let k = idx.toInteger();
if (k < 0) {
k += object.length;
}
object[k] = value[j++];
}
return undefined;
}
if (!(index instanceof Interval)) {
throw new Error('Array access with a non-integer.');
}
Expand Down

0 comments on commit a751d90

Please sign in to comment.