Skip to content

Commit

Permalink
Track how slots merge in serial descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
lynn committed Jul 19, 2024
1 parent 0cbab0c commit 3dc8115
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 33 deletions.
15 changes: 10 additions & 5 deletions src/syntax/serial.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ function describe(text: string): [boolean, string] {
const description = describeSerial(children);
if (!description) return [false, 'bizarre'];
const slots = description.slots
.map(
({ verbIndex, slotIndex }) =>
`${children[verbIndex].source}${slotIndex + 1}`,
.map(group =>
group
.map(
({ verbIndex, slotIndex }) =>
`${children[verbIndex].source}${slotIndex + 1}`,
)
.join('='),
)
.join(' ');
return [description.didSerialize, slots];
Expand All @@ -56,7 +60,8 @@ test('it describes serials', () => {
expect(describe('jaq cho')).toEqual([true, 'cho1 cho2']);
expect(describe('dua cho')).toEqual([true, 'dua1 cho1 cho2']);
expect(describe('rua jaq de')).toEqual([true, 'rua1']);
expect(describe('leo baı')).toEqual([true, 'leo1 baı2']);
expect(describe('taq cho')).toEqual([true, 'taq1']);
expect(describe('leo baı')).toEqual([true, 'leo1=baı1 baı2']);
expect(describe('taq cho')).toEqual([true, 'taq1=cho1=cho2']);
expect(describe('chı do')).toEqual([true, 'chı1 do1 do2 do3']);
expect(describe('nue do')).toEqual([true, 'nue1=do1 nue2 do2 do3']);
});
27 changes: 16 additions & 11 deletions src/syntax/serial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ export interface SerialSlot {
}

export interface SerialDescription {
slots: SerialSlot[];
slots: SerialSlot[][];
didSerialize: boolean;
}

Expand All @@ -360,10 +360,11 @@ export interface SerialDescription {
*
* {
* slots: [
* { verbIndex: 0, slotIndex: 0 }, // nue's subject
* { verbIndex: 0, slotIndex: 1 }, // nue's indirect object
* { verbIndex: 1, slotIndex: 1 }, // do's indirect object
* { verbIndex: 1, slotIndex: 2 }, // do's direct object
* [ { verbIndex: 0, slotIndex: 0 }, // nue's subject
* { verbIndex: 1, slotIndex: 0 } ], // = do's subject
* [ { verbIndex: 0, slotIndex: 1 } ], // nue's indirect object
* [ { verbIndex: 1, slotIndex: 1 } ], // do's indirect object
* [ { verbIndex: 1, slotIndex: 2 } ], // do's direct object
* ],
* didSerialize: true,
* }
Expand All @@ -379,21 +380,25 @@ export function describeSerial(
const frames = children.map(getFrame);
if (frames.includes('?')) return undefined;
const frame = splitNonEmpty(frames[n - 1], ' ');
let slots = frame.map((_, j) => ({ verbIndex: n - 1, slotIndex: j }));
let slots = frame.map((_, j) => [{ verbIndex: n - 1, slotIndex: j }]);
let didSerialize = false;
for (let i = n - 2; i >= 0; i--) {
const frame = splitNonEmpty(frames[i], ' ');
const last = frame.at(-1)!;
if (/c/.test(last)) {
// Wipe the whole description, it was just an adjective:
slots = frame.map((_, j) => ({ verbIndex: i, slotIndex: j }));
slots = frame.map((_, j) => [{ verbIndex: i, slotIndex: j }]);
} else {
// Introduce some new slots and merge away some old slots:
didSerialize = true;
slots = [
...frame.slice(0, -1).map((_, j) => ({ verbIndex: i, slotIndex: j })),
...slots.slice(Number(last[0])),
];
const newSlots = frame
.slice(0, -1)
.map((_, j) => [{ verbIndex: i, slotIndex: j }]);
for (let x = 1; x < last.length; x++) {
if (last[x] === 'i') newSlots[0].push(...slots[x - 1]);
if (last[x] === 'j') newSlots[1].push(...slots[x - 1]);
}
slots = [...newSlots, ...slots.slice(Number(last[0]))];
}
}
return { slots, didSerialize };
Expand Down
5 changes: 5 additions & 0 deletions src/web/Boxes.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
margin: 2px 2px 0px 2px;
}

.boxes-col {
display: flex;
flex-direction: column;
}

.boxes-children {
flex: 1;
display: flex;
Expand Down
39 changes: 22 additions & 17 deletions src/web/Boxes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,28 @@ function argumentDescriptions(serial: Tree): JSX.Element[] {
if (serial && 'children' in serial) {
const children = serial.children;
const description = describeSerial(children);
return (description?.slots ?? []).map(({ verbIndex, slotIndex }, i) => {
const verb = children[verbIndex];
const frame = getFrame(verb);
const arity = splitNonEmpty(frame, ' ').length;
const roles =
arity === 3
? ['Subject', 'Indirect object', 'Direct object']
: ['Subject', 'Object'];
const key = i;
return description?.didSerialize ? (
<span key={key}>
{roles[slotIndex]} of <b>{verb.source.toLowerCase()}</b>
</span>
) : (
<span key={key}>{roles[slotIndex]}</span>
);
});
return (description?.slots ?? []).map((group, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: order is stable
<div className="boxes-col" key={i}>
{group.map(({ verbIndex, slotIndex }, j) => {
const verb = children[verbIndex];
const frame = getFrame(verb);
const arity = splitNonEmpty(frame, ' ').length;
const roles =
arity === 3
? ['Subject', 'Indirect object', 'Direct object']
: ['Subject', 'Object'];
const key = 1000 * i + j;
return description?.didSerialize ? (
<span key={key}>
{roles[slotIndex]} of <b>{verb.source.toLowerCase()}</b>
</span>
) : (
<span key={key}>{roles[slotIndex]}</span>
);
})}
</div>
));
}
return [];
}
Expand Down

0 comments on commit 3dc8115

Please sign in to comment.