diff --git a/src/lib/src/new-verb-engine/render-verb.ts b/src/lib/src/new-verb-engine/render-verb.ts index 3c62219..ea5c979 100644 --- a/src/lib/src/new-verb-engine/render-verb.ts +++ b/src/lib/src/new-verb-engine/render-verb.ts @@ -4,9 +4,6 @@ import { personGender, personNumber, } from "../misc-helpers"; -import { - trimOffPs, -} from "../p-text-helpers"; import { concatPsString, getLength, @@ -21,8 +18,8 @@ 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 { accentPsSyllable } from "../accent-helpers"; import { 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 // length variations earlier in the blocks, flatten those into the variations @@ -65,14 +62,17 @@ export function renderVerb({ verb, tense, person, voice }: { number: personNumber(person), }; // #1 get the appropriate root / stem - console.log({ isAbility }); const [vHead, rest] = getRootStem({ verb, part: { rs: isPast ? "root" : "stem", aspect, }, - type: isAbility ? "ability" : "basic", + type: voice === "passive" + ? "passive" + : isAbility + ? "ability" + : "basic", genderNumber, }); // #2 add the verb ending to it @@ -156,20 +156,6 @@ function addEnding({ verb, rs, ending, person, pastThird, aspect }: { } } -function verbEndingConcat(ps: T.PsString[], end: T.PsString[]): T.PsString[] { - return ps.flatMap(v => ( - end.map(e => { - if (v.f.charAt(v.f.length-1) === "X") { - return concatPsString(trimOffPs(v, 0, 1), accentPsSyllable(e)) - } - if (e.p === "ل" && ["ul", "úl"].includes(v.f.slice(-2))) { - return v; - } - return concatPsString(v, e); - }) - )); -} - function getEnding(person: T.Person, isPast: boolean) { const [row, col] = getVerbBlockPosFromPerson(person); return isPast ? { diff --git a/src/lib/src/new-verb-engine/roots-and-stems.ts b/src/lib/src/new-verb-engine/roots-and-stems.ts index 8e08033..a8f3c8c 100644 --- a/src/lib/src/new-verb-engine/roots-and-stems.ts +++ b/src/lib/src/new-verb-engine/roots-and-stems.ts @@ -7,13 +7,15 @@ */ import { - concatPsString, trimOffPs, + concatPsString, getLength, 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 { inflectPattern1 } from "./new-inflectors"; +import { vEntry, addAbilityEnding, weld, removeL, addTrailingAccent, tlulPerfectiveStem } from "./rs-helpers"; + +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"}); const shwulVB: T.VBBasic = { type: "VB", @@ -22,6 +24,10 @@ const shwulVB: T.VBBasic = { short: [{ p: "شو", f: "shw" }], }, } +const shVB: T.VBBasic = { + type: "VB", + ps: [{ p: "ش", f: "sh" }], +} // start basic inflection functions for pattern 1 and pattern ey things // to be used by inflecting لاړ and participles @@ -38,36 +44,65 @@ export function getRootStem({ verb, part, type, genderNumber }: { number: T.NounNumber, }, }): T.RootsStemsOutput { - console.log({ type }); const v = removeFVarientsFromVerb(verb); if (part === "pastPart") { throw new Error("not implemented yet"); } - console.log({ part }); + if (type === "ability") { + return getAbilityRs(v, part); + } + if (type === "passive") { + return getPassiveRs(v, part); + } return part.rs === "stem" ? part.aspect === "imperfective" ? getImperfectiveStem(v) : getPerfectiveStem(v, genderNumber) : part.aspect === "imperfective" - ? getImperfectiveRoot(v, type) + ? getImperfectiveRoot(v) : getPerfectiveRoot(v); } -function getImperfectiveRoot(verb: T.VerbEntryNoFVars, type: "basic" | "ability" | "passive"): T.RootsStemsOutput { - // if (type === "ability") { - // console.log("in ability"); - // const basic = getImperfectiveRoot(verb, "basic") as [[T.VHead] | [], [T.VBA]]; - // return [ - // basic[0], - // [ - // { - // type: "VB", - - // [1], - // shwulVB, - // ], - // ]; - // } +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); + return [ + vHead, + [ + 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" + ? getImperfectiveRoot + : getPerfectiveRoot + )(verb); + const longRoot = getLongVB(basicRoot); + const kedulVba = getRootStem({ verb: kedulStat, part, type: "basic", 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); return [ [], @@ -83,7 +118,7 @@ function getImperfectiveRoot(verb: T.VerbEntryNoFVars, type: "basic" | "ability" ]; } -function getPerfectiveRoot(verb: T.VerbEntryNoFVars): T.RootsStemsOutput { +function getPerfectiveRoot(verb: T.VerbEntryNoFVars): [[T.VHead] | [], [T.VBA]] { const base = removeAccents( (verb.entry.prp && verb.entry.prf) ? makePsString(verb.entry.prp, verb.entry.prf) @@ -258,37 +293,3 @@ function getPerfectiveHead(base: T.PsString, { entry }: T.VerbEntryNoFVars): [T. }; } } - -function addTrailingAccent(ps: T.PsString): T.PsString { - return { - p: ps.p, - f: ps.f + "X", - }; -} - -function addUl(b: T.PsString): T.PsString { - return concatPsString(b, { p: "ل", f: "ul" }); -} - -// TODO: could do removeEndingL (slower but safer) - -function removeL(ps: T.PsString): T.PsString { - return trimOffPs(ps, 1, 2); -} - -function tlulPerfectiveStem(person: { gender: T.Gender, number: T.NounNumber }): T.RootsStemsOutput { - return [ - [ - { - type: "PH", - ps: inflectPattern1({ p: "لاړ", f: "laaR" }, person).map(x => concatPsString(x, " "))[0], - }, - ], - [ - { - type: "VB", - ps: [{ p: "ش", f: "sh" }], - }, - ], - ]; -} \ No newline at end of file diff --git a/src/lib/src/new-verb-engine/rs-helpers.ts b/src/lib/src/new-verb-engine/rs-helpers.ts index 25b23e2..e0bfb66 100644 --- a/src/lib/src/new-verb-engine/rs-helpers.ts +++ b/src/lib/src/new-verb-engine/rs-helpers.ts @@ -1,13 +1,17 @@ import * as T from "../../../types"; +import { removeFVarients } from "../accent-and-ps-utils"; +import { accentPsSyllable, removeAccents, removeAccentsWLength } from "../accent-helpers"; +import { concatPsString, trimOffPs } from "../p-text-helpers"; import { getRootStem } from "./roots-and-stems"; +import { inflectPattern1 } from "./new-inflectors"; -export function vEntry(e: any, c?: any): T.VerbEntry { +export function vEntry(e: any, c?: any): T.VerbEntryNoFVars { return { - entry: e, + entry: removeFVarients(e), ...c ? { c, } : {}, - } as T.VerbEntry; + } as T.VerbEntryNoFVars; } export function getAllRs(verb: T.VerbEntry): { @@ -30,4 +34,118 @@ export function getAllRs(verb: T.VerbEntry): { imperfective: getRootStem({ verb, type: "basic", part: { rs: "root", aspect: "imperfective" }, genderNumber: { gender: "masc", number: "singular" } }), }, }; +} + +/** + * adds a verb ending, creating all the variations with a set of root psStrings + * it is aware of the trailing accent marker X and also avoids adding the double ل ending 3rd pers masc plur + * + * @param ps - a verb root/stem + * @param end - the verb ending + * @returns + */ +export function verbEndingConcat(ps: T.PsString[], end: T.PsString[]): T.PsString[] { + return ps.flatMap(v => ( + end.map(e => { + if (v.f.charAt(v.f.length-1) === "X") { + return concatPsString(trimOffPs(v, 0, 1), accentPsSyllable(e)) + } + if (e.p === "ل" && ["ul", "úl"].includes(v.f.slice(-2))) { + return v; + } + return concatPsString(v, e); + }) + )); +} + +export function weld(left: T.Welded["left"], right: T.Welded["right"]): T.Welded { + return { + type: "welded", + left: removeAccentsFromLeft(left), + right, + } + function removeAccentsFromLeft(left: T.Welded["left"]): T.Welded["left"] { + if (left.type === "VB") { + return { + ...left, + ps: removeAccentsWLength(left.ps), + } + } + if (left.type === "NComp") { + return { + ...left, + comp: { + ...left.comp, + ps: removeAccents(left.comp.ps), + } + }; + } + return { + ...left, + right: { + ...left.right, + ps: removeAccentsWLength(left.right.ps), + }, + }; + } +} + +export function addTrailingAccent(ps: T.PsString): T.PsString { + return { + p: ps.p, + f: ps.f + "X", + }; +} + +// TODO: could do removeEndingL (slower but safer) + +export function removeL(ps: T.PsString): T.PsString { + return trimOffPs(ps, 1, 2); +} + +export function tlulPerfectiveStem(person: { gender: T.Gender, number: T.NounNumber }): T.RootsStemsOutput { + return [ + [ + { + type: "PH", + ps: inflectPattern1({ p: "لاړ", f: "laaR" }, person).map(x => concatPsString(x, " "))[0], + }, + ], + [ + { + type: "VB", + ps: [{ p: "ش", f: "sh" }], + }, + ], + ]; +} + +export function addAbilityEnding(vb: T.VBA): T.VBA { + const abilityEnding: T.PsString[] = [ + { p: "ی", f: "ey" }, + { p: "ای", f: "aay" }, + ]; + if (vb.type === "welded") { + return { + ...vb, + right: addToVBBasicEnd(vb.right, abilityEnding), + }; + } + return addToVBBasicEnd(vb, abilityEnding); +} + +export function addToVBBasicEnd(vb: T.VBBasic, end: T.PsString[]): T.VBBasic { + if ("long" in vb.ps) { + return { + ...vb, + ps: { + long: verbEndingConcat(vb.ps.long, end), + short: verbEndingConcat(vb.ps.short, end), + }, + }; + } + return { + ...vb, + ps: verbEndingConcat(vb.ps, end), + }; } \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index 125180a..44fb9a9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1078,8 +1078,9 @@ export type VerbRenderedOutput = [[VHead] | [], [VB, VBE] | [VBE]]; export type RootsStemsOutput = [[VHead] | [], [VB, VBA] | [VBA]]; // or perfect / equative export type VB = VBBasic | VBGenNum | Welded; +/** A VB block that can have endings attached to it */ export type VBA = Exclude; - +/** A VB block that has had a person verb ending attached */ export type VBE = (VBBasic | Welded) & { person: Person, }; // or equative