more refactoring, monad-ish? phrase segments in the phrase compiler
This commit is contained in:
parent
e32f2cd6e7
commit
c8c2132bbf
|
@ -18,12 +18,8 @@ type SegmentDescriptions = {
|
||||||
isBa?: boolean,
|
isBa?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
type SDT = keyof SegmentDescriptions;
|
|
||||||
type Segment = { ps: T.PsString[] } & SegmentDescriptions & {
|
|
||||||
adjust: (o: { ps?: T.PsString | T.PsString[], desc?: SDT[] }) => Segment,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: make it an option to include O S V order
|
// TODO: make it an option to include O S V order
|
||||||
|
// TODO: tu ba laaR nu she hyphens all messed up
|
||||||
|
|
||||||
export function compileVP(VP: VPRendered, form: FormVersion): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } {
|
export function compileVP(VP: VPRendered, form: FormVersion): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } {
|
||||||
const verb = VP.verb.ps;
|
const verb = VP.verb.ps;
|
||||||
|
@ -59,10 +55,15 @@ function compilePs({ NPs, kids, verb: { head, rest }, negative }: CompilePsInput
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const verbWNegativeVersions = compileVerbWNegative(head, rest, negative);
|
const verbWNegativeVersions = compileVerbWNegative(head, rest, negative);
|
||||||
|
// potential different versions of where the nu goes
|
||||||
return verbWNegativeVersions.flatMap((verbSegments) => (
|
return verbWNegativeVersions.flatMap((verbSegments) => (
|
||||||
|
// potential reordering of NPs
|
||||||
NPs.flatMap(NP => {
|
NPs.flatMap(NP => {
|
||||||
|
// put in kids
|
||||||
const segments = putKidsInKidsSection([...NP, ...verbSegments], kids);
|
const segments = putKidsInKidsSection([...NP, ...verbSegments], kids);
|
||||||
|
// space out the words properly
|
||||||
const withProperSpaces = addSpacesBetweenSegments(segments);
|
const withProperSpaces = addSpacesBetweenSegments(segments);
|
||||||
|
// throw it all together into a PsString
|
||||||
return combineSegments(withProperSpaces);
|
return combineSegments(withProperSpaces);
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
@ -110,10 +111,10 @@ function getSegmentsAndKids(VP: VPRendered, form: FormVersion): { kids: Segment[
|
||||||
return {
|
return {
|
||||||
kids: [
|
kids: [
|
||||||
...VP.verb.hasBa
|
...VP.verb.hasBa
|
||||||
? [makeSegment(grammarUnits.baParticle, ["isBa"])] : [],
|
? [makeSegment(grammarUnits.baParticle, ["isBa", "isKid"])] : [],
|
||||||
...toShrink
|
...toShrink
|
||||||
? [shrink(toShrink)] : [],
|
? [shrink(toShrink)] : [],
|
||||||
].map(k => ({...k, isKid: true })),
|
],
|
||||||
NPs: [
|
NPs: [
|
||||||
[
|
[
|
||||||
...showSubject ? [makeSegment(main.subject)] : [],
|
...showSubject ? [makeSegment(main.subject)] : [],
|
||||||
|
@ -132,7 +133,7 @@ function getSegmentsAndKids(VP: VPRendered, form: FormVersion): { kids: Segment[
|
||||||
|
|
||||||
function shrink(np: Rendered<NPSelection>): Segment {
|
function shrink(np: Rendered<NPSelection>): Segment {
|
||||||
const [row, col] = getVerbBlockPosFromPerson(np.person);
|
const [row, col] = getVerbBlockPosFromPerson(np.person);
|
||||||
return makeSegment(grammarUnits.pronouns.mini[row][col], ["isMiniPronoun"]);
|
return makeSegment(grammarUnits.pronouns.mini[row][col], ["isKid", "isMiniPronoun"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {
|
function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {
|
||||||
|
@ -141,35 +142,12 @@ function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {
|
||||||
return [
|
return [
|
||||||
first,
|
first,
|
||||||
...(first.isVerbHead && rest[0] && rest[0].isVerbRest)
|
...(first.isVerbHead && rest[0] && rest[0].isVerbRest)
|
||||||
? kids.map(k => ({ ...k, isKidBetweenHeadAndRest: true }))
|
? kids.map(k => k.adjust({ desc: ["isKidBetweenHeadAndRest"] }))
|
||||||
: kids,
|
: kids,
|
||||||
...rest,
|
...rest,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeSegment(
|
|
||||||
ps: T.PsString | T.PsString[],
|
|
||||||
options?: (keyof SegmentDescriptions)[],
|
|
||||||
): Segment {
|
|
||||||
return {
|
|
||||||
ps: Array.isArray(ps) ? ps : [ps],
|
|
||||||
...options && options.reduce((all, curr) => ({
|
|
||||||
...all,
|
|
||||||
[curr]: true,
|
|
||||||
}), {}),
|
|
||||||
adjust: function(o: { ps?: T.PsString | T.PsString[], desc?: SDT[] }): Segment {
|
|
||||||
return {
|
|
||||||
...this,
|
|
||||||
...o.ps ? { ps: Array.isArray(o.ps) ? o.ps : [o.ps] } : {},
|
|
||||||
...o.desc && o.desc.reduce((all, curr) => ({
|
|
||||||
...all,
|
|
||||||
[curr]: true,
|
|
||||||
}), {}),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function compileVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], negative: boolean): Segment[][] {
|
function compileVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], negative: boolean): Segment[][] {
|
||||||
const rest = makeSegment(restRaw.map(removeBa), ["isVerbRest"]);
|
const rest = makeSegment(restRaw.map(removeBa), ["isVerbRest"]);
|
||||||
const headSegment: Segment | undefined = !head
|
const headSegment: Segment | undefined = !head
|
||||||
|
@ -182,35 +160,81 @@ function compileVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[
|
||||||
);
|
);
|
||||||
if (!negative) {
|
if (!negative) {
|
||||||
return [
|
return [
|
||||||
[
|
headSegment ? [headSegment, rest] : [rest],
|
||||||
...headSegment ? [headSegment] : [],
|
|
||||||
rest,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
const nu: T.PsString = { p: "نه", f: "nú" };
|
const nu: T.PsString = { p: "نه", f: "nú" };
|
||||||
if (!headSegment) {
|
if (!headSegment) {
|
||||||
return [[
|
return [[
|
||||||
makeSegment(nu, ["isNu"]),
|
makeSegment(nu, ["isNu"]),
|
||||||
rest.adjust({ ps: rest.ps.map(p => removeAccents(p)) }),
|
rest.adjust({ ps: removeAccents }),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
...headSegment ? [headSegment.adjust({ ps: headSegment.ps.map(h =>removeAccents(h)) })] : [],
|
...headSegment ? [headSegment.adjust({ ps: removeAccents })] : [],
|
||||||
rest.adjust({
|
rest.adjust({
|
||||||
ps: rest.ps.map(r => concatPsString(nu, " ", removeAccents(r))),
|
ps: r => concatPsString(nu, " ", removeAccents(r)),
|
||||||
desc: ["isNu"],
|
desc: ["isNu"],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
...!headSegment.isOoOrWaaHead ? [[
|
...!headSegment.isOoOrWaaHead ? [[
|
||||||
makeSegment(nu, ["isNu"]),
|
makeSegment(nu, ["isNu"]),
|
||||||
headSegment.adjust({ ps: headSegment.ps.map(h =>removeAccents(h)) }),
|
headSegment.adjust({ ps: removeAccents }),
|
||||||
rest.adjust({ ps: rest.ps.map(p => removeAccents(p)) }),
|
rest.adjust({ ps: removeAccents }),
|
||||||
]] : [],
|
]] : [],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function compileEnglish(VP: VPRendered): string[] | undefined {
|
||||||
|
function insertEWords(e: string, { subject, object }: { subject: string, object?: string }): string {
|
||||||
|
return e.replace("$SUBJ", subject).replace("$OBJ", object || "");
|
||||||
|
}
|
||||||
|
const engSubj = VP.subject.e || undefined;
|
||||||
|
const engObj = (typeof VP.object === "object" && VP.object.e) ? VP.object.e : undefined;
|
||||||
|
// require all English parts for making the English phrase
|
||||||
|
return (VP.englishBase && engSubj && (engObj || typeof VP.object !== "object"))
|
||||||
|
? VP.englishBase.map(e => insertEWords(e, {
|
||||||
|
subject: engSubj,
|
||||||
|
object: engObj,
|
||||||
|
}))
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
type SDT = keyof SegmentDescriptions;
|
||||||
|
type Segment = { ps: T.PsString[] } & SegmentDescriptions & {
|
||||||
|
adjust: (o: { ps?: T.PsString | T.PsString[] | ((ps: T.PsString) => T.PsString), desc?: SDT[] }) => Segment,
|
||||||
|
};
|
||||||
|
|
||||||
|
function makeSegment(
|
||||||
|
ps: T.PsString | T.PsString[],
|
||||||
|
options?: (keyof SegmentDescriptions)[],
|
||||||
|
): Segment {
|
||||||
|
return {
|
||||||
|
ps: Array.isArray(ps) ? ps : [ps],
|
||||||
|
...options && options.reduce((all, curr) => ({
|
||||||
|
...all,
|
||||||
|
[curr]: true,
|
||||||
|
}), {}),
|
||||||
|
adjust: function(o: { ps?: T.PsString | T.PsString[] | ((ps: T.PsString) => T.PsString), desc?: SDT[] }): Segment {
|
||||||
|
return {
|
||||||
|
...this,
|
||||||
|
...o.ps ? {
|
||||||
|
ps: Array.isArray(o.ps)
|
||||||
|
? o.ps
|
||||||
|
: "p" in o.ps
|
||||||
|
? [o.ps]
|
||||||
|
: this.ps.map(o.ps)
|
||||||
|
} : {},
|
||||||
|
...o.desc && o.desc.reduce((all, curr) => ({
|
||||||
|
...all,
|
||||||
|
[curr]: true,
|
||||||
|
}), {}),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function combineSegments(loe: (Segment | " " | "" | T.PsString)[]): T.PsString[] {
|
function combineSegments(loe: (Segment | " " | "" | T.PsString)[]): T.PsString[] {
|
||||||
const first = loe[0];
|
const first = loe[0];
|
||||||
const rest = loe.slice(1);
|
const rest = loe.slice(1);
|
||||||
|
@ -226,19 +250,4 @@ function combineSegments(loe: (Segment | " " | "" | T.PsString)[]): T.PsString[]
|
||||||
: [concatPsString(first, r)]
|
: [concatPsString(first, r)]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
function compileEnglish(VP: VPRendered): string[] | undefined {
|
|
||||||
function insertEWords(e: string, { subject, object }: { subject: string, object?: string }): string {
|
|
||||||
return e.replace("$SUBJ", subject).replace("$OBJ", object || "");
|
|
||||||
}
|
|
||||||
const engSubj = VP.subject.e || undefined;
|
|
||||||
const engObj = (typeof VP.object === "object" && VP.object.e) ? VP.object.e : undefined;
|
|
||||||
// require all English parts for making the English phrase
|
|
||||||
return (VP.englishBase && engSubj && (engObj || typeof VP.object !== "object"))
|
|
||||||
? VP.englishBase.map(e => insertEWords(e, {
|
|
||||||
subject: engSubj,
|
|
||||||
object: engObj,
|
|
||||||
}))
|
|
||||||
: undefined;
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue