working for kernel vps w/out 3rd pers masc sing

This commit is contained in:
adueck 2023-08-12 15:19:49 +04:00
parent 4893ef0d70
commit 7f031c4a71
6 changed files with 697 additions and 92 deletions

View File

@ -251,6 +251,8 @@ function getPassivePp(
};
}
// TODO: Abstract out the get T.Vhead part
function getRoot(
verb: T.VerbEntryNoFVars,
genderNum: T.GenderNumber,

View File

@ -33,29 +33,52 @@ export function lookup(s: Partial<T.DictionaryEntry>): T.DictionaryEntry[] {
export function verbLookup(input: string): T.VerbEntry[] {
const s = input.slice(0, -1);
const sWoutOo = s.startsWith("و") ? s.slice(1) : undefined;
if (s.endsWith("ېږ")) {
return verbs.filter(
({ entry }) =>
entry.p.slice(0, -1) === s ||
entry.p === s.slice(0, -1) + "دل" ||
entry.p === s ||
entry.psp === s ||
entry.prp === s ||
entry.ssp === s
sWoutOo
? ({ entry }) =>
[s, sWoutOo].includes(entry.p.slice(0, -1)) ||
[s.slice(0, -1) + "دل", sWoutOo.slice(0, -1) + "دل"].includes(
entry.p
) ||
[s, sWoutOo].includes(entry.p) ||
(entry.psp && [s, sWoutOo].includes(entry.psp)) ||
entry.prp === s ||
entry.ssp === s
: ({ entry }) =>
entry.p.slice(0, -1) === s ||
entry.p === s.slice(0, -1) + "دل" ||
entry.p === s ||
entry.psp === s ||
entry.prp === s ||
entry.ssp === s
);
}
return verbs.filter(
({ entry }) =>
entry.p.slice(0, -1) === s ||
// for short intransitive forms
entry.p.slice(0, -3) === s ||
entry.p === s ||
entry.psp === s ||
entry.prp === s ||
entry.ssp === s ||
(entry.separationAtP &&
(entry.p.slice(entry.separationAtP) === s ||
entry.psp?.slice(entry.separationAtP) === s))
sWoutOo
? ({ entry }) =>
[s, sWoutOo].includes(entry.p.slice(0, -1)) ||
// for short intransitive forms
[s, sWoutOo].includes(entry.p.slice(0, -3)) ||
[s, sWoutOo].includes(entry.p) ||
(entry.psp && [s, sWoutOo].includes(entry.psp)) ||
entry.prp === s ||
entry.ssp === s ||
(entry.separationAtP &&
(entry.p.slice(entry.separationAtP) === s ||
entry.psp?.slice(entry.separationAtP) === s))
: ({ entry }) =>
entry.p.slice(0, -1) === s ||
// for short intransitive forms
entry.p.slice(0, -3) === s ||
entry.p === s ||
entry.psp === s ||
entry.prp === s ||
entry.ssp === s ||
(entry.separationAtP &&
(entry.p.slice(entry.separationAtP) === s ||
entry.psp?.slice(entry.separationAtP) === s))
);
}

View File

@ -20,7 +20,7 @@ export function parsePhrase(
} {
const res = [
...parseNP(s, lookup).filter(({ tokens }) => !tokens.length),
...parseVerb(s, verbLookup),
// ...parseVerb(s, verbLookup),
...parseVP(s, lookup, verbLookup),
];

View File

@ -7,6 +7,7 @@ import { tokenizer } from "./tokenizer";
const wahul = wordQuery("وهل", "verb");
const leekul = wordQuery("لیکل", "verb");
const manul = wordQuery("منل", "verb");
const gaalul = wordQuery("ګالل", "verb");
const rasedul = wordQuery("رسېدل", "verb");
const leedul = wordQuery("لیدل", "verb");
const khorul = wordQuery("خوړل", "verb");
@ -20,6 +21,7 @@ const tests: {
cases: {
input: string;
output: {
ph: string | undefined;
root?: {
persons: T.Person[];
aspects: T.Aspect[];
@ -39,6 +41,7 @@ const tests: {
input: "وهلم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -51,6 +54,7 @@ const tests: {
input: "وهم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -67,6 +71,7 @@ const tests: {
input: "وهې",
output: [
{
ph: undefined,
root: {
persons: [
T.Person.SecondSingMale,
@ -87,6 +92,7 @@ const tests: {
input: "لیکم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -103,6 +109,7 @@ const tests: {
input: "لیکلو",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["imperfective", "perfective"],
@ -115,6 +122,7 @@ const tests: {
input: "لیکل",
output: [
{
ph: undefined,
root: {
persons: [T.Person.ThirdPlurMale],
aspects: ["imperfective", "perfective"],
@ -131,6 +139,7 @@ const tests: {
input: "منله",
output: [
{
ph: undefined,
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"],
@ -143,6 +152,7 @@ const tests: {
input: "مني",
output: [
{
ph: undefined,
stem: {
persons: [
T.Person.ThirdSingMale,
@ -160,6 +170,7 @@ const tests: {
input: "منئ",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
aspects: ["imperfective", "perfective"],
@ -172,6 +183,71 @@ const tests: {
},
],
},
// with perfective head
{
input: "ومنلم",
output: [
{
ph: "و",
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"],
},
verb: manul,
},
],
},
{
input: "منلم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective", "imperfective"],
},
verb: manul,
},
],
},
{
input: "وګاللې",
output: [
{
ph: "و",
root: {
persons: [
T.Person.SecondSingFemale,
T.Person.SecondSingMale,
T.Person.ThirdPlurFemale,
],
aspects: ["perfective"],
},
verb: gaalul,
},
],
},
{
input: "وګالې",
output: [
{
ph: "و",
root: {
persons: [
T.Person.SecondSingFemale,
T.Person.SecondSingMale,
T.Person.ThirdPlurFemale,
],
aspects: ["perfective"],
},
stem: {
persons: [T.Person.SecondSingFemale, T.Person.SecondSingMale],
aspects: ["perfective"],
},
verb: gaalul,
},
],
},
],
},
{
@ -181,6 +257,7 @@ const tests: {
input: "رسېدلم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -193,6 +270,7 @@ const tests: {
input: "رسېدم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -201,10 +279,24 @@ const tests: {
},
],
},
{
input: "ورسېدم",
output: [
{
ph: "و",
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"],
},
verb: rasedul,
},
],
},
{
input: "رسېږې",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["imperfective", "perfective"],
@ -213,11 +305,25 @@ const tests: {
},
],
},
{
input: "ورسېږې",
output: [
{
ph: "و",
stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["perfective"],
},
verb: rasedul,
},
],
},
// short version of intransitive as well
{
input: "رسئ",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
aspects: ["imperfective", "perfective"],
@ -226,6 +332,19 @@ const tests: {
},
],
},
{
input: "ورسئ",
output: [
{
ph: "و",
stem: {
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
aspects: ["perfective"],
},
verb: rasedul,
},
],
},
],
},
{
@ -235,6 +354,7 @@ const tests: {
input: "وینم",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -247,6 +367,7 @@ const tests: {
input: "وینم",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -259,6 +380,7 @@ const tests: {
input: "لیده",
output: [
{
ph: undefined,
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"],
@ -267,10 +389,37 @@ const tests: {
},
],
},
{
input: "ولیده",
output: [
{
ph: "و",
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"],
},
verb: leedul,
},
],
},
{
input: "ولیدله",
output: [
{
ph: "و",
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"],
},
verb: leedul,
},
],
},
{
input: "خورې",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["imperfective", "perfective"],
@ -279,6 +428,19 @@ const tests: {
},
],
},
{
input: "وخورې",
output: [
{
ph: "و",
stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["perfective"],
},
verb: khorul,
},
],
},
{
input: "خوړي",
output: [],
@ -287,6 +449,7 @@ const tests: {
input: "خوړم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"],
@ -295,6 +458,19 @@ const tests: {
},
],
},
{
input: "وخوړم",
output: [
{
ph: "و",
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"],
},
verb: khorul,
},
],
},
],
},
{
@ -304,6 +480,7 @@ const tests: {
input: "کېني",
output: [
{
ph: "کې",
stem: {
persons: [
T.Person.ThirdSingMale,
@ -321,6 +498,7 @@ const tests: {
input: "نم",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"],
@ -333,6 +511,7 @@ const tests: {
input: "پرېږدو",
output: [
{
ph: "پرې",
stem: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["imperfective", "perfective"],
@ -341,10 +520,32 @@ const tests: {
},
],
},
{
input: "ږدو",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["perfective"],
},
verb: prexodul,
},
{
ph: undefined,
stem: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["imperfective", "perfective"],
},
verb: kexodul,
},
],
},
{
input: "پرېښوده",
output: [
{
ph: "پرې",
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"],
@ -357,6 +558,7 @@ const tests: {
input: "ښودله",
output: [
{
ph: undefined,
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"],
@ -364,6 +566,7 @@ const tests: {
verb: xodul,
},
{
ph: undefined,
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"],
@ -371,6 +574,7 @@ const tests: {
verb: prexodul,
},
{
ph: undefined,
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"],
@ -388,21 +592,39 @@ tests.forEach(({ label, cases }) => {
cases.forEach(({ input, output }) => {
const tokens = tokenizer(input);
const vbs = parseVerb(tokens, verbLookup).map((r) => r.body);
const madeVbsS = output.reduce<Omit<T.VBE, "ps">[]>((acc, o) => {
const madeVbsS = output.reduce<
[{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">][]
>((acc, o) => {
return [
...acc,
...(["root", "stem"] as const).flatMap((base) =>
(o[base]?.aspects || []).flatMap((aspect) =>
(o[base]?.persons || []).flatMap((person) => ({
type: "VB" as const,
person,
info: {
type: "verb" as const,
aspect,
base,
verb: o.verb,
},
}))
(o[base]?.persons || []).flatMap<
[{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">]
>((person) => {
const r: [
{ type: "PH"; s: string } | undefined,
Omit<T.VBE, "ps">
] = [
aspect === "perfective" && o.ph
? {
type: "PH",
s: o.ph,
}
: undefined,
{
type: "VB" as const,
person,
info: {
type: "verb" as const,
aspect,
base,
verb: o.verb,
},
},
];
return [r];
})
)
),
];
@ -411,3 +633,194 @@ tests.forEach(({ label, cases }) => {
});
});
});
const b = [
[
undefined,
{
info: {
aspect: "imperfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 6,
type: "VB",
},
],
[
undefined,
{
info: {
aspect: "imperfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 7,
type: "VB",
},
],
[
undefined,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to leave, abandon, forsake, let go, allow",
ec: "abandon",
f: "prexodúl",
g: "prexodul",
i: 2516,
noOo: true,
p: "پرېښودل",
psf: "preGd",
psp: "پرېږد",
r: 4,
separationAtF: 3,
separationAtP: 3,
ts: 1527815190,
},
},
},
person: 6,
type: "VB",
},
],
[
undefined,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to leave, abandon, forsake, let go, allow",
ec: "abandon",
f: "prexodúl",
g: "prexodul",
i: 2516,
noOo: true,
p: "پرېښودل",
psf: "preGd",
psp: "پرېږد",
r: 4,
separationAtF: 3,
separationAtP: 3,
ts: 1527815190,
},
},
},
person: 7,
type: "VB",
},
],
[
{ s: "کې", type: "PH" },
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 6,
type: "VB",
},
],
[
{ s: "کې", type: "PH" },
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 7,
type: "VB",
},
],
];

View File

@ -3,7 +3,7 @@ import * as T from "../../../types";
export function parseVerb(
tokens: Readonly<T.Token[]>,
verbLookup: (s: string) => T.VerbEntry[]
): T.ParseResult<Omit<T.VBE, "ps">>[] {
): T.ParseResult<[{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">]>[] {
if (tokens.length === 0) {
return [];
}
@ -25,9 +25,13 @@ function matchVerbs(
root: T.Person[];
stem: T.Person[];
}
): Omit<T.VBE, "ps">[] {
const w: Omit<T.VBE, "ps">[] = [];
): [{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">][] {
const w: ReturnType<typeof matchVerbs> = [];
const lEnding = s.endsWith("ل");
const base = s.endsWith("ل") ? s : s.slice(0, -1);
const matchShortOrLong = (b: string, x: string) => {
return b === x || (!lEnding && b === x.slice(0, -1));
};
if (people.stem.length) {
const stemMatches = {
imperfective: entries.filter(({ entry: e }) => {
@ -44,39 +48,135 @@ function matchVerbs(
return e.p.slice(0, -1) === base;
}
}),
perfective: entries.filter(({ entry: e }) => {
perfective: entries.reduce<
{ ph: string | undefined; entry: T.VerbEntry }[]
>((acc, entry) => {
const e = entry.entry;
if (e.c.includes("comp")) {
return false;
return acc;
}
if (e.ssp) {
const bSep = e.separationAtP ? e.ssp.slice(e.separationAtP) : "";
return bSep === base || e.ssp === base;
}
if (e.psp) {
const bSep = e.separationAtP ? e.psp.slice(e.separationAtP) : "";
return bSep === base || e.psp === base;
}
if (e.c.includes("intrans.")) {
const bRest = e.separationAtP ? e.ssp.slice(e.separationAtP) : "";
if (bRest === base) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
if (e.ssp === base) {
return [
...acc,
{
ph: e.separationAtF
? e.ssp.slice(0, e.separationAtP)
: undefined,
entry,
},
];
}
} else if (e.psp) {
const bRest = e.separationAtP ? e.psp.slice(e.separationAtP) : "";
if (bRest === base) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
if (e.psp === base && e.separationAtP) {
return [
...acc,
{
ph: e.psp.slice(0, e.separationAtP),
entry,
},
];
}
if ((base.startsWith("و") && base.slice(1)) === e.psp) {
return [
...acc,
{
ph: "و",
entry,
},
];
}
if (base === e.psp) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
} else if (e.c.includes("intrans.")) {
const miniRoot = e.p.slice(0, -3);
return miniRoot + "ېږ" === base || miniRoot === base;
const miniRootEg = miniRoot + "ېږ";
if ([miniRoot, miniRootEg].includes(base)) {
return [
...acc,
{
ph: undefined,
entry,
},
];
} else if (
base.startsWith("و") &&
[miniRoot, miniRootEg].includes(base.slice(1))
) {
return [
...acc,
{
ph: "و", // TODO: check for وا etc
entry,
},
];
}
} else {
return e.p.slice(0, -1) === base;
const eb = e.p.slice(0, -1);
if (eb === base) {
return [
...acc,
{
ph: undefined,
entry,
},
];
} else if (base.startsWith("و") && eb === base.slice(1)) {
return [
...acc,
{
ph: "و",
entry,
},
];
}
}
}),
return acc;
}, []),
};
Object.entries(stemMatches).forEach(([aspect, entries]) => {
entries.forEach((verb) => {
people.stem.forEach((person) => {
w.push({
type: "VB",
person,
info: {
type: "verb",
aspect: aspect as T.Aspect,
base: "stem",
verb: verb,
w.push([
"ph" in verb && verb.ph ? { type: "PH", s: verb.ph } : undefined,
{
type: "VB",
person,
info: {
type: "verb",
aspect: aspect as T.Aspect,
base: "stem",
verb: "ph" in verb ? verb.entry : verb,
},
},
});
]);
});
});
});
@ -84,43 +184,76 @@ function matchVerbs(
if (people.root.length) {
const rootMatches = {
imperfective: entries.filter(
({ entry: e }) =>
!e.c.includes("comp") &&
(base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1)))
({ entry: e }) => !e.c.includes("comp") && matchShortOrLong(base, e.p)
),
perfective: entries.filter(({ entry: e }) => {
perfective: entries.reduce<
{ ph: string | undefined; entry: T.VerbEntry }[]
>((acc, entry) => {
const e = entry.entry;
if (e.c.includes("comp")) {
return false;
return acc;
}
if (e.separationAtP) {
const bSep = e.p.slice(e.separationAtP);
return (
base === bSep ||
base === e.p ||
(!s.endsWith("ل") &&
(base === e.p.slice(0, -1) || base === bSep.slice(0, -1)))
);
} else {
// TODO: perfective roots are so rare could optimize this with a couple of checks?
return e.prp
? e.prp === base || e.prp.slice(0, -1) === base
: base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1));
const b = e.prp || e.p;
const bHead = b.slice(0, e.separationAtP);
const bRest = b.slice(e.separationAtP);
if (matchShortOrLong(base, b)) {
return [
...acc,
{
ph: bHead,
entry,
},
];
} else if (matchShortOrLong(base, bRest)) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
} else if (!e.prp) {
const baseNoOo = base.startsWith("و") && base.slice(1);
if (baseNoOo && matchShortOrLong(baseNoOo, e.p)) {
return [
...acc,
{
ph: "و",
entry,
},
];
} else if (matchShortOrLong(base, e.p)) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
}
}),
return acc;
}, []),
};
Object.entries(rootMatches).forEach(([aspect, entries]) => {
entries.forEach((verb) => {
people.root.forEach((person) => {
w.push({
type: "VB",
person,
info: {
type: "verb",
aspect: aspect as T.Aspect,
base: "root",
verb: verb,
w.push([
"ph" in verb && verb.ph ? { type: "PH", s: verb.ph } : undefined,
{
type: "VB",
person,
info: {
type: "verb",
aspect: aspect as T.Aspect,
base: "root",
verb: "ph" in verb ? verb.entry : verb,
},
},
});
]);
});
});
});

View File

@ -101,18 +101,18 @@ export function parseVP(
}));
}).filter(({ errors }) => !errors.length);
// TODO: be able to bind mulitple vals
return bindParseResult(vb, (tokens, { np1, np2, v }) => {
return bindParseResult(vb, (tokens, { np1, np2, v: [ph, v] }) => {
const w: T.ParseResult<T.VPSelectionComplete>[] = [];
const isPast = v.info.type === "verb" && v.info.base === "root";
if (v.info.type === "equative") {
throw new Error("not yet implemented");
}
const isPast = v.info.base === "root";
const intransitive =
v.info.type === "verb" && v.info.verb.entry.c.includes("intrans.");
if (!np2) {
const errors: T.ParseError[] = [];
if (intransitive) {
if (np2) return [];
const s = np1;
if (!intransitive) {
return [];
}
const errors: T.ParseError[] = [];
if (s.inflected) {
errors.push({
message: "subject of intransitive verb should not be inflected",
@ -143,7 +143,7 @@ export function parseVP(
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: isPast ? "imperfectivePast" : "presentVerb",
tense: getTenseFromRootsStems(false, v.info.base, v.info.aspect),
canChangeVoice: true,
isCompound: false,
voice: "active",
@ -162,8 +162,18 @@ export function parseVP(
errors,
});
} else {
// transitive verb
if (!(np1 && np2)) return [];
[[np1, np2, false] as const, [np2, np1, true] as const].forEach(
([s, o, reversed]) => {
if (v.info.type === "equative") {
throw new Error("not yet implemented");
}
if (!s || !o) return [];
// TODO: check if perfective head MATCHES verb
if (v.info.aspect === "perfective" && !ph) {
return [];
}
const subjPerson = getPersonFromNP(s.selection);
const errors: T.ParseError[] = [];
if (intransitive) {
@ -230,7 +240,7 @@ export function parseVP(
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: isPast ? "imperfectivePast" : "presentVerb",
tense: getTenseFromRootsStems(false, v.info.base, v.info.aspect),
canChangeVoice: true,
isCompound: false,
voice: "active",
@ -254,3 +264,27 @@ export function parseVP(
return w;
});
}
function getTenseFromRootsStems(
hasBa: boolean,
base: "root" | "stem",
aspect: T.Aspect
): T.VerbTense {
if (!hasBa) {
if (base === "root") {
return aspect === "perfective" ? "perfectivePast" : "imperfectivePast";
} else {
return aspect === "imperfective" ? "presentVerb" : "subjunctiveVerb";
}
} else {
if (base === "root") {
return aspect === "perfective"
? "habitualPerfectivePast"
: "habitualImperfectivePast";
} else {
return aspect === "imperfective"
? "imperfectiveFuture"
: "perfectiveFuture";
}
}
}