bit of refactor

This commit is contained in:
adueck 2023-09-01 19:20:49 +04:00
parent 56770b5041
commit 7ac14371f4
2 changed files with 219 additions and 197 deletions

View File

@ -1005,129 +1005,129 @@ const tests: {
})) }))
), ),
}, },
{ // {
input: "ودې وینم", // input: "ودې وینم",
output: getPeople(2, "sing").flatMap((objectPerson) => // output: getPeople(2, "sing").flatMap((objectPerson) =>
getPeople(1, "sing").map<T.VPSelectionComplete>((subjectPerson) => ({ // getPeople(1, "sing").map<T.VPSelectionComplete>((subjectPerson) => ({
blocks: [ // blocks: [
{ // {
key: 1, // key: 1,
block: makeSubjectSelectionComplete({ // block: makeSubjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(subjectPerson), // selection: makePronounSelection(subjectPerson),
}), // }),
}, // },
{ // {
key: 2, // key: 2,
block: makeObjectSelectionComplete({ // block: makeObjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(objectPerson), // selection: makePronounSelection(objectPerson),
}), // }),
}, // },
], // ],
verb: { // verb: {
type: "verb", // type: "verb",
verb: leedul, // verb: leedul,
transitivity: "transitive", // transitivity: "transitive",
canChangeTransitivity: false, // canChangeTransitivity: false,
canChangeStatDyn: false, // canChangeStatDyn: false,
negative: false, // negative: false,
tense: "subjunctiveVerb", // tense: "subjunctiveVerb",
canChangeVoice: true, // canChangeVoice: true,
isCompound: false, // isCompound: false,
voice: "active", // voice: "active",
}, // },
externalComplement: undefined, // externalComplement: undefined,
form: { // form: {
removeKing: true, // removeKing: true,
shrinkServant: true, // shrinkServant: true,
}, // },
})) // }))
), // ),
}, // },
{ // {
input: "وینم به دې", // input: "وینم به دې",
output: getPeople(2, "sing").flatMap((objectPerson) => // output: getPeople(2, "sing").flatMap((objectPerson) =>
getPeople(1, "sing").map<T.VPSelectionComplete>((subjectPerson) => ({ // getPeople(1, "sing").map<T.VPSelectionComplete>((subjectPerson) => ({
blocks: [ // blocks: [
{ // {
key: 1, // key: 1,
block: makeSubjectSelectionComplete({ // block: makeSubjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(subjectPerson), // selection: makePronounSelection(subjectPerson),
}), // }),
}, // },
{ // {
key: 2, // key: 2,
block: makeObjectSelectionComplete({ // block: makeObjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(objectPerson), // selection: makePronounSelection(objectPerson),
}), // }),
}, // },
], // ],
verb: { // verb: {
type: "verb", // type: "verb",
verb: leedul, // verb: leedul,
transitivity: "transitive", // transitivity: "transitive",
canChangeTransitivity: false, // canChangeTransitivity: false,
canChangeStatDyn: false, // canChangeStatDyn: false,
negative: false, // negative: false,
tense: "imperfectiveFuture", // tense: "imperfectiveFuture",
canChangeVoice: true, // canChangeVoice: true,
isCompound: false, // isCompound: false,
voice: "active", // voice: "active",
}, // },
externalComplement: undefined, // externalComplement: undefined,
form: { // form: {
removeKing: true, // removeKing: true,
shrinkServant: true, // shrinkServant: true,
}, // },
})) // }))
), // ),
}, // },
{ // {
input: "یو به مې ړلې", // input: "یو به مې ړلې",
output: [...getPeople(2, "sing"), T.Person.ThirdPlurFemale].flatMap( // output: [...getPeople(2, "sing"), T.Person.ThirdPlurFemale].flatMap(
(objectPerson) => // (objectPerson) =>
getPeople(1, "sing").map<T.VPSelectionComplete>( // getPeople(1, "sing").map<T.VPSelectionComplete>(
(subjectPerson) => ({ // (subjectPerson) => ({
blocks: [ // blocks: [
{ // {
key: 1, // key: 1,
block: makeSubjectSelectionComplete({ // block: makeSubjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(subjectPerson), // selection: makePronounSelection(subjectPerson),
}), // }),
}, // },
{ // {
key: 2, // key: 2,
block: makeObjectSelectionComplete({ // block: makeObjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(objectPerson), // selection: makePronounSelection(objectPerson),
}), // }),
}, // },
], // ],
verb: { // verb: {
type: "verb", // type: "verb",
verb: wurul, // verb: wurul,
transitivity: "transitive", // transitivity: "transitive",
canChangeTransitivity: false, // canChangeTransitivity: false,
canChangeStatDyn: false, // canChangeStatDyn: false,
negative: false, // negative: false,
tense: "habitualPerfectivePast", // tense: "habitualPerfectivePast",
canChangeVoice: true, // canChangeVoice: true,
isCompound: false, // isCompound: false,
voice: "active", // voice: "active",
}, // },
externalComplement: undefined, // externalComplement: undefined,
form: { // form: {
removeKing: true, // removeKing: true,
shrinkServant: true, // shrinkServant: true,
}, // },
}) // })
) // )
), // ),
}, // },
], ],
}, },
{ {

View File

@ -24,8 +24,6 @@ import { LookupFunction } from "./lookup";
// TODO: word query for kawul/kedul/stat/dyn // TODO: word query for kawul/kedul/stat/dyn
// map over transitivities, to give transitive / gramm. transitive optionns
// TODO: learn how to yank / use plugin for JSON neovim // TODO: learn how to yank / use plugin for JSON neovim
// learn to use jq to edit selected json in vim ?? COOOL // learn to use jq to edit selected json in vim ?? COOOL
@ -42,54 +40,79 @@ export function parseVP(
} }
const blocks = parseBlocks(tokens, lookup, [], []); const blocks = parseBlocks(tokens, lookup, [], []);
return bindParseResult(blocks, (tokens, { blocks, kids }) => { return bindParseResult(blocks, (tokens, { blocks, kids }) => {
const phIndex = blocks.findIndex((x) => x.type === "PH");
const vbeIndex = blocks.findIndex((x) => x.type === "VB");
const ba = !!kids.find((k) => k === "ba"); const ba = !!kids.find((k) => k === "ba");
const negIndex = blocks.findIndex(
(x) => x.type === "negative" && !x.imperative
);
const ph = phIndex !== -1 ? (blocks[phIndex] as T.ParsedPH) : undefined;
const verb =
vbeIndex !== -1 ? (blocks[vbeIndex] as T.ParsedVBE) : undefined;
const negative = negIndex !== -1;
if (!verb || verb.type !== "VB" || verb.info.type !== "verb") {
return [];
}
// TODO: check for either VBE or Equative and VBP
if (
!negativeInPlace({
neg: negIndex,
v: vbeIndex,
phIndex: phIndex,
ph,
kids: !!kids.length,
})
) {
return [];
}
if (verb.info.aspect === "perfective") {
if (!ph) {
return [];
}
} else {
if (ph) {
return [];
}
}
const tense = getTenseFromRootsStems(ba, verb.info.base, verb.info.aspect);
const transitivities = getTransitivities(verb.info.verb);
const nps = blocks.filter((x): x is T.ParsedNP => x.type === "NP");
const miniPronouns = getMiniPronouns(kids); const miniPronouns = getMiniPronouns(kids);
return finishPossibleVPSs({ const nps = blocks.filter((x): x is T.ParsedNP => x.type === "NP");
const tenses = getTenses(blocks, ba, !!kids.length);
// TODO get errors from the get tenses (perfect verbs not agreeing)
return tenses.flatMap(({ tense, person, transitivities, negative, verb }) =>
finishPossibleVPSs({
tense,
transitivities,
nps,
miniPronouns,
tokens,
negative,
verb,
person,
})
);
});
}
function getTenses(
blocks: T.ParsedBlock[],
ba: boolean,
hasKids: boolean
): {
tense: T.VerbTense;
person: T.Person;
transitivities: T.Transitivity[];
negative: boolean;
verb: T.VerbEntry;
}[] {
const negIndex = blocks.findIndex(
(x) => x.type === "negative" && !x.imperative
);
const negative = negIndex !== -1;
const phIndex = blocks.findIndex((x) => x.type === "PH");
const vbeIndex = blocks.findIndex((x) => x.type === "VB");
const ph = phIndex !== -1 ? (blocks[phIndex] as T.ParsedPH) : undefined;
const verb = vbeIndex !== -1 ? (blocks[vbeIndex] as T.ParsedVBE) : undefined;
if (!verb || verb.type !== "VB" || verb.info.type !== "verb") {
return [];
}
if (
!negativeInPlace({
neg: negIndex,
v: vbeIndex,
phIndex: phIndex,
ph,
kids: hasKids,
})
) {
return [];
}
if (verb.info.aspect === "perfective") {
if (!ph) {
return [];
}
} else {
if (ph) {
return [];
}
}
const tense = getTenseFromRootsStems(ba, verb.info.base, verb.info.aspect);
const transitivities = getTransitivities(verb.info.verb);
return [
{
tense, tense,
transitivities, transitivities,
nps,
miniPronouns,
tokens,
negative, negative,
verb, person: verb.person,
}); verb: verb.info.verb,
}); },
];
} }
function finishPossibleVPSs({ function finishPossibleVPSs({
@ -100,6 +123,7 @@ function finishPossibleVPSs({
negative, negative,
verb, verb,
tokens, tokens,
person,
}: { }: {
tense: T.VerbTense; tense: T.VerbTense;
transitivities: T.Transitivity[]; transitivities: T.Transitivity[];
@ -107,17 +131,15 @@ function finishPossibleVPSs({
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
negative: boolean; negative: boolean;
verb: T.ParsedVBE; verb: T.VerbEntry;
person: T.Person;
}): T.ParseResult<T.VPSelectionComplete>[] { }): T.ParseResult<T.VPSelectionComplete>[] {
const isPast = isPastTense(tense); const isPast = isPastTense(tense);
return transitivities.flatMap<T.ParseResult<T.VPSelectionComplete>>( return transitivities.flatMap<T.ParseResult<T.VPSelectionComplete>>(
(transitivity): T.ParseResult<T.VPSelectionComplete>[] => { (transitivity): T.ParseResult<T.VPSelectionComplete>[] => {
if (verb.info.type === "equative") {
return [];
}
const v: T.VerbSelectionComplete = { const v: T.VerbSelectionComplete = {
type: "verb", type: "verb",
verb: verb.info.verb, verb,
transitivity, transitivity,
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
@ -133,7 +155,7 @@ function finishPossibleVPSs({
nps, nps,
tokens, tokens,
v, v,
verbPerson: verb.person, person,
}); });
} else if (transitivity === "transitive") { } else if (transitivity === "transitive") {
return finishTransitive({ return finishTransitive({
@ -141,7 +163,7 @@ function finishPossibleVPSs({
nps, nps,
tokens, tokens,
v, v,
verbPerson: verb.person, person,
isPast, isPast,
}); });
} else { } else {
@ -150,7 +172,7 @@ function finishPossibleVPSs({
nps, nps,
tokens, tokens,
v, v,
verbPerson: verb.person, person,
isPast, isPast,
}); });
} }
@ -163,13 +185,13 @@ function finishIntransitive({
nps, nps,
tokens, tokens,
v, v,
verbPerson, person,
}: { }: {
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
nps: T.ParsedNP[]; nps: T.ParsedNP[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
v: T.VerbSelectionComplete; v: T.VerbSelectionComplete;
verbPerson: T.Person; person: T.Person;
}): T.ParseResult<T.VPSelectionComplete>[] { }): T.ParseResult<T.VPSelectionComplete>[] {
const errors: T.ParseError[] = []; const errors: T.ParseError[] = [];
if (miniPronouns.length) { if (miniPronouns.length) {
@ -186,7 +208,7 @@ function finishIntransitive({
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(verbPerson), selection: makePronounSelection(person),
}), }),
}, },
{ {
@ -213,7 +235,7 @@ function finishIntransitive({
}, },
]; ];
} }
if (getPersonFromNP(nps[0].selection) !== verbPerson) { if (getPersonFromNP(nps[0].selection) !== person) {
errors.push({ message: "subject must agree with intransitive verb" }); errors.push({ message: "subject must agree with intransitive verb" });
} }
if (nps[0].inflected) { if (nps[0].inflected) {
@ -256,14 +278,14 @@ function finishTransitive({
nps, nps,
tokens, tokens,
v, v,
verbPerson, person,
isPast, isPast,
}: { }: {
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
nps: T.ParsedNP[]; nps: T.ParsedNP[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
v: T.VerbSelectionComplete; v: T.VerbSelectionComplete;
verbPerson: T.Person; person: T.Person;
isPast: boolean; isPast: boolean;
}): T.ParseResult<T.VPSelectionComplete>[] { }): T.ParseResult<T.VPSelectionComplete>[] {
// transitive // transitive
@ -285,21 +307,21 @@ function finishTransitive({
} }
const blockOpts: T.VPSBlockComplete[][] = getPeopleFromMiniPronouns( const blockOpts: T.VPSBlockComplete[][] = getPeopleFromMiniPronouns(
miniPronouns miniPronouns
).map((person) => ).map((servantPerson) =>
!isPast !isPast
? [ ? [
{ {
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(verbPerson), selection: makePronounSelection(person),
}), }),
}, },
{ {
key: 2, key: 2,
block: makeObjectSelectionComplete({ block: makeObjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(person), selection: makePronounSelection(servantPerson),
}), }),
}, },
] ]
@ -308,14 +330,14 @@ function finishTransitive({
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(person), selection: makePronounSelection(servantPerson),
}), }),
}, },
{ {
key: 2, key: 2,
block: makeObjectSelectionComplete({ block: makeObjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(verbPerson), selection: makePronounSelection(person),
}), }),
}, },
] ]
@ -363,7 +385,7 @@ function finishTransitive({
const king: T.NPSelection = form.removeKing const king: T.NPSelection = form.removeKing
? { ? {
type: "NP", type: "NP",
selection: makePronounSelection(verbPerson), selection: makePronounSelection(person),
} }
: np.selection; : np.selection;
const servants: T.NPSelection[] = form.shrinkServant const servants: T.NPSelection[] = form.shrinkServant
@ -403,7 +425,7 @@ function finishTransitive({
: "subject of a non-past tense transitive verb should not be inflected", : "subject of a non-past tense transitive verb should not be inflected",
}); });
} }
if (getPersonFromNP(king) !== verbPerson) { if (getPersonFromNP(king) !== person) {
errors.push({ errors.push({
message: `${ message: `${
isPast ? "past tense" : "non-past tense" isPast ? "past tense" : "non-past tense"
@ -479,7 +501,7 @@ function finishTransitive({
"object of past tense transitive verb must not be inflected", "object of past tense transitive verb must not be inflected",
}); });
} }
if (getPersonFromNP(o.selection) !== verbPerson) { if (getPersonFromNP(o.selection) !== person) {
errors.push({ errors.push({
message: "past tense transitive verb must agree with the object", message: "past tense transitive verb must agree with the object",
}); });
@ -550,7 +572,7 @@ function finishTransitive({
"subject of transitive non-past tense verb must not be inflected", "subject of transitive non-past tense verb must not be inflected",
}); });
} }
if (getPersonFromNP(s.selection) !== verbPerson) { if (getPersonFromNP(s.selection) !== person) {
errors.push({ errors.push({
message: message:
"non-past tense transitive verb must agree with the subject", "non-past tense transitive verb must agree with the subject",
@ -592,14 +614,14 @@ function finishGrammaticallyTransitive({
nps, nps,
tokens, tokens,
v, v,
verbPerson, person,
isPast, isPast,
}: { }: {
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
nps: T.ParsedNP[]; nps: T.ParsedNP[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
v: T.VerbSelectionComplete; v: T.VerbSelectionComplete;
verbPerson: T.Person; person: T.Person;
isPast: boolean; isPast: boolean;
}): T.ParseResult<T.VPSelectionComplete>[] { }): T.ParseResult<T.VPSelectionComplete>[] {
const errors: T.ParseError[] = []; const errors: T.ParseError[] = [];
@ -610,7 +632,7 @@ function finishGrammaticallyTransitive({
message: "unknown mini-pronoun", message: "unknown mini-pronoun",
}); });
} }
if (verbPerson !== T.Person.ThirdPlurMale) { if (person !== T.Person.ThirdPlurMale) {
errors.push({ errors.push({
message: message:
"grammatically transitive verb must be 3rd pers. masc. plur.", "grammatically transitive verb must be 3rd pers. masc. plur.",
@ -661,7 +683,7 @@ function finishGrammaticallyTransitive({
message: "subject required for grammatically transitive verb", message: "subject required for grammatically transitive verb",
}); });
} }
if (verbPerson !== T.Person.ThirdPlurMale) { if (person !== T.Person.ThirdPlurMale) {
errors.push({ errors.push({
message: message:
"grammatically transitive verb must be 3rd pers. masc. plur.", "grammatically transitive verb must be 3rd pers. masc. plur.",
@ -708,7 +730,7 @@ function finishGrammaticallyTransitive({
} }
if (nps.length === 1) { if (nps.length === 1) {
const subj = nps[0]; const subj = nps[0];
if (verbPerson !== getPersonFromNP(subj.selection)) { if (person !== getPersonFromNP(subj.selection)) {
errors.push({ errors.push({
message: "non-past verb must agree with subject", message: "non-past verb must agree with subject",
}); });
@ -758,7 +780,7 @@ function finishGrammaticallyTransitive({
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(verbPerson), selection: makePronounSelection(person),
}), }),
}, },
{ {