Adapt parser and tests to new sompyler AST slot names
Sompyler commit c3b51bc renamed slots across the board: - offset.stem_note → line.stem_note (parentSlot 'offset' → 'line') - motif.stem_note → line.stem_note (parentSlot 'motif' → 'line') - clause.note/pause/stack → seq.note/pause/stack (parentSlot 'clause' → 'seq') - stem_note.chain is now a real hierarchical node (depth 04) between line.stem_note and chain.clause; clauses are now its children, not direct children of stem_note Also adds: - offset.motifs[] for line.motif invocations at tick positions - stem_note.writeToName from stem_note.write_to positional - adjacent prop already stored; new tests verify True/False/absent PaneFO.js: show offset motif invocations inline (label + chord) test-parser.mjs: update synthetic fixtures to new depths/slot names; add tests for line.motif, stem_note.write_to, adjacent prop
This commit is contained in:
@@ -439,17 +439,22 @@ function buildOffset(node) {
|
||||
type: 'offset',
|
||||
tick: node.props.tick,
|
||||
stemNotes: [],
|
||||
motifs: [],
|
||||
unknownProps: collectUnknownProps(node.props, new Set(['tick'])),
|
||||
};
|
||||
for (const child of node.children) {
|
||||
if (child.parentSlot === 'offset' && child.slot === 'stem_note')
|
||||
if (child.parentSlot === 'line' && child.slot === 'stem_note')
|
||||
offset.stemNotes.push(buildStemNote(child));
|
||||
else if (child.parentSlot === 'line' && child.slot === 'motif')
|
||||
offset.motifs.push({ label: child.positionals[0], chord: child.props.chord ?? null });
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
function buildStemNote(node) {
|
||||
const KNOWN = new Set(['pitch', 'eff_length', 'adj_stress', 'adjacent']);
|
||||
const chainNode = node.children.find(c => c.parentSlot === 'stem_note' && c.slot === 'chain');
|
||||
const writeToNode = node.children.find(c => c.parentSlot === 'stem_note' && c.slot === 'write_to');
|
||||
return {
|
||||
type: 'stem_note',
|
||||
pitch: node.props.pitch,
|
||||
@@ -458,8 +463,9 @@ function buildStemNote(node) {
|
||||
adjStress: node.props.adj_stress ?? null,
|
||||
length: null,
|
||||
weight: null,
|
||||
chainText: node.children.find(c => c.slot === 'chain')?.props._tmp_string ?? '',
|
||||
clauses: node.children
|
||||
chainText: chainNode?.props._tmp_string ?? '',
|
||||
writeToName: writeToNode?.positionals[0] ?? null,
|
||||
clauses: (chainNode?.children ?? [])
|
||||
.filter(c => c.parentSlot === 'chain' && c.slot === 'clause')
|
||||
.map(buildClause),
|
||||
isDirty: false,
|
||||
@@ -472,9 +478,9 @@ function buildClause(node) {
|
||||
type: 'clause',
|
||||
index: node.positionals[0] ?? 0,
|
||||
repeat: node.props.repeat ?? null,
|
||||
notes: node.children.filter(c => c.slot === 'note' && c.parentSlot === 'clause').map(c => ({ ...c.props })),
|
||||
pauses: node.children.filter(c => c.slot === 'pause').map(c => ({ length: c.props.length })),
|
||||
stacks: node.children.filter(c => c.slot === 'stack').map(c => ({
|
||||
notes: node.children.filter(c => c.slot === 'note' && c.parentSlot === 'seq').map(c => ({ ...c.props })),
|
||||
pauses: node.children.filter(c => c.slot === 'pause' && c.parentSlot === 'seq').map(c => ({ length: c.props.length })),
|
||||
stacks: node.children.filter(c => c.slot === 'stack' && c.parentSlot === 'seq').map(c => ({
|
||||
length: c.props.length, netlength: c.props.netlength,
|
||||
notes: c.children.filter(cn => cn.slot === 'note').map(cn => ({ ...cn.props })),
|
||||
})),
|
||||
@@ -489,7 +495,7 @@ function buildMotif(node) {
|
||||
unknownProps: collectUnknownProps(node.props, new Set(['label'])),
|
||||
};
|
||||
for (const child of node.children) {
|
||||
if (child.parentSlot === 'motif' && child.slot === 'stem_note')
|
||||
if (child.parentSlot === 'line' && child.slot === 'stem_note')
|
||||
m.stemNotes.push(buildStemNote(child));
|
||||
}
|
||||
m.isStatic = m.stemNotes.length > 0 && !m.stemNotes.some(sn => Number.isInteger(sn.pitch));
|
||||
|
||||
@@ -193,8 +193,11 @@ export const PaneFO = {
|
||||
fields: [
|
||||
{ key: 'tick', value: node.tick, editable: false },
|
||||
{ key: 'stem notes', value: node.stemNotes.map(snLabel).join(', ') || '—', editable: false },
|
||||
node.motifs?.length
|
||||
? { key: 'motifs', value: node.motifs.map(m => m.chord ? `${m.label}(${m.chord})` : m.label).join(', '), editable: false }
|
||||
: null,
|
||||
...unknownPropFields(node),
|
||||
],
|
||||
].filter(Boolean),
|
||||
onChange: null,
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user