more
This commit is contained in:
parent
91d3a10abb
commit
ed4e494e54
|
@ -120,6 +120,7 @@ export function accentPsSyllable(ps: T.PsString): T.PsString {
|
|||
}
|
||||
|
||||
|
||||
|
||||
export function removeAccentsWLength(s: T.SingleOrLengthOpts<T.PsString[]>): T.SingleOrLengthOpts<T.PsString[]> {
|
||||
if ("long" in s) {
|
||||
return {
|
||||
|
|
|
@ -18,7 +18,7 @@ import { tenseHasBa } from "../phrase-building/vp-tools";
|
|||
import { isPastTense } from "../phrase-building/vp-tools";
|
||||
import { makePsString, removeFVarients } from "../accent-and-ps-utils";
|
||||
import { pashtoConsonants } from "../pashto-consonants";
|
||||
import { getRootStem } from "./roots-and-stems";
|
||||
import { getPastParticiple, getRootStem } from "./roots-and-stems";
|
||||
import { verbEndingConcat } from "./rs-helpers";
|
||||
|
||||
// For the chart display of the results: base the length thing on the VBE at the end, if there are other
|
||||
|
@ -49,27 +49,24 @@ export function renderVerb({ verb, tense, person, voice }: {
|
|||
hasBa: boolean,
|
||||
vbs: T.VerbRenderedOutput,
|
||||
} {
|
||||
// TODO: check for transitivity with passive voice ??
|
||||
|
||||
const hasBa = tenseHasBa(tense);
|
||||
if (isPerfectTense(tense)) {
|
||||
throw new Error("not implemented yet");
|
||||
return renderPerfectVerb({ verb, tense, voice, person });
|
||||
}
|
||||
|
||||
const isPast = isPastTense(tense);
|
||||
const aspect = getAspect(tense);
|
||||
const type = isAbilityTense(tense) ? "ability" : "basic";
|
||||
const hasBa = tenseHasBa(tense);
|
||||
const genderNumber = {
|
||||
gender: personGender(person),
|
||||
number: personNumber(person),
|
||||
};
|
||||
const isPast = isPastTense(tense);
|
||||
const aspect = getAspect(tense);
|
||||
const type = isAbilityTense(tense) ? "ability" : "basic";
|
||||
|
||||
// #1 get the appropriate root / stem
|
||||
const [vHead, rest] = getRootStem({
|
||||
verb,
|
||||
part: {
|
||||
rs: isPast ? "root" : "stem",
|
||||
aspect,
|
||||
},
|
||||
voice,
|
||||
type,
|
||||
genderNumber,
|
||||
|
@ -87,28 +84,50 @@ export function renderVerb({ verb, tense, person, voice }: {
|
|||
person,
|
||||
pastThird: isPast && person === T.Person.ThirdSingMale,
|
||||
aspect,
|
||||
basicForm: type === "basic" && voice === "active",
|
||||
}),
|
||||
],
|
||||
};
|
||||
}
|
||||
// const equative = equativeEndings[perfectTenseToEquative(tense)];
|
||||
// const [row, col] = getVerbBlockPosFromPerson(person);
|
||||
// const equativeBlock: T.EQ = {
|
||||
// type: "EQ",
|
||||
// person,
|
||||
// ps: "long" in equative ? {
|
||||
// long: equative.long[row][col],
|
||||
// short: equative.short[row][col],
|
||||
// } : equative[row][col],
|
||||
// }
|
||||
|
||||
function addEnding({ verb, rs, ending, person, pastThird, aspect }: {
|
||||
function renderPerfectVerb({ tense, verb, voice, person }: {
|
||||
tense: T.PerfectTense,
|
||||
verb: T.VerbEntry,
|
||||
voice: T.Voice,
|
||||
person: T.Person,
|
||||
}): { hasBa: boolean, vbs: [[], [T.VBGenNum, T.VBE]] } {
|
||||
const hasBa = tenseHasBa(tense);
|
||||
const genderNumber = {
|
||||
gender: personGender(person),
|
||||
number: personNumber(person),
|
||||
};
|
||||
// #1 get the past participle
|
||||
const pp = getPastParticiple(verb, voice, genderNumber);
|
||||
// #2 get the right equative
|
||||
const equative = equativeEndings[perfectTenseToEquative(tense)];
|
||||
const [row, col] = getVerbBlockPosFromPerson(person);
|
||||
const equativeBlock: T.VBE = {
|
||||
type: "VB",
|
||||
person,
|
||||
ps: "long" in equative ? {
|
||||
long: equative.long[row][col],
|
||||
short: equative.short[row][col],
|
||||
} : equative[row][col],
|
||||
};
|
||||
return {
|
||||
hasBa,
|
||||
vbs: [[], [pp, equativeBlock]],
|
||||
};
|
||||
}
|
||||
|
||||
function addEnding({ verb, rs, ending, person, pastThird, aspect, basicForm }: {
|
||||
rs: [T.VB, T.VBA] | [T.VBA],
|
||||
ending: T.SingleOrLengthOpts<T.PsString[]>,
|
||||
person: T.Person,
|
||||
verb: T.VerbEntry,
|
||||
pastThird: boolean,
|
||||
aspect: T.Aspect,
|
||||
basicForm: boolean,
|
||||
}): [T.VB, T.VBE] | [T.VBE] {
|
||||
return rs.length === 2
|
||||
? [rs[0], addEnd(rs[1], ending)]
|
||||
|
@ -138,7 +157,7 @@ function addEnding({ verb, rs, ending, person, pastThird, aspect }: {
|
|||
...vb,
|
||||
ps: {
|
||||
long: verbEndingConcat(rsLong, endLong),
|
||||
short: pastThird
|
||||
short: pastThird && basicForm
|
||||
? ensure3rdPast(endShort, vb.ps.short, verb, aspect)
|
||||
: verbEndingConcat(vb.ps.short, endShort),
|
||||
},
|
||||
|
@ -164,7 +183,7 @@ function getEnding(person: T.Person, isPast: boolean) {
|
|||
}
|
||||
|
||||
// TODO: THIS IS PROBABLY SKEEEETCH
|
||||
function ensure3rdPast(ending: T.PsString[], rs: T.PsString[], verb: T.VerbEntry, aspect: T.Aspect): T.PsString[] {
|
||||
function ensure3rdPast(rs: T.PsString[], ending: T.PsString[], verb: T.VerbEntry, aspect: T.Aspect): T.PsString[] {
|
||||
if (isKedul(verb) && rs[0].p === "شو") {
|
||||
return [{ p: "شو", f: "sho" }];
|
||||
}
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
concatPsString, getLength, trimOffPs,
|
||||
concatPsString, trimOffPs,
|
||||
} from "../p-text-helpers";
|
||||
import * as T from "../../../types";
|
||||
import { makePsString, removeFVarientsFromVerb } from "../accent-and-ps-utils";
|
||||
import { accentOnNFromEnd, accentSyllable, removeAccents } from "../accent-helpers";
|
||||
import { isKawulVerb } from "../type-predicates";
|
||||
import { vEntry, addAbilityEnding, weld, removeL, addTrailingAccent, tlulPerfectiveStem } from "./rs-helpers";
|
||||
import { isKawulVerb, isTlulVerb } from "../type-predicates";
|
||||
import { vEntry, addAbilityEnding, weld, removeL, addTrailingAccent, tlulPerfectiveStem, getLongVB } from "./rs-helpers";
|
||||
import { inflectPattern3 } from "./new-inflectors";
|
||||
|
||||
const kedulStat = vEntry({"ts":1581086654898,"i":11100,"p":"کېدل","f":"kedul","g":"kedul","e":"to become _____","r":2,"c":"v. intrans.","ssp":"ش","ssf":"sh","prp":"شول","prf":"shwul","pprtp":"شوی","pprtf":"shúwey","noOo":true,"ec":"become"});
|
||||
|
||||
|
@ -29,15 +30,60 @@ const shVB: T.VBBasic = {
|
|||
ps: [{ p: "ش", f: "sh" }],
|
||||
}
|
||||
|
||||
// put the past participle in a different function
|
||||
// TODO: kuRee shuwey etc
|
||||
export function getPastParticiple(verb: T.VerbEntry, voice: T.Voice, { gender, number }: { gender: T.Gender, number: T.NounNumber }): T.VBGenNum {
|
||||
const v = removeFVarientsFromVerb(verb);
|
||||
if (voice === "passive") {
|
||||
return getPassivePp(v, { gender, number });
|
||||
}
|
||||
if (verb.entry.pprtp && verb.entry.pprtf) {
|
||||
const base = makePsString(verb.entry.pprtp, verb.entry.pprtf);
|
||||
return {
|
||||
type: "VB",
|
||||
ps: inflectPattern3(base, { gender, number }),
|
||||
gender,
|
||||
number,
|
||||
};
|
||||
}
|
||||
const [_, [basicRoot]] = getImperfectiveRoot(removeFVarientsFromVerb(verb));
|
||||
const longRoot = getLongVB(basicRoot);
|
||||
|
||||
export function getRootStem({ verb, part, type, genderNumber, voice }: {
|
||||
if ("right" in longRoot) {
|
||||
return {
|
||||
...longRoot,
|
||||
right: {
|
||||
...longRoot.right,
|
||||
ps: addTail(longRoot.right.ps),
|
||||
},
|
||||
gender,
|
||||
number,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...longRoot,
|
||||
ps: addTail(longRoot.ps),
|
||||
gender,
|
||||
number,
|
||||
};
|
||||
}
|
||||
|
||||
function addTail(ps: T.SingleOrLengthOpts<T.PsString[]>): T.SingleOrLengthOpts<T.PsString[]> {
|
||||
if ("long" in ps) {
|
||||
return {
|
||||
long: addTail(ps.long) as T.PsString[],
|
||||
short: addTail(ps.short) as T.PsString[],
|
||||
};
|
||||
}
|
||||
const withTail = concatPsString(ps[0], { p: "ی", f: "ey"});
|
||||
return inflectPattern3(withTail, { gender, number });
|
||||
}
|
||||
}
|
||||
|
||||
export function getRootStem({ verb, rs, aspect, type, genderNumber, voice }: {
|
||||
verb: T.VerbEntry,
|
||||
part: {
|
||||
rs: "root" | "stem",
|
||||
aspect: T.Aspect,
|
||||
} | "pastPart",
|
||||
voice: "active" | "passive",
|
||||
voice: T.Voice,
|
||||
type: "basic" | "ability",
|
||||
genderNumber: {
|
||||
gender: T.Gender,
|
||||
|
@ -45,61 +91,65 @@ export function getRootStem({ verb, part, type, genderNumber, voice }: {
|
|||
},
|
||||
}): T.RootsStemsOutput {
|
||||
const v = removeFVarientsFromVerb(verb);
|
||||
if (part === "pastPart") {
|
||||
throw new Error("not implemented yet");
|
||||
}
|
||||
if (type === "ability") {
|
||||
return getAbilityRs(v, part);
|
||||
return getAbilityRs(v, aspect, rs, voice);
|
||||
}
|
||||
if (voice === "passive") {
|
||||
return getPassiveRs(v, part);
|
||||
return getPassiveRs(v, aspect, rs);
|
||||
}
|
||||
return part.rs === "stem"
|
||||
? part.aspect === "imperfective"
|
||||
return rs === "stem"
|
||||
? aspect === "imperfective"
|
||||
? getImperfectiveStem(v)
|
||||
: getPerfectiveStem(v, genderNumber)
|
||||
: part.aspect === "imperfective"
|
||||
: aspect === "imperfective"
|
||||
? getImperfectiveRoot(v)
|
||||
: getPerfectiveRoot(v);
|
||||
}
|
||||
|
||||
function getAbilityRs(verb: T.VerbEntryNoFVars, { aspect, rs }: { aspect: T.Aspect, rs: "root" | "stem" }): [[] | [T.VHead], [T.VB, T.VBA]] {
|
||||
const [vHead, [basicRoot]] = (aspect === "imperfective"
|
||||
? getImperfectiveRoot
|
||||
: getPerfectiveRoot
|
||||
)(verb);
|
||||
function getAbilityRs(
|
||||
verb: T.VerbEntryNoFVars,
|
||||
aspect: T.Aspect,
|
||||
rs: "root" | "stem",
|
||||
voice: T.Voice,
|
||||
): [[] | [T.VHead], [T.VB, T.VBA]] {
|
||||
const losesAspect = isTlulVerb(verb); // or is intransitive stative compound
|
||||
const [vhead, [basicroot]] = voice === "passive"
|
||||
// passive ability loses aspect
|
||||
? getPassiveRs(verb, "imperfective", "root")
|
||||
: aspect === "imperfective" || losesAspect
|
||||
? getImperfectiveRoot(verb)
|
||||
: getPerfectiveRoot(verb);
|
||||
return [
|
||||
vHead,
|
||||
vhead,
|
||||
[
|
||||
addAbilityEnding(basicRoot),
|
||||
addAbilityEnding(basicroot),
|
||||
rs === "root" ? shwulVB : shVB,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
function getPassiveRs(verb: T.VerbEntryNoFVars, part: { aspect: T.Aspect, rs: "root" | "stem" }): [[] | [T.VHead], [T.VBA]] {
|
||||
const [vHead, [basicRoot]] = (part.aspect === "imperfective"
|
||||
function getPassivePp(verb: T.VerbEntryNoFVars, genderNumber: T.GenderNumber): T.VBGenNum {
|
||||
const [_, [basicRoot]] = getImperfectiveRoot(verb);
|
||||
const longRoot = getLongVB(basicRoot);
|
||||
const kedulVbGenNum = getPastParticiple(kedulStat, "active", genderNumber) as T.VBBasic & T.GenderNumber;
|
||||
const kedulVb: T.VBBasic = {
|
||||
type: "VB",
|
||||
ps: kedulVbGenNum.ps,
|
||||
};
|
||||
return weld(longRoot, kedulVb, genderNumber);
|
||||
}
|
||||
|
||||
function getPassiveRs(verb: T.VerbEntryNoFVars, aspect: T.Aspect, rs: "root" | "stem"): [[] | [T.VHead], [T.VBA]] {
|
||||
const [vHead, [basicRoot]] = (aspect === "imperfective"
|
||||
? getImperfectiveRoot
|
||||
: getPerfectiveRoot
|
||||
)(verb);
|
||||
const longRoot = getLongVB(basicRoot);
|
||||
const kedulVba = getRootStem({ verb: kedulStat, part, type: "basic", voice: "active", genderNumber: { gender: "masc", number: "singular" }})[1][0] as T.VBBasic;
|
||||
const kedulVba = getRootStem({ verb: kedulStat, aspect, rs, type: "basic", voice: "active", genderNumber: { gender: "masc", number: "singular" }})[1][0] as T.VBBasic;
|
||||
return [
|
||||
vHead,
|
||||
[weld(longRoot, kedulVba)],
|
||||
];
|
||||
function getLongVB(vb: T.VBA): T.VBA {
|
||||
if (vb.type === "welded") {
|
||||
return {
|
||||
...vb,
|
||||
right: getLongVB(vb) as T.VBBasic,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...vb,
|
||||
ps: getLength(vb.ps, "long"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getImperfectiveRoot(verb: T.VerbEntryNoFVars): [[], [T.VBA]] {
|
||||
|
@ -211,12 +261,6 @@ function getPerfectiveStem(verb: T.VerbEntryNoFVars, person: { gender: T.Gender,
|
|||
];
|
||||
}
|
||||
|
||||
// function getPastPart(verb: T.VerbEntryNoFVars, person: { gender: T.Gender, number: T.NounNumber }): T.SingleOrLengthOpts<T.PsString> {
|
||||
// const root = getImperfectiveRoot(verb);
|
||||
// // TODO: with new inflection engine more streamlined
|
||||
// return inflectRoot
|
||||
// }
|
||||
|
||||
function getPerfectiveHead(base: T.PsString, { entry }: T.VerbEntryNoFVars): [T.PH, T.PsString] | [undefined, T.PsString] {
|
||||
// if ((verb.entry.ssp && verb.entry.ssf) || verb.entry.separationAtP) {
|
||||
// // handle split
|
||||
|
|
|
@ -4,6 +4,7 @@ import { accentPsSyllable, removeAccents, removeAccentsWLength } from "../accent
|
|||
import { concatPsString, trimOffPs } from "../p-text-helpers";
|
||||
import { getRootStem } from "./roots-and-stems";
|
||||
import { inflectPattern1 } from "./new-inflectors";
|
||||
import { getLength } from "../p-text-helpers";
|
||||
|
||||
export function vEntry(e: any, c?: any): T.VerbEntryNoFVars {
|
||||
return {
|
||||
|
@ -26,12 +27,12 @@ export function getAllRs(verb: T.VerbEntry): {
|
|||
} {
|
||||
return {
|
||||
stem: {
|
||||
perfective: getRootStem({ verb, type: "basic", voice: "active", part: { rs: "stem", aspect: "perfective" }, genderNumber: { gender: "masc", number: "singular" } }),
|
||||
imperfective: getRootStem({ verb, type: "basic", voice: "active", part: { rs: "stem", aspect: "imperfective" }, genderNumber: { gender: "masc", number: "singular" } }),
|
||||
perfective: getRootStem({ verb, type: "basic", voice: "active", rs: "stem", aspect: "perfective", genderNumber: { gender: "masc", number: "singular" } }),
|
||||
imperfective: getRootStem({ verb, type: "basic", voice: "active", rs: "stem", aspect: "imperfective", genderNumber: { gender: "masc", number: "singular" } }),
|
||||
},
|
||||
root: {
|
||||
perfective: getRootStem({ verb, type: "basic", voice: "active", part: { rs: "root", aspect: "perfective" }, genderNumber: { gender: "masc", number: "singular" } }),
|
||||
imperfective: getRootStem({ verb, type: "basic", voice: "active", part: { rs: "root", aspect: "imperfective" }, genderNumber: { gender: "masc", number: "singular" } }),
|
||||
perfective: getRootStem({ verb, type: "basic", voice: "active", rs: "root", aspect: "perfective", genderNumber: { gender: "masc", number: "singular" } }),
|
||||
imperfective: getRootStem({ verb, type: "basic", voice: "active", rs: "root", aspect: "imperfective", genderNumber: { gender: "masc", number: "singular" } }),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -45,6 +46,14 @@ export function getAllRs(verb: T.VerbEntry): {
|
|||
* @returns
|
||||
*/
|
||||
export function verbEndingConcat(ps: T.PsString[], end: T.PsString[]): T.PsString[] {
|
||||
if (ps[0].f === "shw") {
|
||||
if (end[1]?.f === "o") {
|
||||
return [{ p: "شو", f: "sho" }];
|
||||
}
|
||||
if (end[0].f === "oo") {
|
||||
return [{ p: "شو", f: "oo" }];
|
||||
}
|
||||
}
|
||||
return ps.flatMap(v => (
|
||||
end.map(e => {
|
||||
if (v.f.charAt(v.f.length-1) === "X") {
|
||||
|
@ -58,17 +67,26 @@ export function verbEndingConcat(ps: T.PsString[], end: T.PsString[]): T.PsStrin
|
|||
));
|
||||
}
|
||||
|
||||
export function weld(left: T.Welded["left"], right: T.Welded["right"]): T.Welded {
|
||||
// TODO: better to have the genderNumber included and inferred in the right?
|
||||
export function weld(left: T.Welded["left"], right: T.Welded["right"]): T.Welded;
|
||||
export function weld(left: T.Welded["left"], right: T.Welded["right"], genderNum: T.GenderNumber): T.Welded & T.GenderNumber;
|
||||
export function weld(left: T.Welded["left"], right: T.Welded["right"], genderNum?: T.GenderNumber): T.Welded {
|
||||
return {
|
||||
type: "welded",
|
||||
left: removeAccentsFromLeft(left),
|
||||
right,
|
||||
...genderNum ? {
|
||||
...genderNum,
|
||||
} : {},
|
||||
}
|
||||
function removeAccentsFromLeft(left: T.Welded["left"]): T.Welded["left"] {
|
||||
if (left.type === "VB") {
|
||||
return {
|
||||
...left,
|
||||
ps: removeAccentsWLength(left.ps),
|
||||
...genderNum ? {
|
||||
...genderNum,
|
||||
} : {},
|
||||
}
|
||||
}
|
||||
if (left.type === "NComp") {
|
||||
|
@ -77,7 +95,10 @@ export function weld(left: T.Welded["left"], right: T.Welded["right"]): T.Welded
|
|||
comp: {
|
||||
...left.comp,
|
||||
ps: removeAccents(left.comp.ps),
|
||||
}
|
||||
},
|
||||
...genderNum ? {
|
||||
...genderNum,
|
||||
} : {},
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
@ -86,6 +107,9 @@ export function weld(left: T.Welded["left"], right: T.Welded["right"]): T.Welded
|
|||
...left.right,
|
||||
ps: removeAccentsWLength(left.right.ps),
|
||||
},
|
||||
...genderNum ? {
|
||||
...genderNum,
|
||||
} : {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -149,3 +173,16 @@ export function addToVBBasicEnd(vb: T.VBBasic, end: T.PsString[]): T.VBBasic {
|
|||
ps: verbEndingConcat(vb.ps, end),
|
||||
};
|
||||
}
|
||||
|
||||
export function getLongVB(vb: T.VBA): T.VBA {
|
||||
if (vb.type === "welded") {
|
||||
return {
|
||||
...vb,
|
||||
right: getLongVB(vb) as T.VBBasic,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...vb,
|
||||
ps: getLength(vb.ps, "long"),
|
||||
};
|
||||
}
|
|
@ -1090,7 +1090,9 @@ export type VBBasic = {
|
|||
ps: SingleOrLengthOpts<PsString[]>,
|
||||
};
|
||||
|
||||
export type VBGenNum = VBBasic & GenderNumber;
|
||||
// TODO: might be a better design decision to keep the GenderNuber stuff
|
||||
// in the RIGHT side of the weld
|
||||
export type VBGenNum = (VBBasic | Welded) & GenderNumber;
|
||||
|
||||
export type GenderNumber = {
|
||||
gender: Gender,
|
||||
|
|
Loading…
Reference in New Issue