This commit is contained in:
adueck 2023-04-11 11:22:09 +04:00
parent 91d3a10abb
commit ed4e494e54
5 changed files with 182 additions and 79 deletions

View File

@ -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 {

View File

@ -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,
},
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" }];
}

View File

@ -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",
rs: "root" | "stem",
aspect: T.Aspect,
voice: T.Voice,
type: "basic" | "ability",
genderNumber: {
gender: T.Gender,
@ -45,62 +91,66 @@ 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]] {
const infinitive = accentOnNFromEnd(makePsString(verb.entry.p, verb.entry.f), 0);
@ -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

View File

@ -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,
} : {},
};
}
}
@ -148,4 +172,17 @@ export function addToVBBasicEnd(vb: T.VBBasic, end: T.PsString[]): T.VBBasic {
...vb,
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"),
};
}

View File

@ -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,