working on new roots and stems getter to replace verbInfo
This commit is contained in:
parent
3eb630a7b7
commit
1658f021a0
|
@ -28,8 +28,8 @@ function AllTensesDisplay({ VS, opts }: { VS: T.VerbSelection, opts: T.TextOptio
|
||||||
: ("transitive" in rawConjugations)
|
: ("transitive" in rawConjugations)
|
||||||
? rawConjugations[VS.transitivity === "grammatically transitive" ? "grammaticallyTransitive" : "transitive"]
|
? rawConjugations[VS.transitivity === "grammatically transitive" ? "grammaticallyTransitive" : "transitive"]
|
||||||
: rawConjugations;
|
: rawConjugations;
|
||||||
function getTense(baseTense: T.VerbTense | T.PerfectTense | T.ImperativeTense): T.VerbTense | T.PerfectTense | T.ImperativeTense | T.ModalTense {
|
function getTense(baseTense: T.VerbTense | T.PerfectTense | T.ImperativeTense): T.VerbTense | T.PerfectTense | T.ImperativeTense | T.AbilityTense {
|
||||||
return VS.tenseCategory === "modal" ? `${baseTense}Modal` as T.ModalTense : baseTense;
|
return VS.tenseCategory === "modal" ? `${baseTense}Modal` as T.AbilityTense : baseTense;
|
||||||
}
|
}
|
||||||
return <div>
|
return <div>
|
||||||
<div className="clickable mb-2 small text-center" onClick={() => setShowFormulas(x => !x)}>
|
<div className="clickable mb-2 small text-center" onClick={() => setShowFormulas(x => !x)}>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Select from "react-select";
|
import Select from "react-select";
|
||||||
import * as T from "../../../types";
|
import * as T from "../../../types";
|
||||||
import ButtonSelect from "../ButtonSelect";
|
import ButtonSelect from "../ButtonSelect";
|
||||||
import { isImperativeTense, isModalTense, isPerfectTense, isVerbTense } from "../../../lib/src/type-predicates";
|
import { isImperativeTense, isAbilityTense, isPerfectTense, isVerbTense } from "../../../lib/src/type-predicates";
|
||||||
import useStickyState from "../useStickyState";
|
import useStickyState from "../useStickyState";
|
||||||
import { customStyles } from "../EntrySelect";
|
import { customStyles } from "../EntrySelect";
|
||||||
import {
|
import {
|
||||||
|
@ -19,15 +19,15 @@ function composeFormula(formula: string, prefix: "passive" | "ability"): string
|
||||||
.replace("past participle", `${prefix} past participle`);
|
.replace("past participle", `${prefix} past participle`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRandomTense(o?: T.PerfectTense | T.VerbTense | T.ModalTense | T.ImperativeTense): T.PerfectTense | T.VerbTense | T.ModalTense | T.ImperativeTense {
|
export function getRandomTense(o?: T.PerfectTense | T.VerbTense | T.AbilityTense | T.ImperativeTense): T.PerfectTense | T.VerbTense | T.AbilityTense | T.ImperativeTense {
|
||||||
let tns: T.PerfectTense | T.VerbTense | T.ModalTense | T.ImperativeTense;
|
let tns: T.PerfectTense | T.VerbTense | T.AbilityTense | T.ImperativeTense;
|
||||||
const oldTenseCategory = !o
|
const oldTenseCategory = !o
|
||||||
? undefined
|
? undefined
|
||||||
: getTenseCategory(o);
|
: getTenseCategory(o);
|
||||||
const tenseOptions = oldTenseCategory === "perfect"
|
const tenseOptions = oldTenseCategory === "perfect"
|
||||||
? perfectTenseOptions
|
? perfectTenseOptions
|
||||||
: oldTenseCategory === "modal"
|
: oldTenseCategory === "modal"
|
||||||
? verbTenseOptions.map(x => ({ ...x, value: `${x.value}Modal` as T.ModalTense }))
|
? verbTenseOptions.map(x => ({ ...x, value: `${x.value}Modal` as T.AbilityTense }))
|
||||||
: oldTenseCategory === "imperative"
|
: oldTenseCategory === "imperative"
|
||||||
? imperativeTenseOptions
|
? imperativeTenseOptions
|
||||||
: verbTenseOptions;
|
: verbTenseOptions;
|
||||||
|
@ -238,14 +238,14 @@ function TensePicker(props: ({
|
||||||
|
|
||||||
export default TensePicker;
|
export default TensePicker;
|
||||||
|
|
||||||
function getTenseCategory(tense: T.VerbTense | T.PerfectTense | T.ModalTense | T.ImperativeTense): "basic" | "perfect" | "modal" | "imperative" {
|
function getTenseCategory(tense: T.VerbTense | T.PerfectTense | T.AbilityTense | T.ImperativeTense): "basic" | "perfect" | "modal" | "imperative" {
|
||||||
if (isPerfectTense(tense)) {
|
if (isPerfectTense(tense)) {
|
||||||
return "perfect";
|
return "perfect";
|
||||||
}
|
}
|
||||||
if (isVerbTense(tense)) {
|
if (isVerbTense(tense)) {
|
||||||
return "basic";
|
return "basic";
|
||||||
}
|
}
|
||||||
if (isModalTense(tense)) {
|
if (isAbilityTense(tense)) {
|
||||||
return "modal";
|
return "modal";
|
||||||
}
|
}
|
||||||
if (isImperativeTense(tense)) {
|
if (isImperativeTense(tense)) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import * as T from "../../../types";
|
||||||
|
|
||||||
function ChartDisplay({ conjugations, tense, opts, voice }: {
|
function ChartDisplay({ conjugations, tense, opts, voice }: {
|
||||||
conjugations: T.VerbConjugation,
|
conjugations: T.VerbConjugation,
|
||||||
tense: T.VerbTense | T.PerfectTense | T.ModalTense | T.ImperativeTense,
|
tense: T.VerbTense | T.PerfectTense | T.AbilityTense | T.ImperativeTense,
|
||||||
opts: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
voice: T.VerbSelection["voice"],
|
voice: T.VerbSelection["voice"],
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
randomNumber,
|
randomNumber,
|
||||||
} from "../lib/src/misc-helpers";
|
} from "../lib/src/misc-helpers";
|
||||||
import { entryFeeder } from "./entryFeeder";
|
import { entryFeeder } from "./entryFeeder";
|
||||||
import { renderVerb } from "../lib/src/render-verb";
|
import { renderVerb } from "../lib/src/new-verb-engine/render-verb";
|
||||||
import NPPronounPicker from "../components/src/np-picker/NPPronounPicker";
|
import NPPronounPicker from "../components/src/np-picker/NPPronounPicker";
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ const testPerfectTenses: T.PerfectTense[] = [
|
||||||
"pastSubjunctivePerfect",
|
"pastSubjunctivePerfect",
|
||||||
];
|
];
|
||||||
|
|
||||||
const testAbilityTenses: T.ModalTense[] = testVerbTenses.map<T.ModalTense>(t => `${t}Modal`);
|
const testAbilityTenses: T.AbilityTense[] = testVerbTenses.map<T.AbilityTense>(t => `${t}Modal`);
|
||||||
|
|
||||||
const testTenses = [
|
const testTenses = [
|
||||||
...testVerbTenses,
|
...testVerbTenses,
|
||||||
|
@ -76,7 +76,7 @@ function VPBuilderDemo({ opts }: {
|
||||||
person: 0,
|
person: 0,
|
||||||
}, "testPronoun");
|
}, "testPronoun");
|
||||||
const [testVoice, setTestVoice] = useStickyState<T.Voice>("active", "testVoice");
|
const [testVoice, setTestVoice] = useStickyState<T.Voice>("active", "testVoice");
|
||||||
const [testTense, setTestTense] = useStickyState<T.VerbTense | T.PerfectTense | T.ModalTense>("presentVerb", "testTense");
|
const [testTense, setTestTense] = useStickyState<T.VerbTense | T.PerfectTense | T.AbilityTense>("presentVerb", "testTense");
|
||||||
// const onlyGrammTrans = (arr: Transitivity[]) => (
|
// const onlyGrammTrans = (arr: Transitivity[]) => (
|
||||||
// arr.length === 1 && arr[0] === "grammatically transitive"
|
// arr.length === 1 && arr[0] === "grammatically transitive"
|
||||||
// );
|
// );
|
||||||
|
|
|
@ -10,10 +10,21 @@ export function makePsString(p: string, f: string): T.PsString {
|
||||||
return { p, f };
|
return { p, f };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function removeFVarientsFromVerb(v: T.VerbEntry): T.VerbEntryNoFVars {
|
||||||
|
const b = removeFVarients(v.entry);
|
||||||
|
return {
|
||||||
|
entry: b,
|
||||||
|
...v.complement ? {
|
||||||
|
complement: removeFVarients(v.complement),
|
||||||
|
} : {},
|
||||||
|
} as T.VerbEntryNoFVars;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeFVarients(x: T.VerbDictionaryEntry): T.VerbDictionaryEntryNoFVars;
|
||||||
export function removeFVarients(x: T.DictionaryEntry): T.DictionaryEntryNoFVars;
|
export function removeFVarients(x: T.DictionaryEntry): T.DictionaryEntryNoFVars;
|
||||||
export function removeFVarients(x: T.PsString): T.PsStringNoFVars;
|
export function removeFVarients(x: T.PsString): T.PsStringNoFVars;
|
||||||
export function removeFVarients(x: string): T.FStringNoFVars;
|
export function removeFVarients(x: string): T.FStringNoFVars;
|
||||||
export function removeFVarients(x: string | T.PsString | T.DictionaryEntry): T.FStringNoFVars | T.PsStringNoFVars | T.DictionaryEntryNoFVars {
|
export function removeFVarients(x: string | T.PsString | T.DictionaryEntry | T.VerbDictionaryEntry): T.FStringNoFVars | T.PsStringNoFVars | T.DictionaryEntryNoFVars | T.VerbDictionaryEntryNoFVars {
|
||||||
if (typeof x === "string") {
|
if (typeof x === "string") {
|
||||||
return x.split(",")[0] as T.FStringNoFVars;
|
return x.split(",")[0] as T.FStringNoFVars;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as T from "../../types";
|
import * as T from "../../types";
|
||||||
import {
|
import {
|
||||||
isModalTense,
|
isAbilityTense,
|
||||||
isPerfectTense,
|
isPerfectTense,
|
||||||
isImperativeTense,
|
isImperativeTense,
|
||||||
} from "./type-predicates";
|
} from "./type-predicates";
|
||||||
|
@ -24,7 +24,7 @@ function humanReadableVerbTense(tense: T.VerbTense): string {
|
||||||
: "habitual continuous past";
|
: "habitual continuous past";
|
||||||
}
|
}
|
||||||
|
|
||||||
function humanReadableModalTense(tense: T.ModalTense): string {
|
function humanReadableModalTense(tense: T.AbilityTense): string {
|
||||||
const base = tense.replace("Modal", "") as T.VerbTense;
|
const base = tense.replace("Modal", "") as T.VerbTense;
|
||||||
return `${humanReadableVerbTense(base)} ability`;
|
return `${humanReadableVerbTense(base)} ability`;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ function humanReadableImperativeTense(tense: T.ImperativeTense): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function humanReadableVerbForm(f: T.VerbFormName): string {
|
export function humanReadableVerbForm(f: T.VerbFormName): string {
|
||||||
return isModalTense(f)
|
return isAbilityTense(f)
|
||||||
? humanReadableModalTense(f)
|
? humanReadableModalTense(f)
|
||||||
: isPerfectTense(f)
|
: isPerfectTense(f)
|
||||||
? humanReadablePerfectTense(f)
|
? humanReadablePerfectTense(f)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as T from "../../types";
|
import * as T from "../../../types";
|
||||||
import { renderVerb } from "./render-verb";
|
import { renderVerb } from "./render-verb";
|
||||||
|
|
||||||
function vEntry(e: any, c?: any): T.VerbEntry {
|
export function vEntry(e: any, c?: any): T.VerbEntry {
|
||||||
return {
|
return {
|
||||||
entry: e,
|
entry: e,
|
||||||
...c ? {
|
...c ? {
|
||||||
|
@ -1214,7 +1214,7 @@ test("perfect simple verb forms", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("ability simple verb forms", () => {
|
test("ability simple verb forms", () => {
|
||||||
const tests: { verb: T.VerbEntry, tense: T.ModalTense, person: T.Person, output: ReturnType<typeof renderVerb> }[] = [
|
const tests: { verb: T.VerbEntry, tense: T.AbilityTense, person: T.Person, output: ReturnType<typeof renderVerb> }[] = [
|
||||||
{
|
{
|
||||||
tense: "presentVerbModal",
|
tense: "presentVerbModal",
|
||||||
verb: ganul,
|
verb: ganul,
|
||||||
|
@ -1625,7 +1625,7 @@ test("passive perfect simple verbs", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("passive ability simple verbs", () => {
|
test("passive ability simple verbs", () => {
|
||||||
const tests: { verb: T.VerbEntry, tense: T.ModalTense, person: T.Person, output: ReturnType<typeof renderVerb> }[] = [
|
const tests: { verb: T.VerbEntry, tense: T.AbilityTense, person: T.Person, output: ReturnType<typeof renderVerb> }[] = [
|
||||||
{
|
{
|
||||||
verb: ganul,
|
verb: ganul,
|
||||||
tense: "presentVerbModal",
|
tense: "presentVerbModal",
|
|
@ -1,47 +1,57 @@
|
||||||
import * as T from "../../types";
|
import * as T from "../../../types";
|
||||||
import {
|
import {
|
||||||
functionOnOptLengths,
|
functionOnOptLengths,
|
||||||
getPersonInflectionsKey,
|
getPersonInflectionsKey,
|
||||||
getVerbBlockPosFromPerson,
|
getVerbBlockPosFromPerson,
|
||||||
noPersInfs,
|
|
||||||
personGender,
|
personGender,
|
||||||
personIsPlural,
|
personIsPlural,
|
||||||
personNumber,
|
personNumber,
|
||||||
} from "./misc-helpers";
|
} from "../misc-helpers";
|
||||||
import {
|
import {
|
||||||
yulEndingInfinitive,
|
yulEndingInfinitive,
|
||||||
} from "./p-text-helpers";
|
} from "../p-text-helpers";
|
||||||
import {
|
import {
|
||||||
concatPsString,
|
concatPsString,
|
||||||
getLength,
|
getLength,
|
||||||
} from "./p-text-helpers";
|
} from "../p-text-helpers";
|
||||||
import {
|
import {
|
||||||
presentEndings,
|
presentEndings,
|
||||||
pastEndings,
|
pastEndings,
|
||||||
equativeEndings,
|
equativeEndings,
|
||||||
} from "./grammar-units";
|
} from "../grammar-units";
|
||||||
import { isKawulVerb, isModalTense, isPerfectTense, isTlulVerb } from "./type-predicates";
|
import { isKawulVerb, isAbilityTense, isPerfectTense, isTlulVerb } from "../type-predicates";
|
||||||
import { tenseHasBa } from "./phrase-building/vp-tools";
|
import { tenseHasBa } from "../phrase-building/vp-tools";
|
||||||
import { inflectYey } from "./pashto-inflector";
|
import { inflectYey } from "../pashto-inflector";
|
||||||
import {
|
import {
|
||||||
getVerbInfo,
|
getVerbInfo,
|
||||||
} from "./verb-info";
|
} from "../verb-info";
|
||||||
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 { pashtoConsonants } from "../pashto-consonants";
|
||||||
import { accentOnNFromEnd, removeAccents } from "./accent-helpers";
|
import { accentOnNFromEnd, removeAccents } from "../accent-helpers";
|
||||||
|
import { getRootStem as newGetRootStem } from "./roots-and-stems";
|
||||||
|
|
||||||
const kedulStatVerb: T.VerbEntry = {
|
const kedulStatVerb: T.VerbEntry = {
|
||||||
entry: {"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"} as T.VerbDictionaryEntry,
|
entry: {"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"} as T.VerbDictionaryEntry,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Amazingly, the basic formula with the roots and stems from the basic verbs
|
||||||
|
// works perfectly with stative compounds as well!
|
||||||
|
// The only issue is that if we want to include more information (complement noun gender etc) in the blocks
|
||||||
|
// we need to redo the stem building to have those parts
|
||||||
|
// 2 options:
|
||||||
|
// 1. redo the root/stem builder to output primitive blocks
|
||||||
|
// 2. rebuild the roots/stems in the verb engine
|
||||||
|
// Will start with number 2 and then if I go back and rebuild the root/stem builder
|
||||||
|
// We can go back to using a very simple verb building formula
|
||||||
|
|
||||||
// TODO: problem with laaR - no perfective split
|
// TODO: problem with laaR - no perfective split
|
||||||
// TODO: are azmóyulum and wáayulo really not just azmoyúlum and waayúlo ?
|
// TODO: are azmóyulum and wáayulo really not just azmoyúlum and waayúlo ?
|
||||||
// TODO: automatic 3rd person idiosyncronizing of raTul raaTu, shaRul, shaaRu, rasedul rased etc
|
// TODO: automatic 3rd person idiosyncronizing of raTul raaTu, shaRul, shaaRu, rasedul rased etc
|
||||||
|
|
||||||
export function renderVerb({ verb, tense, person, voice }: {
|
export function renderVerb({ verb, tense, person, voice }: {
|
||||||
verb: T.VerbEntry,
|
verb: T.VerbEntry,
|
||||||
tense: T.VerbTense | T.PerfectTense | T.ModalTense, // 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,
|
||||||
}): {
|
}): {
|
||||||
|
@ -52,25 +62,36 @@ export function renderVerb({ verb, tense, person, voice }: {
|
||||||
if (isPerfectTense(tense)) {
|
if (isPerfectTense(tense)) {
|
||||||
return getPerfectVBs({ verb, tense, person, voice });
|
return getPerfectVBs({ verb, tense, person, voice });
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasBa = tenseHasBa(tense);
|
const hasBa = tenseHasBa(tense);
|
||||||
const isPast = isPastTense(tense);
|
const isPast = isPastTense(tense);
|
||||||
const aspect = getAspect(tense);
|
const aspect = getAspect(tense);
|
||||||
const isAbility = isModalTense(tense);
|
const isAbility = isAbilityTense(tense);
|
||||||
const noPerfective = isAbility && (voice === "passive" || isTlulVerb(verb) || isKedul(verb));
|
const noPerfective = isAbility && (voice === "passive" || isTlulVerb(verb) || isKedul(verb));
|
||||||
|
// console.log(newGetRootStem({
|
||||||
|
// verb,
|
||||||
|
// part: {
|
||||||
|
// rs: isPast ? "root" : "stem",
|
||||||
|
// aspect,
|
||||||
|
// },
|
||||||
|
// type: "basic",
|
||||||
|
// person: undefined,
|
||||||
|
// }));
|
||||||
const { perfectiveHead, rootStem } = getRootStem({
|
const { perfectiveHead, rootStem } = getRootStem({
|
||||||
verb, aspect, isPast, isAbility, person, voice, noPerfective,
|
verb, aspect, isPast, isAbility, person, voice, noPerfective,
|
||||||
});
|
});
|
||||||
const verbBlocks: T.VB[] = isAbility
|
const verbBlocks: T.VB[] = isAbility
|
||||||
? getAbilityVerbBlocks({ isPast, person, root: rootStem, aspect, voice, noPerfective })
|
? getAbilityVerbBlocks({ isPast, person, root: rootStem, aspect, voice, noPerfective })
|
||||||
: voice === "passive"
|
: voice === "passive"
|
||||||
? getPassiveVerbBlocks({ root: rootStem, tense, person })
|
? getPassiveVerbBlocks({ root: rootStem, tense, person })
|
||||||
: getBasicVerbBlock({
|
: getBasicVerbBlock({
|
||||||
rootStem, person, isPast, verb, aspect,
|
rootStem, person, isPast, verb, aspect,
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
hasBa,
|
hasBa,
|
||||||
verbBlocks: [
|
verbBlocks: [
|
||||||
...!noPerfective && perfectiveHead ? [perfectiveHead] : [],
|
...(!noPerfective && perfectiveHead)
|
||||||
|
? [perfectiveHead] : [],
|
||||||
...verbBlocks,
|
...verbBlocks,
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -185,19 +206,19 @@ function getPerfectVBs({ verb, tense, person, voice }: {
|
||||||
voice: T.Voice,
|
voice: T.Voice,
|
||||||
}): { hasBa: boolean, verbBlocks: T.VB[] } {
|
}): { hasBa: boolean, verbBlocks: T.VB[] } {
|
||||||
const hasBa = tenseHasBa(tense);
|
const hasBa = tenseHasBa(tense);
|
||||||
const vInfo = getVerbInfo(verb.entry) as T.SimpleVerbInfo;
|
const vInfo = getVerbInfo(verb.entry, verb.complement) as T.SimpleVerbInfo;
|
||||||
|
|
||||||
if (voice === "passive") {
|
if (voice === "passive") {
|
||||||
const [pt, eq] = getKedulStatPerfect(person, tense);
|
const [pt, eq] = getKedulStatPerfect(person, tense);
|
||||||
const passiveRoot: T.VI = {
|
const passiveRoot: T.VI = {
|
||||||
type: "VI",
|
type: "VI",
|
||||||
ps: [noPersInfs(vInfo.root.imperfective).long],
|
ps: [fromPersInfls(vInfo.root.imperfective, person).long],
|
||||||
};
|
};
|
||||||
const welded: T.Welded = weld(passiveRoot, pt);
|
const welded: T.Welded = weld(passiveRoot, pt);
|
||||||
return {
|
return {
|
||||||
hasBa,
|
hasBa,
|
||||||
verbBlocks: [welded, eq],
|
verbBlocks: [welded, eq],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const equative = equativeEndings[perfectTenseToEquative(tense)];
|
const equative = equativeEndings[perfectTenseToEquative(tense)];
|
||||||
|
@ -215,7 +236,7 @@ function getPerfectVBs({ verb, tense, person, voice }: {
|
||||||
type: "PT",
|
type: "PT",
|
||||||
gender: personGender(person),
|
gender: personGender(person),
|
||||||
number: personNumber(person),
|
number: personNumber(person),
|
||||||
ps: chooseParticipleInflection(inflectYey(noPersInfs(vInfo.participle.past)), person)
|
ps: chooseParticipleInflection(inflectYey(fromPersInfls(vInfo.participle.past, person)), person)
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
hasBa,
|
hasBa,
|
||||||
|
@ -246,13 +267,13 @@ function getRootStem({ verb, aspect, isPast, isAbility, voice, person, noPerfect
|
||||||
perfectiveHead: undefined | T.PH,
|
perfectiveHead: undefined | T.PH,
|
||||||
rootStem: T.SingleOrLengthOpts<T.PsString>,
|
rootStem: T.SingleOrLengthOpts<T.PsString>,
|
||||||
} {
|
} {
|
||||||
const vInfo = getVerbInfo(verb.entry) as T.SimpleVerbInfo;
|
const vInfo = getVerbInfo(verb.entry, verb.complement) as T.SimpleVerbInfo;
|
||||||
const rs = vInfo[(isPast || isAbility || voice === "passive") ? "root" : "stem"];
|
const rs = vInfo[(isPast || isAbility || voice === "passive") ? "root" : "stem"];
|
||||||
if (noPerfective) {
|
if (noPerfective) {
|
||||||
// exception with tlul verbs for ability stems
|
// exception with tlul verbs for ability stems
|
||||||
return {
|
return {
|
||||||
perfectiveHead: undefined,
|
perfectiveHead: undefined,
|
||||||
rootStem: noPersInfs(rs.imperfective),
|
rootStem: fromPersInfls(rs.imperfective, person),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (aspect === "perfective" && rs.perfectiveSplit) {
|
if (aspect === "perfective" && rs.perfectiveSplit) {
|
||||||
|
@ -262,7 +283,7 @@ function getRootStem({ verb, aspect, isPast, isAbility, voice, person, noPerfect
|
||||||
perfectiveHead: undefined,
|
perfectiveHead: undefined,
|
||||||
// because the persInfs only happen with stative compound verbs,j
|
// because the persInfs only happen with stative compound verbs,j
|
||||||
// which we are handling differently now
|
// which we are handling differently now
|
||||||
rootStem: noPersInfs(rs[aspect]),
|
rootStem: fromPersInfls(rs[aspect], person),
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractPerfectiveSplit(splitInfo: T.SplitInfo): ReturnType<typeof getRootStem> {
|
function extractPerfectiveSplit(splitInfo: T.SplitInfo): ReturnType<typeof getRootStem> {
|
||||||
|
@ -438,7 +459,7 @@ function ensure3rdPast(ending: T.PsString[], rs: T.PsString, verb: T.VerbEntry,
|
||||||
] : ending).map(e => concatPsString(rs, e));
|
] : ending).map(e => concatPsString(rs, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAspect(tense: T.VerbTense | T.ModalTense): T.Aspect {
|
function getAspect(tense: T.VerbTense | T.AbilityTense): T.Aspect {
|
||||||
const t = tense.replace("Modal", "");
|
const t = tense.replace("Modal", "");
|
||||||
if (["presentVerb", "imperfectiveFuture", "imperfectivePast", "habitualImperfectivePast"].includes(t)) {
|
if (["presentVerb", "imperfectiveFuture", "imperfectivePast", "habitualImperfectivePast"].includes(t)) {
|
||||||
return "imperfective";
|
return "imperfective";
|
|
@ -0,0 +1,181 @@
|
||||||
|
import * as T from "../../../types";
|
||||||
|
import { getRootStem } from "./roots-and-stems";
|
||||||
|
import { vEntry } from "./render-verb.test";
|
||||||
|
import { ooPrefix } from "./roots-and-stems";
|
||||||
|
|
||||||
|
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 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 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 kawulDyn = vEntry({"ts":1527812752,"i":11031,"p":"کول","f":"kawul","g":"kawul","e":"to do (an action or activity)","r":4,"c":"v. trans./gramm. trans.","ssp":"وکړ","ssf":"óokR","prp":"وکړل","prf":"óokRul","pprtp":"کړی","pprtf":"kúRey","diacExcept":true,"ec":"do,does,doing,did,done"});
|
||||||
|
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 kedulDyn = vEntry({"ts":1527812754,"i":11101,"p":"کېدل","f":"kedul","g":"kedul","e":"to happen, occur","r":2,"c":"v. intrans.","ssp":"وش","ssf":"óosh","prp":"وشول","prf":"óoshwul","pprtp":"شوی","pprtf":"shúwey","diacExcept":true,"ec":"happen"});
|
||||||
|
const raatlul = vEntry({"ts":1527815216,"i":6875,"p":"راتلل","f":"raatlúl","g":"raatlul","e":"to come","r":4,"c":"v. intrans.","psp":"راځ","psf":"raadz","ssp":"راش","ssf":"ráash","prp":"راغلل","prf":"ráaghlul","pprtp":"راغلی","pprtf":"raaghúley","tppp":"راغی","tppf":"ráaghey","noOo":true,"separationAtP":2,"separationAtF":3,"ec":"come,comes,coming,came,come"});
|
||||||
|
const wartlul = vEntry({"ts":1585228579997,"i":14821,"p":"ورتلل","f":"wărtlul","g":"wartlul","e":"to come / go over to (third person or place)","r":4,"c":"v. intrans.","psp":"ورځ","psf":"wărdz","ssp":"ورش","ssf":"wársh","prp":"ورغلل","prf":"wárghlul","pprtp":"ورغلی","pprtf":"wărghúley","tppp":"ورغی","tppf":"wărghey","noOo":true,"separationAtP":2,"separationAtF":3,"ec":"come,comes,coming,came,come"});
|
||||||
|
const tlul = vEntry({"ts":1527815348,"i":3791,"p":"تلل","f":"tlul","g":"tlul","e":"to go","r":4,"c":"v. intrans.","psp":"ځ","psf":"dz","ssp":"لاړ ش","ssf":"láaR sh","prp":"لاړ","prf":"láaR","ec":"go,goes,going,went,gone"});
|
||||||
|
const awuxtul = vEntry({"ts":1527814012,"i":1133,"p":"اوښتل","f":"awUxtul","g":"awUxtul","e":"to pass over, overturn, be flipped over, spill over, shift, change, diverge, pass, cross, abandon; to be sprained","r":4,"c":"v. intrans.","psp":"اوړ","psf":"awR","ec":"pass","ep":"over"});
|
||||||
|
const khorul = vEntry({"ts":1527812790,"i":6002,"p":"خوړل","f":"khoRul","g":"khoRul","e":"to eat, to bite","r":4,"c":"v. trans.","psp":"خور","psf":"khor","tppp":"خوړ","tppf":"khoR","ec":"eat,eats,eating,ate,eaten"});
|
||||||
|
const azmoyul = vEntry({"ts":1527811605,"i":468,"p":"ازمویل","f":"azmoyul","g":"azmoyul","e":"to attempt, try; to experiment, test","r":4,"c":"v. trans.","sepOo":true,"ec":"try"});
|
||||||
|
const khatul = vEntry({"ts":1527814025,"i":5677,"p":"ختل","f":"khatul","g":"khatul","e":"to climb, ascend, rise, go up; to fall out, to fall off, to leave/dissapear; to turn out to be ...; to give a sentence (in law)","r":3,"c":"v. intrans.","psp":"خېژ","psf":"khejz","tppp":"خوت","tppf":"khot","ec":"climb"});
|
||||||
|
const rasedul = vEntry({"ts":1527813573,"i":7057,"p":"رسېدل","f":"rasedul","g":"rasedul","e":"arrive, reach; (fig.) understand, attain to; mature, ripen","r":4,"c":"v. intrans.","shortIntrans":true,"ec":"arrive"});
|
||||||
|
const weshul = vEntry({"ts":1527811701,"i":15106,"p":"وېشل","f":"weshul","g":"weshul","e":"divide, distribute, share","r":4,"c":"v. trans.","ec":"divide"});
|
||||||
|
|
||||||
|
type RSO = ReturnType<typeof getRootStem>;
|
||||||
|
function getAllRs(verb: T.VerbEntry): (typeof regularVerbs)[0]["result"] {
|
||||||
|
return {
|
||||||
|
stem: {
|
||||||
|
perfective: getRootStem({ verb, type: "basic", part: { rs: "stem", aspect: "perfective" }, person: undefined }),
|
||||||
|
imperfective: getRootStem({ verb, type: "basic", part: { rs: "stem", aspect: "imperfective" }, person: undefined }),
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
perfective: getRootStem({ verb, type: "basic", part: { rs: "root", aspect: "perfective" }, person: undefined }),
|
||||||
|
imperfective: getRootStem({ verb, type: "basic", part: { rs: "root", aspect: "imperfective" }, person: undefined }),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const regularVerbs: {
|
||||||
|
verb: T.VerbEntry,
|
||||||
|
result: Record<"stem" | "root", {
|
||||||
|
imperfective: RSO,
|
||||||
|
perfective: RSO,
|
||||||
|
}>
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
verb: weshul,
|
||||||
|
result: {
|
||||||
|
stem: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
[{ p: "وېش", f: "wesh" }],
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
[{ p: "وېش", f: "wesh" }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
{
|
||||||
|
long: [{ p: "وېشل", f: "weshul" }],
|
||||||
|
short: [{ p: "وېش", f: "wesh" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
{
|
||||||
|
long: [{ p: "وېشل", f: "weshúl" }],
|
||||||
|
short: [{ p: "وېش", f: "weshX" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
verb: ganul,
|
||||||
|
result: {
|
||||||
|
stem: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
[{ p: "ګڼ", f: "gaN" }],
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
[{ p: "ګڼ", f: "gaN" }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
{
|
||||||
|
long: [{ p: "ګڼل", f: "gaNul" }],
|
||||||
|
short: [{ p: "ګڼ", f: "gaN" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
{
|
||||||
|
long: [{ p: "ګڼل", f: "gaNúl" }],
|
||||||
|
short: [{ p: "ګڼ", f: "gaNX" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const verbsWithIrregularStems: {
|
||||||
|
verb: T.VerbEntry,
|
||||||
|
result: Record<"stem" | "root", {
|
||||||
|
imperfective: RSO,
|
||||||
|
perfective: RSO,
|
||||||
|
}>
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
verb: khorul,
|
||||||
|
result: {
|
||||||
|
stem: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
[{ p: "خور", f: "khor" }],
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
[{ p: "خور", f: "khor" }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
{
|
||||||
|
long: [{ p: "خوړل", f: "khoRul" }],
|
||||||
|
short: [{ p: "خوړ", f: "khoR" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
{
|
||||||
|
long: [{ p: "خوړل", f: "khoRúl" }],
|
||||||
|
short: [{ p: "خوړ", f: "khoRX" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
verb: khatul,
|
||||||
|
result: {
|
||||||
|
stem: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
[{ p: "خېژ", f: "khejz" }],
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
[{ p: "خېژ", f: "khejz" }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
perfective: [
|
||||||
|
ooPrefix,
|
||||||
|
{
|
||||||
|
long: [{ p: "ختل", f: "khatul" }],
|
||||||
|
short: [{ p: "خت", f: "khat" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
imperfective: [
|
||||||
|
{
|
||||||
|
long: [{ p: "ختل", f: "khatúl" }],
|
||||||
|
short: [{ p: "خت", f: "khatX" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
test("basic roots and stems with regular verbs", () => {
|
||||||
|
regularVerbs.forEach(({ verb, result }) => {
|
||||||
|
expect(getAllRs(verb)).toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("baisc roots and stems with verbs with irregular stems", () => {
|
||||||
|
verbsWithIrregularStems.forEach(({ verb, result }) => {
|
||||||
|
expect(getAllRs(verb)).toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2023 lingdocs.com
|
||||||
|
*
|
||||||
|
* This source code is licensed under the GPL3 license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
concatPsString,
|
||||||
|
} from "../p-text-helpers";
|
||||||
|
import * as T from "../../../types";
|
||||||
|
import { makePsString, removeFVarientsFromVerb } from "../accent-and-ps-utils";
|
||||||
|
import { accentOnNFromEnd, removeAccents } from "../accent-helpers";
|
||||||
|
|
||||||
|
type RootStemOutput = (T.PH | T.SingleOrLengthOpts<T.PsString[]>)[];
|
||||||
|
|
||||||
|
export const ooPrefix: T.PH = {
|
||||||
|
type: "PH",
|
||||||
|
ps: { p: "و", f: "óo" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getRootStem({ verb, part, type, person }: {
|
||||||
|
verb: T.VerbEntry,
|
||||||
|
part: {
|
||||||
|
rs: "root" | "stem",
|
||||||
|
aspect: T.Aspect,
|
||||||
|
} | {
|
||||||
|
participle: "present" | "past",
|
||||||
|
},
|
||||||
|
type: "basic" | "ability" | "passive",
|
||||||
|
person: {
|
||||||
|
gender: T.Gender,
|
||||||
|
number: T.NounNumber,
|
||||||
|
} | undefined,
|
||||||
|
}): RootStemOutput {
|
||||||
|
const v = removeFVarientsFromVerb(verb);
|
||||||
|
if ("participle" in part) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (part.rs === "stem") {
|
||||||
|
return getStem(v, part.aspect);
|
||||||
|
} else {
|
||||||
|
return getRoot(v, part.aspect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoot(verb: T.VerbEntryNoFVars, aspect: T.Aspect): RootStemOutput {
|
||||||
|
if (aspect === "imperfective") {
|
||||||
|
const infinitive = accentOnNFromEnd(makePsString(verb.entry.p, verb.entry.f), 0);
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
long: [infinitive],
|
||||||
|
short: [addTrailingAccent(removeL(infinitive))],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (aspect === "perfective") {
|
||||||
|
const base = removeAccents(
|
||||||
|
(verb.entry.prp && verb.entry.prf)
|
||||||
|
? makePsString(verb.entry.prp, verb.entry.prf)
|
||||||
|
: makePsString(verb.entry.p, verb.entry.f)
|
||||||
|
);
|
||||||
|
// TODO: determine ph and base
|
||||||
|
return [
|
||||||
|
ooPrefix,
|
||||||
|
{
|
||||||
|
long: [base],
|
||||||
|
short: [removeL(base)],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
throw new Error("unknown aspect");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStem(verb: T.VerbEntryNoFVars, aspect: T.Aspect): RootStemOutput {
|
||||||
|
if (aspect === "imperfective") {
|
||||||
|
const base = (verb.entry.psp && verb.entry.psf)
|
||||||
|
// with irregular imperfective stem
|
||||||
|
? makePsString(verb.entry.psp, verb.entry.psf)
|
||||||
|
// with regular infinitive based imperfective stem
|
||||||
|
: removeL(makePsString(verb.entry.p, verb.entry.f));
|
||||||
|
return [
|
||||||
|
[base],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (aspect === "perfective") {
|
||||||
|
const base = (verb.entry.ssp && verb.entry.ssf)
|
||||||
|
// with irregular perfective stem
|
||||||
|
? makePsString(verb.entry.ssp, verb.entry.ssf)
|
||||||
|
: (verb.entry.psp && verb.entry.psf)
|
||||||
|
// with perfective stem based on irregular perfective root
|
||||||
|
? makePsString(verb.entry.psp, verb.entry.psf)
|
||||||
|
// with regular infinitive based perfective stem
|
||||||
|
: removeL(makePsString(verb.entry.p, verb.entry.f));
|
||||||
|
// TODO: determine ph and base
|
||||||
|
return [
|
||||||
|
ooPrefix,
|
||||||
|
[base],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
p: ps.p.slice(0, -1),
|
||||||
|
f: ps.f.slice(0, -2),
|
||||||
|
};
|
||||||
|
}
|
|
@ -88,7 +88,7 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
const modalBuilders: Record<
|
const modalBuilders: Record<
|
||||||
T.ModalTense,
|
T.AbilityTense,
|
||||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||||
> = {
|
> = {
|
||||||
presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
|
@ -215,7 +215,7 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
||||||
]),
|
]),
|
||||||
}
|
}
|
||||||
const passiveModalBuilders: Record<
|
const passiveModalBuilders: Record<
|
||||||
T.ModalTense,
|
T.AbilityTense,
|
||||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||||
> = {
|
> = {
|
||||||
presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {
|
||||||
isAdjectiveEntry,
|
isAdjectiveEntry,
|
||||||
isImperativeTense,
|
isImperativeTense,
|
||||||
isLocativeAdverbEntry,
|
isLocativeAdverbEntry,
|
||||||
isModalTense,
|
isAbilityTense,
|
||||||
isNounEntry,
|
isNounEntry,
|
||||||
isPattern4Entry,
|
isPattern4Entry,
|
||||||
isPerfectTense,
|
isPerfectTense,
|
||||||
|
@ -505,7 +505,7 @@ export function isStativeHelper(v: T.VerbEntry): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
function splitUpIfModal(v: T.VerbRenderedBlock): [T.VerbRenderedBlock] | [T.ModalVerbBlock, T.ModalVerbKedulPart] {
|
function splitUpIfModal(v: T.VerbRenderedBlock): [T.VerbRenderedBlock] | [T.ModalVerbBlock, T.ModalVerbKedulPart] {
|
||||||
if (!isModalTense(v.block.tense)) {
|
if (!isAbilityTense(v.block.tense)) {
|
||||||
return [v];
|
return [v];
|
||||||
}
|
}
|
||||||
const [vrb, k] = splitOffLeapfrogWordFull(v.block.ps);
|
const [vrb, k] = splitOffLeapfrogWordFull(v.block.ps);
|
||||||
|
@ -561,8 +561,8 @@ function getPsVerbConjugation(conj: T.VerbConjugation, vs: T.VerbSelectionComple
|
||||||
const hasBa = hasBaParticle(getLong(verbForm)[0]);
|
const hasBa = hasBaParticle(getLong(verbForm)[0]);
|
||||||
if (perfective) {
|
if (perfective) {
|
||||||
const past = isPastTense(vs.tense);
|
const past = isPastTense(vs.tense);
|
||||||
const splitInfo = conj.info[(past || isModalTense(vs.tense)) ? "root" : "stem"].perfectiveSplit;
|
const splitInfo = conj.info[(past || isAbilityTense(vs.tense)) ? "root" : "stem"].perfectiveSplit;
|
||||||
if (!splitInfo || (isTlulVerb(vs.verb.entry) && isModalTense(vs.tense))) {
|
if (!splitInfo || (isTlulVerb(vs.verb.entry) && isAbilityTense(vs.tense))) {
|
||||||
return { ps: { head: undefined, rest: removeBaFromForm(verbForm) }, hasBa };
|
return { ps: { head: undefined, rest: removeBaFromForm(verbForm) }, hasBa };
|
||||||
}
|
}
|
||||||
// TODO: Either solve this in the inflector or here, it seems silly (or redundant)
|
// TODO: Either solve this in the inflector or here, it seems silly (or redundant)
|
||||||
|
|
|
@ -38,7 +38,7 @@ export function isInvalidSubjObjCombo(subj: T.Person, obj: T.Person): boolean {
|
||||||
*/
|
*/
|
||||||
export function getTenseVerbForm(
|
export function getTenseVerbForm(
|
||||||
conjR: T.VerbConjugation,
|
conjR: T.VerbConjugation,
|
||||||
tense: T.VerbTense | T.PerfectTense | T.ModalTense | T.ImperativeTense,
|
tense: T.VerbTense | T.PerfectTense | T.AbilityTense | T.ImperativeTense,
|
||||||
voice: "active" | "passive",
|
voice: "active" | "passive",
|
||||||
mode: "charts" | "phrase-building",
|
mode: "charts" | "phrase-building",
|
||||||
negative: boolean,
|
negative: boolean,
|
||||||
|
@ -152,8 +152,8 @@ export function removeBa(ps: T.PsString): T.PsString {
|
||||||
return psRemove(ps, concatPsString(grammarUnits.baParticle, " "));
|
return psRemove(ps, concatPsString(grammarUnits.baParticle, " "));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTenseFromVerbSelection(vs: T.VerbSelection): T.VerbTense | T.PerfectTense | T.ModalTense | T.ImperativeTense {
|
export function getTenseFromVerbSelection(vs: T.VerbSelection): T.VerbTense | T.PerfectTense | T.AbilityTense | T.ImperativeTense {
|
||||||
function verbTenseToModalTense(tn: T.VerbTense): T.ModalTense {
|
function verbTenseToModalTense(tn: T.VerbTense): T.AbilityTense {
|
||||||
if (tn === "presentVerb") {
|
if (tn === "presentVerb") {
|
||||||
return "presentVerbModal";
|
return "presentVerbModal";
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ export function isPastTense(tense: T.Tense): boolean {
|
||||||
return tense.toLowerCase().includes("past");
|
return tense.toLowerCase().includes("past");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tenseHasBa(tense: T.VerbTense | T.PerfectTense | T.ModalTense | T.ImperativeTense): boolean {
|
export function tenseHasBa(tense: T.VerbTense | T.PerfectTense | T.AbilityTense | T.ImperativeTense): boolean {
|
||||||
return [
|
return [
|
||||||
"imperfectiveFuture",
|
"imperfectiveFuture",
|
||||||
"perfectiveFuture",
|
"perfectiveFuture",
|
||||||
|
|
|
@ -222,7 +222,7 @@ export function isVerbTense(tense: T.Tense): tense is T.VerbTense {
|
||||||
return verbTenses.some(x => x === tense);
|
return verbTenses.some(x => x === tense);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isModalTense(tense: T.Tense): tense is T.ModalTense {
|
export function isAbilityTense(tense: T.Tense): tense is T.AbilityTense {
|
||||||
return tense.endsWith("Modal");
|
return tense.endsWith("Modal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
35
src/types.ts
35
src/types.ts
|
@ -142,6 +142,11 @@ export type DictionaryEntry = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DictionaryEntryNoFVars = DictionaryEntry & { __brand: "name for a dictionary entry with all the phonetics variations removed" };
|
export type DictionaryEntryNoFVars = DictionaryEntry & { __brand: "name for a dictionary entry with all the phonetics variations removed" };
|
||||||
|
export type VerbDictionaryEntryNoFVars = VerbDictionaryEntry & { __brand2: "name for a verb dictionary entry with all the phonetics variations removed" };
|
||||||
|
export type VerbEntryNoFVars = {
|
||||||
|
entry: VerbDictionaryEntryNoFVars,
|
||||||
|
complement?: DictionaryEntryNoFVars,
|
||||||
|
} & { __brand: "name for a verb entry with all the phonetics variations removed" };
|
||||||
export type PsStringNoFVars = PsString & { __brand: "name for a ps string with all the phonetics variations removed" };
|
export type PsStringNoFVars = PsString & { __brand: "name for a ps string with all the phonetics variations removed" };
|
||||||
export type FStringNoFVars = string & { __brand: "name for a phonetics string with all the phonetics variations removed" };
|
export type FStringNoFVars = string & { __brand: "name for a phonetics string with all the phonetics variations removed" };
|
||||||
|
|
||||||
|
@ -612,9 +617,9 @@ export type NounNumber = "singular" | "plural";
|
||||||
|
|
||||||
export type EquativeTense = "present" | "subjunctive" | "habitual" | "past" | "future" | "wouldBe" | "pastSubjunctive" | "wouldHaveBeen";
|
export type EquativeTense = "present" | "subjunctive" | "habitual" | "past" | "future" | "wouldBe" | "pastSubjunctive" | "wouldHaveBeen";
|
||||||
export type PerfectTense = `${EquativeTense}Perfect`;
|
export type PerfectTense = `${EquativeTense}Perfect`;
|
||||||
export type ModalTense = `${VerbTense}Modal`;
|
export type AbilityTense = `${VerbTense}Modal`;
|
||||||
export type ImperativeTense = `${Aspect}Imperative`;
|
export type ImperativeTense = `${Aspect}Imperative`;
|
||||||
export type Tense = EquativeTense | VerbTense | PerfectTense | ModalTense | ImperativeTense;
|
export type Tense = EquativeTense | VerbTense | PerfectTense | AbilityTense | ImperativeTense;
|
||||||
|
|
||||||
export type SubjectSelection = {
|
export type SubjectSelection = {
|
||||||
type: "subjectSelection",
|
type: "subjectSelection",
|
||||||
|
@ -655,7 +660,7 @@ export type VPSelectionComplete = {
|
||||||
form: FormVersion,
|
form: FormVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type VerbFormName = VerbTense | PerfectTense | ModalTense | ImperativeTense;
|
export type VerbFormName = VerbTense | PerfectTense | AbilityTense | ImperativeTense;
|
||||||
|
|
||||||
export type VerbSelectionComplete = Omit<VerbSelection, "object" | "verbTense" | "perfectTense" | "imperativeTense" | "tenseCategory"> & {
|
export type VerbSelectionComplete = Omit<VerbSelection, "object" | "verbTense" | "perfectTense" | "imperativeTense" | "tenseCategory"> & {
|
||||||
tense: VerbFormName,
|
tense: VerbFormName,
|
||||||
|
@ -1075,6 +1080,9 @@ export type VB = PH | VA | VI | PT | EQ | Welded;
|
||||||
export type PH = {
|
export type PH = {
|
||||||
type: "PH",
|
type: "PH",
|
||||||
ps: PsString,
|
ps: PsString,
|
||||||
|
} | {
|
||||||
|
type: "PHComp",
|
||||||
|
comp: Comp,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** verb block with person agreement */
|
/** verb block with person agreement */
|
||||||
|
@ -1105,11 +1113,30 @@ export type EQ = {
|
||||||
person: Person,
|
person: Person,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Complement can be one of
|
||||||
|
// - adjective
|
||||||
|
// - locative adv
|
||||||
|
// - sandwich (TODO)
|
||||||
|
// - noun
|
||||||
|
/** complement block */
|
||||||
|
export type Comp = {
|
||||||
|
type: "AdjComp",
|
||||||
|
ps: PsString,
|
||||||
|
gender: Gender,
|
||||||
|
number: NounNumber,
|
||||||
|
} | {
|
||||||
|
type: "LocAdvComp",
|
||||||
|
ps: PsString,
|
||||||
|
} | {
|
||||||
|
type: "NounComp",
|
||||||
|
ps: PsString,
|
||||||
|
};
|
||||||
|
|
||||||
/** a veb block with a welded part having it's accents removed */
|
/** a veb block with a welded part having it's accents removed */
|
||||||
export type Welded = {
|
export type Welded = {
|
||||||
type: "welded",
|
type: "welded",
|
||||||
/** accents must be removed from the left */
|
/** accents must be removed from the left */
|
||||||
left: VI, // TODO - will get more complex with compounds
|
left: VI | Comp,
|
||||||
right: VA | PT | VI,
|
right: VA | PT | VI,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue