full testing for roots and stems and render verb - need to add imperative

This commit is contained in:
adueck 2023-04-17 21:15:55 -04:00
parent 9f08c4cc5b
commit 623db598bb
6 changed files with 972 additions and 87 deletions

View File

@ -3,6 +3,7 @@ import { vEntry } from "./rs-helpers";
import * as T from "../../../types"; import * as T from "../../../types";
const wahul = vEntry({"ts":1527815399,"i":15049,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","r":4,"c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"}); const wahul = vEntry({"ts":1527815399,"i":15049,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","r":4,"c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"});
const raawrul = vEntry({"ts":1527815214,"i":6954,"p":"راوړل","f":"raawRúl","g":"raawRul","e":"to bring, deliver (inanimate objects)","r":4,"c":"v. trans.","tppp":"راووړ","tppf":"raawoR","noOo":true,"separationAtP":2,"separationAtF":3,"ec":"bring,brings,bringing,brought,brought"});
const achawul = vEntry({"ts":1527811872,"i":224,"p":"اچول","f":"achawul","g":"achawul","e":"to put, pour, drop, throw, put on","r":4,"c":"v. trans.","ec":"put,puts,putting,put,put"}); const achawul = vEntry({"ts":1527811872,"i":224,"p":"اچول","f":"achawul","g":"achawul","e":"to put, pour, drop, throw, put on","r":4,"c":"v. trans.","ec":"put,puts,putting,put,put"});
const ganul = vEntry({"ts":1527812000,"i":11398,"p":"ګڼل","f":"gaNul, guNul","g":"gaNul,guNul","e":"to count, consider, reckon, suppose, assume","r":4,"c":"v. trans.","tppp":"ګاڼه","tppf":"gaaNu","ec":"deem"}); const ganul = vEntry({"ts":1527812000,"i":11398,"p":"ګڼل","f":"gaNul, guNul","g":"gaNul,guNul","e":"to count, consider, reckon, suppose, assume","r":4,"c":"v. trans.","tppp":"ګاڼه","tppf":"gaaNu","ec":"deem"});
const kawulStat = vEntry({"ts":1579015359582,"i":11030,"p":"کول","f":"kawul","g":"kawul","e":"to make ____ ____ (as in \"He's making me angry.\")","r":4,"c":"v. trans.","ssp":"کړ","ssf":"kR","prp":"کړل","prf":"kRul","pprtp":"کړی","pprtf":"kúRey","noOo":true,"ec":"make,makes,making,made,made"}); const kawulStat = vEntry({"ts":1579015359582,"i":11030,"p":"کول","f":"kawul","g":"kawul","e":"to make ____ ____ (as in \"He's making me angry.\")","r":4,"c":"v. trans.","ssp":"کړ","ssf":"kR","prp":"کړل","prf":"kRul","pprtp":"کړی","pprtf":"kúRey","noOo":true,"ec":"make,makes,making,made,made"});
@ -26,6 +27,7 @@ const kenaastul = vEntry({"ts":1527812759,"i":11124,"p":"کېناستل","f":"ke
const ghadzedul = vEntry({"ts":1527812615,"i":9500,"p":"غځېدل","f":"ghadzedul","g":"ghadzedul","e":"stretch out, lie, be extended, expand","r":3,"c":"v. intrans.","ec":"stretch","ep":"out"}); const ghadzedul = vEntry({"ts":1527812615,"i":9500,"p":"غځېدل","f":"ghadzedul","g":"ghadzedul","e":"stretch out, lie, be extended, expand","r":3,"c":"v. intrans.","ec":"stretch","ep":"out"});
const prexodul = vEntry({"ts":1527815190,"i":2495,"p":"پرېښودل","f":"prexodúl","g":"prexodul","e":"to leave, abandon, forsake, let go, allow","r":4,"c":"v. trans.","psp":"پرېږد","psf":"preGd","noOo":true,"separationAtP":3,"separationAtF":3,"ec":"abandon"}); const prexodul = vEntry({"ts":1527815190,"i":2495,"p":"پرېښودل","f":"prexodúl","g":"prexodul","e":"to leave, abandon, forsake, let go, allow","r":4,"c":"v. trans.","psp":"پرېږد","psf":"preGd","noOo":true,"separationAtP":3,"separationAtF":3,"ec":"abandon"});
const raawustul = vEntry({"ts":1527819827,"i":6955,"p":"راوستل","f":"raawustúl","g":"raawustul","e":"to bring, deliver (animate objects), obtain, extract","r":3,"c":"v. trans.","psp":"راول","psf":"raawul","noOo":true,"separationAtP":2,"separationAtF":3,"ec":"bring,brings,bringing,brought,brought"}); const raawustul = vEntry({"ts":1527819827,"i":6955,"p":"راوستل","f":"raawustúl","g":"raawustul","e":"to bring, deliver (animate objects), obtain, extract","r":3,"c":"v. trans.","psp":"راول","psf":"raawul","noOo":true,"separationAtP":2,"separationAtF":3,"ec":"bring,brings,bringing,brought,brought"});
const leedul = vEntry({"ts":1527812275,"i":12049,"p":"لیدل","f":"leedul","g":"leedul","e":"to see","r":4,"c":"v. trans./gramm. trans.","psp":"وین","psf":"ween","tppp":"لید","tppf":"leed","ec":"see,sees,seeing,saw,seen"});
const bandawul = vEntry( const bandawul = vEntry(
{"ts":1527821309,"i":1792,"p":"بندول","f":"bandawul","g":"bandawul","e":"to close, block, stop, barricade, cut off, restrain, hold back","r":3,"c":"v. stat. comp. trans.","l":1577301753727,"ec":"close"}, {"ts":1527821309,"i":1792,"p":"بندول","f":"bandawul","g":"bandawul","e":"to close, block, stop, barricade, cut off, restrain, hold back","r":3,"c":"v. stat. comp. trans.","l":1577301753727,"ec":"close"},
{"ts":1577301753727,"i":1780,"p":"بند","f":"band","g":"band","e":"closed, blocked, stopped","c":"adj."}, {"ts":1577301753727,"i":1780,"p":"بند","f":"band","g":"band","e":"closed, blocked, stopped","c":"adj."},
@ -42,7 +44,7 @@ const stureyKedul = vEntry(
{"ts":1591033069786,"i":7878,"p":"ستړی کېدل","f":"stuRey kedul","g":"stuReykedul","e":"to get tired, fatigued","r":4,"c":"v. stat. comp. intrans.","l":1527815306,"ec":"get","ep":"tired"}, {"ts":1591033069786,"i":7878,"p":"ستړی کېدل","f":"stuRey kedul","g":"stuReykedul","e":"to get tired, fatigued","r":4,"c":"v. stat. comp. intrans.","l":1527815306,"ec":"get","ep":"tired"},
{"ts":1527815306,"i":7876,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","r":4,"c":"adj. / adv."}, {"ts":1527815306,"i":7876,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","r":4,"c":"adj. / adv."},
); );
const ooPh: T.PH = { type: "PH", ps: { p: "و", f: "óo" }};
test("basic tenses", () => { test("basic tenses", () => {
expect(renderVerb({ expect(renderVerb({
@ -97,6 +99,537 @@ test("basic tenses", () => {
}); });
}); });
test("basic tenses with inflecting roots/stems", () => {
expect(renderVerb({
verb: bandawul,
tense: "subjunctiveVerb",
person: T.Person.FirstSingMale,
presObj: T.Person.ThirdSingFemale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[
{
type: "NComp",
comp: {
type: "AdjComp",
ps: { p: "بنده", f: "bánda" },
gender: "fem",
number: "singular",
},
},
],
[
{
type: "VB",
ps: {
long: [{ p: "کړم", f: "kRum" }],
short: [{ p: "کم", f: "kum" }],
},
person: T.Person.FirstSingMale,
},
],
],
});
});
test("special endings", () => {
const tests: {
verb: T.VerbEntryNoFVars,
tense: "perfectivePast" | "imperfectivePast",
result: T.VerbRenderedOutput,
}[] = [
// verbs ending in -awul
{
verb: achawul,
tense: "perfectivePast",
result: [
[{ type: "PH", ps: { p: "وا", f: "wáa" }}],
[
{
type: "VB",
ps: {
long: [{ p: "چولو", f: "chawulo" }],
short: [{ p: "چاوه", f: "chaawu" }],
},
person: 4,
},
],
],
},
{
verb: achawul,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "اچولو", f: "achawúlo" }],
short: [{ p: "اچاوه", f: "achaawú" }],
},
person: 4,
},
],
],
},
// verbs with special tppp
{
verb: ganul,
tense: "perfectivePast",
result: [
[ooPh],
[
{
type: "VB",
ps: {
long: [{ p: "ګڼلو", f: "gaNulo" }],
short: [{ p: "ګاڼه", f: "gaaNu" }],
},
person: 4,
},
],
],
},
{
verb: ganul,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "ګڼلو", f: "gaNúlo" }],
short: [{ p: "ګاڼه", f: "gaaNú" }],
},
person: 4,
},
],
],
},
// verbs with special tppp ending in a consonant
{
verb: khatul,
tense: "perfectivePast",
result: [
[ooPh],
[
{
type: "VB",
ps: {
long: [{ p: "ختلو", f: "khatulo" }],
short: [
{ p: "خوت", f: "khot" },
// // TODO: is this even right?
// { p: "خوته", f: "khotu" },
// { p: "خوتو", f: "khoto" },
],
},
person: 4,
},
],
],
},
{
verb: leedul,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "لیدلو", f: "leedúlo" }],
short: [
{ p: "لید", f: "léed" },
// // TODO: is this even right?
// { p: "خوته", f: "khotu" },
// { p: "خوتو", f: "khoto" },
],
},
person: 4,
},
],
],
},
{
verb: raawrul,
tense: "perfectivePast",
result: [
[{ type: "PH", ps: { p: "را", f: "ráa" }}],
[
{
type: "VB",
ps: {
long: [{ p: "وړلو", f: "wRulo" }],
short: [{ p: "ووړ", f: "woR" }],
},
person: 4,
},
],
],
},
// verbs ending in a dental ت or د
{
verb: rasedul,
tense: "perfectivePast",
result: [
[ooPh],
[
{
type: "VB",
ps: {
long: [{ p: "رسېدلو", f: "rasedulo" }],
short: [
{ p: "رسېد", f: "rased" },
{ p: "رسېده", f: "rasedu" },
{ p: "رسېدو", f: "rasedo" },
],
},
person: 4,
},
],
],
},
{
verb: awuxtul,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "اوښتلو", f: "awUxtúlo" }],
short: [
{ p: "اوښت", f: "awÚxt" },
{ p: "اوښته", f: "awUxtú" },
{ p: "اوښتو", f: "awUxtó" },
],
},
person: 4,
},
],
],
},
// other verbs
{
verb: weshul,
tense: "perfectivePast",
result: [
[ooPh],
[
{
type: "VB",
ps: {
long: [{ p: "وېشلو", f: "weshulo" }],
short: [
{ p: "وېشه", f: "weshu" },
{ p: "وېشو", f: "wesho" },
],
},
person: 4,
},
],
],
},
{
verb: kedulStat,
tense: "perfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "شولو", f: "shwulo" }],
short: [{ p: "شو", f: "sho" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: kedulStat,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "کېدلو", f: "kedúlo" }],
short: [{ p: "کېده", f: "kedú" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: kawulStat,
tense: "perfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "کړلو", f: "kRulo" }],
short: [
{ p: "کړ", f: "kuR" },
{ p: "کړه", f: "kRu" },
{ p: "کړو", f: "kRo" },
],
mini: [{ p: "که", f: "ku" }, { p: "کو", f: "ko" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: kawulDyn,
tense: "perfectivePast",
result: [
[ooPh],
[
{
type: "VB",
ps: {
long: [{ p: "کړلو", f: "kRulo" }],
short: [
{ p: "کړ", f: "kuR" },
{ p: "کړه", f: "kRu" },
{ p: "کړو", f: "kRo" },
],
mini: [{ p: "که", f: "ku" }, { p: "کو", f: "ko" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: kawulDyn,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "کولو", f: "kawúlo" }],
short: [{ p: "کاوه", f: "kaawú" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: tlul,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "تللو", f: "tlúlo" }],
short: [{ p: "ته", f: "tú" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: tlul,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "تللو", f: "tlúlo" }],
short: [{ p: "ته", f: "tú" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: raatlul,
tense: "imperfectivePast",
result: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "راتللو", f: "raatlúlo" }],
short: [{ p: "راته", f: "raatú" }],
},
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: raatlul,
tense: "perfectivePast",
result: [
[{ type: "PH", ps: { p: "را", f: "ráa" }}],
[
{
type: "VB",
ps: [{ p: "غی", f: "ghey" }],
person: T.Person.ThirdSingMale,
},
],
],
},
{
verb: wartlul,
tense: "perfectivePast",
result: [
[{ type: "PH", ps: { p: "ور", f: "wár" }}],
[
{
type: "VB",
ps: [{ p: "غی", f: "ghey" }],
person: T.Person.ThirdSingMale,
},
],
],
},
];
tests.forEach(x => {
expect(renderVerb({
verb: x.verb,
tense: x.tense,
person: T.Person.ThirdSingMale,
voice: "active",
})).toEqual({ hasBa: false, vbs: x.result });
});
expect(renderVerb({
verb: kedulStat,
tense: "perfectivePast",
person: T.Person.FirstPlurMale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "شولو", f: "shwuloo" }],
short: [{ p: "شو", f: "shoo" }],
},
person: T.Person.FirstPlurMale,
},
],
],
});
expect(renderVerb({
verb: tlul,
tense: "imperfectivePast",
person: T.Person.FirstSingMale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "تللم", f: "tlúlum" }],
// TODO: Shouldn't be accent here on single syllable
short: [{ p: "تلم", f: "tlúm" }],
},
person: T.Person.FirstSingMale,
},
],
],
});
expect(renderVerb({
verb: tlul,
tense: "imperfectivePast",
person: T.Person.ThirdSingFemale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "تلله", f: "tlúla" }],
// TODO: Shouldn't be accent here on single syllable
short: [{ p: "تله", f: "tlá" }],
},
person: T.Person.ThirdSingFemale,
},
],
],
});
// avoid redundant ل ending
expect(renderVerb({
verb: khorul,
tense: "imperfectivePast",
person: T.Person.ThirdPlurMale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{
type: "VB",
ps: {
long: [{ p: "خوړل", f: "khoRúl" }],
short: [{ p: "خوړل", f: "khoRúl" }],
},
person: T.Person.ThirdPlurMale,
},
],
],
});
expect(renderVerb({
verb: khorul,
tense: "perfectivePast",
person: T.Person.ThirdPlurMale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[ooPh],
[
{
type: "VB",
ps: {
long: [{ p: "خوړل", f: "khoRul" }],
short: [{ p: "خوړل", f: "khoRul" }],
},
person: T.Person.ThirdPlurMale,
},
],
],
});
});
test("perfect tenses", () => { test("perfect tenses", () => {
expect(renderVerb({ expect(renderVerb({
verb: wahul, verb: wahul,
@ -113,6 +646,88 @@ test("perfect tenses", () => {
], ],
], ],
}); });
expect(renderVerb({
verb: wahul,
tense: "subjunctivePerfect",
person: T.Person.FirstSingMale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{ type: "VB", ps: [{ p: "وهلی", f: "wahúley" }], gender: "masc", number: "singular" },
{ type: "VB", ps: [{ p: "وم", f: "wum" }], person: T.Person.FirstSingMale },
],
],
});
expect(renderVerb({
verb: wahul,
tense: "habitualPerfect",
person: T.Person.FirstSingMale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{ type: "VB", ps: [{ p: "وهلی", f: "wahúley" }], gender: "masc", number: "singular" },
{ type: "VB", ps: [{ p: "یم", f: "yum" }], person: T.Person.FirstSingMale },
],
],
});
expect(renderVerb({
verb: wahul,
tense: "habitualPerfect",
person: T.Person.ThirdPlurMale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{ type: "VB", ps: [{ p: "وهلي", f: "wahúlee" }], gender: "masc", number: "plural" },
{ type: "VB", ps: [{ p: "وي", f: "wee" }], person: T.Person.ThirdPlurMale },
],
],
});
expect(renderVerb({
verb: wahul,
tense: "futurePerfect",
person: T.Person.FirstSingMale,
voice: "active",
})).toEqual({
hasBa: true,
vbs: [
[],
[
{ type: "VB", ps: [{ p: "وهلی", f: "wahúley" }], gender: "masc", number: "singular" },
{ type: "VB", ps: [{ p: "یم", f: "yum" }], person: T.Person.FirstSingMale },
],
],
});
expect(renderVerb({
verb: wahul,
tense: "pastPerfect",
person: T.Person.SecondSingFemale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{ type: "VB", ps: [{ p: "وهلې", f: "wahúle" }], gender: "fem", number: "singular" },
{
type: "VB",
ps: {
long: [{ p: "ولې", f: "wule" }],
short: [{ p: "وې", f: "we" }],
},
person: T.Person.SecondSingFemale,
},
],
],
});
expect(renderVerb({ expect(renderVerb({
verb: wahul, verb: wahul,
tense: "wouldBePerfect", tense: "wouldBePerfect",
@ -135,6 +750,44 @@ test("perfect tenses", () => {
], ],
], ],
}); });
expect(renderVerb({
verb: wahul,
tense: "pastSubjunctivePerfect",
person: T.Person.SecondSingFemale,
voice: "active",
})).toEqual({
hasBa: false,
vbs: [
[],
[
{ type: "VB", ps: [{ p: "وهلې", f: "wahúle" }], gender: "fem", number: "singular" },
{
type: "VB",
ps: [{ p: "وای", f: "waay" }, { p: "وی", f: "wey" }],
person: T.Person.SecondSingFemale,
},
],
],
});
expect(renderVerb({
verb: wahul,
tense: "wouldHaveBeenPerfect",
person: T.Person.SecondSingFemale,
voice: "active",
})).toEqual({
hasBa: true,
vbs: [
[],
[
{ type: "VB", ps: [{ p: "وهلې", f: "wahúle" }], gender: "fem", number: "singular" },
{
type: "VB",
ps: [{ p: "وای", f: "waay" }, { p: "وی", f: "wey" }],
person: T.Person.SecondSingFemale,
},
],
],
});
}); });
test("ability tenses", () => { test("ability tenses", () => {
@ -169,4 +822,82 @@ test("ability tenses", () => {
], ],
], ],
}); });
});
test("ending on complex verbs", () => {
expect(renderVerb({
verb: stureyKawul,
tense: "presentVerbModal",
person: T.Person.SecondSingMale,
voice: "active",
presObj: T.Person.ThirdSingFemale
})).toEqual({
hasBa: false,
vbs: [
[],
[
{
type: "welded",
left: {
type: "NComp",
comp: {
type: "AdjComp",
ps: { p: "ستړې", f: "stuRe" },
gender: "fem",
number: "singular",
},
},
right: {
type: "VB",
ps: {
long: [
{ p: "کولی", f: "kawúley" },
{ p: "کولای", f: "kawúlaay" },
],
short: [
{ p: "کوی", f: "kawéy" },
{ p: "کوای", f: "kawáay" },
],
},
},
},
{
type: "VB",
ps: [{ p: "شې", f: "she" }],
person: T.Person.SecondSingMale,
},
],
],
});
expect(renderVerb({
verb: stureyKawul,
tense: "presentVerb",
person: T.Person.SecondSingMale,
voice: "active",
presObj: T.Person.ThirdSingFemale
})).toEqual({
hasBa: false,
vbs: [
[],
[
{
type: "welded",
left: {
type: "NComp",
comp: {
type: "AdjComp",
ps: { p: "ستړې", f: "stuRe" },
gender: "fem",
number: "singular",
},
},
right: {
type: "VB",
ps: [{ p: "کوې", f: "kawé" }],
},
person: T.Person.SecondSingMale,
},
],
],
});
}); });

View File

@ -17,20 +17,19 @@ import { isKawulVerb, isAbilityTense, isPerfectTense, isTlulVerb } from "../type
import { tenseHasBa } from "../phrase-building/vp-tools"; import { tenseHasBa } from "../phrase-building/vp-tools";
import { isPastTense } from "../phrase-building/vp-tools"; import { isPastTense } from "../phrase-building/vp-tools";
import { makePsString, removeFVarients } from "../accent-and-ps-utils"; import { makePsString, removeFVarients } from "../accent-and-ps-utils";
import { pashtoConsonants } from "../pashto-consonants";
import { getPastParticiple, getRootStem } from "./roots-and-stems"; import { getPastParticiple, getRootStem } from "./roots-and-stems";
import { getAspect, isKedul, perfectTenseToEquative, verbEndingConcat } from "./rs-helpers"; import { getAspect, isKedul, perfectTenseToEquative, verbEndingConcat } from "./rs-helpers";
import { accentOnNFromEnd, removeAccents } from "../accent-helpers";
// TODO: problem with laaR - no perfective split // TODO: problem with laaR - no perfective split
// TODO: automatic 3rd person idiosyncronizing of raTul raaTu, shaRul, shaaRu, rasedul rased etc // TODO: non past compounds with different object
// TODO: coverage of rs-helpers
// IMMEDIATE TODO: shwoo -> shoo export function renderVerb({ verb, tense, person, voice, presObj }: {
export function renderVerb({ verb, tense, person, voice }: {
verb: T.VerbEntry, verb: T.VerbEntry,
tense: T.VerbTense | T.PerfectTense | T.AbilityTense, // TODO: make T.Tense tense: T.VerbTense | T.PerfectTense | T.AbilityTense, // TODO: make T.Tense
person: T.Person, person: T.Person,
voice: T.Voice, voice: T.Voice,
presObj?: T.Person,
}): { }): {
hasBa: boolean, hasBa: boolean,
vbs: T.VerbRenderedOutput, vbs: T.VerbRenderedOutput,
@ -38,13 +37,14 @@ export function renderVerb({ verb, tense, person, voice }: {
if (isPerfectTense(tense)) { if (isPerfectTense(tense)) {
return renderPerfectVerb({ verb, tense, voice, person }); return renderPerfectVerb({ verb, tense, voice, person });
} }
const isPast = isPastTense(tense);
const rootPerson = isPast ? person : (presObj ?? person);
const hasBa = tenseHasBa(tense); const hasBa = tenseHasBa(tense);
const genderNumber = { const genderNumber = {
gender: personGender(person), gender: personGender(rootPerson),
number: personNumber(person), number: personNumber(rootPerson),
}; };
const isPast = isPastTense(tense);
const aspect = getAspect(tense); const aspect = getAspect(tense);
const type = isAbilityTense(tense) ? "ability" : "basic"; const type = isAbilityTense(tense) ? "ability" : "basic";
@ -134,19 +134,25 @@ function addEnding({ verb, rs, ending, person, pastThird, aspect, basicForm }: {
} }
function addToVBBasicEnd(vb: T.VBBasic, end: T.SingleOrLengthOpts<T.PsString[]>): T.VBBasic { function addToVBBasicEnd(vb: T.VBBasic, end: T.SingleOrLengthOpts<T.PsString[]>): T.VBBasic {
if ("long" in vb.ps) { if ("long" in vb.ps) {
if (vb.ps.short[0].f === "ghl" && pastThird && basicForm) {
return {
...vb,
ps: [{ p: "غی", f: "ghey" }],
};
}
const endLong = getLength(end, "long"); const endLong = getLength(end, "long");
const endShort = getLength(end, "short"); const endShort = getLength(end, "short");
// TODO: this is hacky // TODO: this is hackyۉ
const rsLong: T.PsString[] = vb.ps.long[0].f === "tlul"
? [{ p: "تلل", f: "tlúl" }]
: vb.ps.long;
return { return {
...vb, ...vb,
ps: { ps: {
long: verbEndingConcat(rsLong, endLong), long: verbEndingConcat(vb.ps.long, endLong),
short: pastThird && basicForm short: pastThird && basicForm
? ensure3rdPast(endShort, vb.ps.short, verb, aspect) ? ensure3rdPast(vb.ps.short, endShort, verb, aspect)
: verbEndingConcat(vb.ps.short, endShort), : verbEndingConcat(vb.ps.short, endShort),
...vb.ps.mini ? {
mini: verbEndingConcat(vb.ps.mini, endShort),
} : {},
}, },
}; };
} }
@ -171,8 +177,10 @@ function getEnding(person: T.Person, isPast: boolean) {
// TODO: THIS IS PROBABLY SKEEEETCH // TODO: THIS IS PROBABLY SKEEEETCH
function ensure3rdPast(rs: T.PsString[], ending: 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 === "شو") { if (isKedul(verb)) {
return [{ p: "شو", f: "sho" }]; return aspect === "perfective"
? [{ p: "شو", f: "sho" }]
: [{ p: "کېده", f: "kedú" }];
} }
if (isKawulVerb(verb) && rs[0].p === "کړ") { if (isKawulVerb(verb) && rs[0].p === "کړ") {
return [ return [
@ -182,30 +190,30 @@ function ensure3rdPast(rs: T.PsString[], ending: T.PsString[], verb: T.VerbEntry
]; ];
} }
if (isTlulVerb(verb)) { if (isTlulVerb(verb)) {
if (aspect === "perfective") { // should be imperfective at this point
return [{ p: "غی", f: "ghey" }]; // the perfective غی should already be covered in the function this is coming from
} return [{
const specialTuShort: T.PsString = {
p: rs[0].p.slice(0, -1) + "ه", p: rs[0].p.slice(0, -1) + "ه",
f: rs[0].f.slice(0, -1) + (rs[0].f === "tl" ? "u" : "ú"), f: rs[0].f.slice(0, -2) + "ú",
}; }];
return [
specialTuShort,
concatPsString(rs[0], { p: "و", f: "o" }),
];
} }
if (verb.entry.tppp && verb.entry.tppf) { if (verb.entry.tppp && verb.entry.tppf) {
const tip = makePsString(verb.entry.tppp, verb.entry.tppf) const tip = removeAccents(verb.entry.separationAtP !== undefined
? makePsString(verb.entry.tppp.slice(verb.entry.separationAtP), verb.entry.tppf.slice(verb.entry.separationAtF))
: makePsString(verb.entry.tppp, verb.entry.tppf));
const aTip = aspect === "imperfective"
? accentOnNFromEnd(tip, 0)
: tip;
return [aTip];
// if it ends in a consonant, the special form will also have another // if it ends in a consonant, the special form will also have another
// variation ending with a ه - u // variation ending with a ه - u
const endsInAConsonant = (pashtoConsonants.includes(tip.p.slice(-1)) || tip.f.slice(-1) === "w"); // const endsInAConsonant = (pashtoConsonants.includes(tip.p.slice(-1)) || tip.f.slice(-1) === "w");
return [ // return [
tip, // aTip,
...endsInAConsonant ? [ // ...endsInAConsonant ? [
concatPsString(tip, { p: "ه", f: "u" }), // ...verbEndingConcat([aTip], [{ p: "ه", f: "u" }, { p: "و", f: "o" }]),
concatPsString(tip, { p: "و", f: "o" }), // ] : [],
] : [], // ];
];
} }
const endsInAwul = ( const endsInAwul = (
(["awul", "awúl"].includes(removeFVarients(verb.entry.f).slice(-4))) (["awul", "awúl"].includes(removeFVarients(verb.entry.f).slice(-4)))
@ -215,12 +223,13 @@ function ensure3rdPast(rs: T.PsString[], ending: T.PsString[], verb: T.VerbEntry
// TODO: check about verbs like tawul (if they exist) // TODO: check about verbs like tawul (if they exist)
if (endsInAwul) { if (endsInAwul) {
const base = { p: rs[0].p.slice(0, -1), f: rs[0].f.slice(0, -2) }; const base = { p: rs[0].p.slice(0, -1), f: rs[0].f.slice(0, -2) };
return [concatPsString(base, { p: "اوه", f: "aawu" })]; const aawuEnd = concatPsString(base, { p: "اوه", f: base.f.charAt(base.f.length-1) === "a" ? "awu" : "aawu" });
return [aspect === "imperfective"
? accentOnNFromEnd(aawuEnd, 0)
: aawuEnd];
} }
const endsInDental = ["د", "ت"].includes(rs[0].p.slice(-1)); const endsInDental = ["د", "ت"].includes(rs[0].p.slice(-1));
// short endings like ورسېد // short endings like ورسېد
return (endsInDental ? [ const ends = endsInDental ? [{ p: "", f: "" }, ...ending] : ending;
"", return verbEndingConcat(rs, ends);
...ending,
] : ending).map(e => concatPsString(rs[0], e));
} }

View File

@ -42,6 +42,14 @@ const stureyKedul = vEntry(
{"ts":1591033069786,"i":7878,"p":"ستړی کېدل","f":"stuRey kedul","g":"stuReykedul","e":"to get tired, fatigued","r":4,"c":"v. stat. comp. intrans.","l":1527815306,"ec":"get","ep":"tired"}, {"ts":1591033069786,"i":7878,"p":"ستړی کېدل","f":"stuRey kedul","g":"stuReykedul","e":"to get tired, fatigued","r":4,"c":"v. stat. comp. intrans.","l":1527815306,"ec":"get","ep":"tired"},
{"ts":1527815306,"i":7876,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","r":4,"c":"adj. / adv."}, {"ts":1527815306,"i":7876,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","r":4,"c":"adj. / adv."},
); );
const bayaanedul = vEntry(
{"ts":1659037345120,"i":2055,"p":"بیانېدل","f":"bayaanedúl","g":"bayaanedul","e":"to be described, told, narrated, explained, declared","r":4,"c":"v. stat. comp. intrans.","l":1527814259},
{"ts":1527814259,"i":2052,"p":"بیان","f":"bayáan","g":"bayaan","e":"description, statement, speaking, narration, sermon","r":4,"c":"n. m.","app":"بیانات","apf":"bayaanaat"},
);
const khufaKedul = vEntry(
{"ts":1577898920635,"i":5845,"p":"خفه کېدل","f":"khufa kedul","g":"khufakedul","e":"to become sad, grieved, annoyed, upset; to be choked, to suffocate","r":4,"c":"v. stat. comp. intrans.","l":1527812798,"ec":"become","ep":"sad"},
{"ts":1527812798,"i":5843,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","r":4,"c":"adj."},
);
const ooPH: T.PH= { type: "PH", ps: { p: "و", f: "óo" }}; const ooPH: T.PH= { type: "PH", ps: { p: "و", f: "óo" }};
@ -440,6 +448,26 @@ describe("perfective stems", () => {
}, },
], ],
}, },
{
title: "has a perfective head from kawul dynamic",
tests: [
{
verb: kawulDyn,
result: [
[ooPH],
[
{
type: "VB",
ps: {
long: [{ p: "کړ", f: "kR" }],
short: [{ p: "ک", f: "k" }],
},
},
],
],
},
],
},
{ {
title: "irregular, inflecting stem for tlul", title: "irregular, inflecting stem for tlul",
tests: [ tests: [
@ -550,6 +578,52 @@ describe("perfective stems", () => {
], ],
], ],
}, },
// noun complements don't inflect
{
verb: bayaanedul,
genderNumber: { gender: "fem", number: "plural" },
result: [
[
{
type: "NComp",
comp: {
type: "Comp",
ps: { p: "بیان", f: "bayáan" },
},
},
],
[
{
type: "VB",
ps: [{ p: "ش", f: "sh" }],
},
],
],
},
// some adjectives can't inflect
{
verb: khufaKedul,
genderNumber: { gender: "fem", number: "plural" },
result: [
[
{
type: "NComp",
comp: {
type: "AdjComp",
ps: { p: "خفه", f: "khufa" },
gender: "fem",
number: "plural",
},
},
],
[
{
type: "VB",
ps: [{ p: "ش", f: "sh" }],
},
],
],
},
], ],
}, },
{ {
@ -743,6 +817,27 @@ describe("perfective roots", () => {
}, },
], ],
}, },
{
title: "has a perfective head from kawul dynamic",
tests: [
{
verb: kawulDyn,
result: [
[ooPH],
[
{
type: "VB",
ps: {
long: [{ p: "کړل", f: "kRul" }],
short: [{ p: "کړ", f: "kR" }],
mini: [{ p: "ک", f: "k" }],
},
},
],
],
},
],
},
{ {
title: "broken apart with complement seperately in the perfective", title: "broken apart with complement seperately in the perfective",
tests: [ tests: [
@ -1539,5 +1634,56 @@ describe("passive roots and stems", () => {
}, },
], ],
]); ]);
expect(getRootStem({
verb: stureyKawul,
aspect: "imperfective",
type: "basic",
voice: "passive",
genderNumber: {
gender: "masc",
number: "singular",
},
rs: "stem",
})).toEqual([
[],
[
{
"type": "welded",
"left": {
"type": "welded",
"left": {
"type": "NComp",
"comp": {
"type": "AdjComp",
"ps": {
"p": "ستړی",
"f": "stuRey"
},
"gender": "masc",
"number": "singular"
}
},
"right": {
"type": "VB",
"ps": [
{
"p": "کول",
"f": "kawul"
}
]
}
},
"right": {
"type": "VB",
"ps": [
{
"p": "کېږ",
"f": "kéG"
}
]
},
}
]
]);
}); });
}); });

View File

@ -77,7 +77,6 @@ function getAbilityRs(
]; ];
} }
// TODO: kuRee shuwey etc
export function getPastParticiple(verb: T.VerbEntry, voice: T.Voice, { gender, number }: { gender: T.Gender, number: T.NounNumber }): T.VBGenNum | T.WeldedGN { export function getPastParticiple(verb: T.VerbEntry, voice: T.Voice, { gender, number }: { gender: T.Gender, number: T.NounNumber }): T.VBGenNum | T.WeldedGN {
const v = removeFVarientsFromVerb(verb); const v = removeFVarientsFromVerb(verb);
if (voice === "passive") { if (voice === "passive") {

View File

@ -2,7 +2,6 @@ import * as T from "../../../types";
import { removeFVarients } from "../accent-and-ps-utils"; import { removeFVarients } from "../accent-and-ps-utils";
import { accentOnNFromEnd, accentPsSyllable, countSyllables, removeAccents, removeAccentsWLength } from "../accent-helpers"; import { accentOnNFromEnd, accentPsSyllable, countSyllables, removeAccents, removeAccentsWLength } from "../accent-helpers";
import { concatPsString, isUnisexSet, psStringFromEntry, trimOffPs } from "../p-text-helpers"; import { concatPsString, isUnisexSet, psStringFromEntry, trimOffPs } from "../p-text-helpers";
import { getRootStem } from "./roots-and-stems";
import { inflectPattern1 } from "./new-inflectors"; import { inflectPattern1 } from "./new-inflectors";
import { getLength } from "../p-text-helpers"; import { getLength } from "../p-text-helpers";
import { equativeEndings } from "../grammar-units"; import { equativeEndings } from "../grammar-units";
@ -56,27 +55,27 @@ export function vEntry(e: any, c?: any): T.VerbEntryNoFVars {
} as T.VerbEntryNoFVars; } as T.VerbEntryNoFVars;
} }
export function getAllRs(verb: T.VerbEntry): { // export function getAllRs(verb: T.VerbEntry): {
stem: { // stem: {
perfective: T.RootsStemsOutput, // perfective: T.RootsStemsOutput,
imperfective: T.RootsStemsOutput, // imperfective: T.RootsStemsOutput,
}, // },
root: { // root: {
perfective: T.RootsStemsOutput, // perfective: T.RootsStemsOutput,
imperfective: T.RootsStemsOutput, // imperfective: T.RootsStemsOutput,
}, // },
} { // } {
return { // return {
stem: { // stem: {
perfective: getRootStem({ verb, type: "basic", voice: "active", rs: "stem", aspect: "perfective", 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" } }), // imperfective: getRootStem({ verb, type: "basic", voice: "active", rs: "stem", aspect: "imperfective", genderNumber: { gender: "masc", number: "singular" } }),
}, // },
root: { // root: {
perfective: getRootStem({ verb, type: "basic", voice: "active", rs: "root", aspect: "perfective", 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" } }), // imperfective: getRootStem({ verb, type: "basic", voice: "active", rs: "root", aspect: "imperfective", genderNumber: { gender: "masc", number: "singular" } }),
}, // },
}; // };
} // }
/** /**
* adds a verb ending, creating all the variations with a set of root psStrings * adds a verb ending, creating all the variations with a set of root psStrings
@ -87,18 +86,16 @@ export function getAllRs(verb: T.VerbEntry): {
* @returns * @returns
*/ */
export function verbEndingConcat(ps: T.PsString[], end: T.PsString[]): T.PsString[] { export function verbEndingConcat(ps: T.PsString[], end: T.PsString[]): T.PsString[] {
if (ps[0].f === "shw") { if (ps[0].f === "shw" && end[0].f === "oo") {
if (end[1]?.f === "o") { return [{ p: "شو", f: "shoo" }];
return [{ p: "شو", f: "sho" }];
}
if (end[0].f === "oo") {
return [{ p: "شو", f: "oo" }];
}
} }
return ps.flatMap(v => ( return ps.flatMap(v => (
end.map(e => { end.map(e => {
if (v.f.charAt(v.f.length-1) === "X") { if (v.f.charAt(v.f.length-1) === "X") {
return concatPsString(trimOffPs(v, 0, 1), accentPsSyllable(e)) // faster to do concatPsString(trimOffPs(v, 0, 1), accentSyllable(e))
// but this covers cases like adding the 3rd person no-ending to a string with the
// trailing accent marker and still getting the accent right
return accentOnNFromEnd(concatPsString(trimOffPs(v, 0, 1), e), 0);
} }
if (e.p === "ل" && ["ul", "úl"].includes(v.f.slice(-2))) { if (e.p === "ل" && ["ul", "úl"].includes(v.f.slice(-2))) {
return v; return v;
@ -199,14 +196,15 @@ export function addAbilityEnding(vb: T.VBA): T.VBA {
if (vb.type === "welded") { if (vb.type === "welded") {
return { return {
...vb, ...vb,
right: addToVBBasicEnd(vb.right, abilityEnding), right: addToEnd(vb.right, abilityEnding),
}; };
} }
return addToVBBasicEnd(vb, abilityEnding); return addToEnd(vb, abilityEnding);
} function addToEnd(vb: T.VBBasic, end: T.PsString[]): T.VBBasic {
/* istanbul ignore next */
export function addToVBBasicEnd(vb: T.VBBasic, end: T.PsString[]): T.VBBasic { if (!("long" in vb.ps)) {
if ("long" in vb.ps) { throw new Error("should have long and short form for adding to ability ending");
}
return { return {
...vb, ...vb,
ps: { ps: {
@ -215,17 +213,16 @@ export function addToVBBasicEnd(vb: T.VBBasic, end: T.PsString[]): T.VBBasic {
}, },
}; };
} }
return {
...vb,
ps: verbEndingConcat(vb.ps, end),
};
} }
export function possiblePPartLengths(vba: T.VBNoLenghts<T.VBBasic>): T.VBBasic; export function possiblePPartLengths(vba: T.VBNoLenghts<T.VBBasic>): T.VBBasic;
export function possiblePPartLengths(vba: T.VBNoLenghts<T.VBA>): T.VBA; export function possiblePPartLengths(vba: T.VBNoLenghts<T.VBA>): T.VBA;
export function possiblePPartLengths(vba: T.VBNoLenghts<T.VBA>): T.VBA { export function possiblePPartLengths(vba: T.VBNoLenghts<T.VBA>): T.VBA {
const shortenableEndings = ["ښتل", "ستل", "وتل"]; const shortenableEndings = ["ښتل", "ستل", "وتل"];
const wrul = ["وړل", "راوړل", "وروړل", "دروړل"]; const wrul = ["وړل", "راوړل", "وروړل", "دروړل"];
// can't find a case where this is used - type safety
/* istanbul ignore next */
if ("right" in vba) { if ("right" in vba) {
return { return {
...vba, ...vba,
@ -302,5 +299,7 @@ export function perfectTenseToEquative(t: T.PerfectTense): keyof typeof equative
? "pastSubjunctive" ? "pastSubjunctive"
: t === "wouldBePerfect" : t === "wouldBePerfect"
? "past" ? "past"
: "subjunctive" : t === "wouldHaveBeenPerfect"
? "pastSubjunctive"
: "subjunctive";
} }

View File

@ -199,7 +199,7 @@ export function isPastTense(tense: T.Tense): boolean {
} }
export function tenseHasBa(tense: T.VerbTense | T.PerfectTense | T.AbilityTense | T.ImperativeTense): boolean { export function tenseHasBa(tense: T.VerbTense | T.PerfectTense | T.AbilityTense | T.ImperativeTense): boolean {
return [ const withBa: Parameters<typeof tenseHasBa>[0][] = [
"imperfectiveFuture", "imperfectiveFuture",
"perfectiveFuture", "perfectiveFuture",
"habitualPerfectivePast", "habitualPerfectivePast",
@ -210,8 +210,9 @@ export function tenseHasBa(tense: T.VerbTense | T.PerfectTense | T.AbilityTense
"habitualImperfectivePastModal", "habitualImperfectivePastModal",
"futurePerfect", "futurePerfect",
"wouldBePerfect", "wouldBePerfect",
"wouldBeHaveBeenPerfect", "wouldHaveBeenPerfect",
].includes(tense); ];
return withBa.includes(tense);
} }
export function removeDuplicates(psv: T.PsString[]): T.PsString[] { export function removeDuplicates(psv: T.PsString[]): T.PsString[] {