(false, "includeOSV");
- if (!isVPSelectionComplete(VP)) {
+ const VPComplete = completeVPSelection(VP);
+ if (!VPComplete) {
return
{(() => {
const twoNPs = (VP.subject === undefined) && (VP.verb.object === undefined);
@@ -17,7 +20,7 @@ function VPDisplay({ VP, opts }: { VP: T.VPSelection | T.VPSelectionComplete, op
})()}
;
}
- const result = compileVP(renderVP(VP), { ...form, OSV });
+ const result = compileVP(renderVP(VPComplete), { ...form, OSV });
return
{VP.verb.transitivity === "transitive" &&
}
diff --git a/src/components/vp-explorer/VPExplorer.tsx b/src/components/vp-explorer/VPExplorer.tsx
index f587900..81826ae 100644
--- a/src/components/vp-explorer/VPExplorer.tsx
+++ b/src/components/vp-explorer/VPExplorer.tsx
@@ -48,7 +48,7 @@ export function VPExplorer(props: {
})) {
const [vps, setVps] = useStickyState
(
savedVps => makeVPSelectionState(props.verb, savedVps),
- "vpsState1",
+ "vpsState2",
);
const [mode, setMode] = useStickyState<"charts" | "phrases" | "quiz">(
savedMode => {
@@ -59,7 +59,10 @@ export function VPExplorer(props: {
"verbExplorerMode",
);
const [showingExplanation, setShowingExplanation] = useState<{ role: "servant" | "king", item: "subject" | "object" } | false>(false);
- const roles = getKingAndServant(isPastTense(vps.verb.tense), vps.verb.transitivity !== "intransitive");
+ const roles = getKingAndServant(
+ isPastTense(vps.verb.tenseCategory === "perfect" ? vps.verb.perfectTense : vps.verb.verbTense),
+ vps.verb.transitivity !== "intransitive",
+ );
useEffect(() => {
setVps(oldVps => {
if (mode === "quiz") {
diff --git a/src/components/vp-explorer/VPExplorerQuiz.tsx b/src/components/vp-explorer/VPExplorerQuiz.tsx
index 88e69e2..ac5f229 100644
--- a/src/components/vp-explorer/VPExplorerQuiz.tsx
+++ b/src/components/vp-explorer/VPExplorerQuiz.tsx
@@ -9,7 +9,7 @@ import InlinePs from "../InlinePs";
import { psStringEquals } from "../../lib/p-text-helpers";
import { renderVP, compileVP } from "../../lib/phrase-building/index";
import { getRandomTense } from "./TensePicker";
-import { removeBa, switchSubjObj } from "../../lib/phrase-building/vp-tools";
+import { getTenseFromVerbSelection, removeBa, switchSubjObj } from "../../lib/phrase-building/vp-tools";
import playAudio from "../../lib/play-audio";
import TensePicker from "./TensePicker";
import Keyframes from "../Keyframes";
@@ -57,7 +57,7 @@ function VPExplorerQuiz(props: {
opts: T.TextOptions,
vps: T.VPSelection,
}) {
- const startingQs = tickQuizState(props.vps);
+ const startingQs = tickQuizState(completeVPs(props.vps));
const [quizState, setQuizState] = useState(startingQs);
const [showCheck, setShowCheck] = useState(false);
const [answerBlank, setAnswerBlank] = useState("");
@@ -115,7 +115,7 @@ function VPExplorerQuiz(props: {
}
null}
mode={"quiz"}
/>
@@ -278,7 +278,7 @@ function QuizNPDisplay({ children, stage, opts }: {
* @param startingWith
* @returns
*/
-function tickQuizState(startingWith: T.VPSelection | QuizState): QuizState {
+function tickQuizState(startingWith: T.VPSelectionComplete | QuizState): QuizState {
function makeRes(x: T.VPSelectionComplete) {
return compileVP(renderVP(x), { removeKing: false, shrinkServant: false });
}
@@ -369,13 +369,54 @@ function getOptionFromResult(r: {
return ps[0];
}
+function completeVPs(vps: T.VPSelection): T.VPSelectionComplete {
+ const oldSubj = vps.subject?.type === "pronoun"
+ ? vps.subject.person
+ : undefined;
+ const oldObj = (typeof vps.verb.object === "object" && vps.verb.object.type === "pronoun")
+ ? vps.verb.object.person
+ : undefined;
+ const { subj, obj } = randomSubjObj(
+ oldSubj === undefined
+ ? undefined
+ : {
+ subj: oldSubj,
+ obj: oldObj,
+ }
+ );
+ const verb: T.VerbSelectionComplete = {
+ ...vps.verb,
+ object: (
+ (typeof vps.verb.object === "object" && !(vps.verb.object.type === "noun" && vps.verb.object.dynamicComplement))
+ ||
+ vps.verb.object === undefined
+ )
+ ? {
+ type: "pronoun",
+ distance: "far",
+ person: obj,
+ }
+ : vps.verb.object,
+ tense: getTenseFromVerbSelection(vps.verb),
+ };
+ return {
+ ...vps,
+ subject: {
+ type: "pronoun",
+ distance: "far",
+ person: subj,
+ },
+ verb,
+ };
+}
+
function getRandomVPSelection(mix: MixType = "both") {
// TODO: Type safety to make sure it's safe?
- return ({ subject, verb }: T.VPSelection): T.VPSelectionComplete => {
- const oldSubj = (subject?.type === "pronoun")
+ return ({ subject, verb }: T.VPSelectionComplete): T.VPSelectionComplete => {
+ const oldSubj = (subject.type === "pronoun")
? subject.person
: undefined;
- const oldObj = (typeof verb?.object === "object" && verb.object.type === "pronoun")
+ const oldObj = (typeof verb.object === "object" && verb.object.type === "pronoun")
? verb.object.person
: undefined;
const { subj, obj } = randomSubjObj(
@@ -401,7 +442,6 @@ function getRandomVPSelection(mix: MixType = "both") {
if (mix === "tenses") {
return {
subject: subject !== undefined ? subject : randSubj,
- // @ts-ignore
verb: randomizeTense(verb, true),
}
}
@@ -426,9 +466,6 @@ function randomizeTense(verb: T.VerbSelectionComplete, dontRepeatTense: boolean)
return {
...verb,
tense: getRandomTense(
- // TODO: WHY ISN'T THE OVERLOADING ON THIS
- // @ts-ignore
- verb.tenseCategory,
dontRepeatTense ? verb.tense : undefined,
),
};
diff --git a/src/components/vp-explorer/verb-selection.ts b/src/components/vp-explorer/verb-selection.ts
index 89e2028..c2d8d81 100644
--- a/src/components/vp-explorer/verb-selection.ts
+++ b/src/components/vp-explorer/verb-selection.ts
@@ -3,7 +3,6 @@ import {
} from "../np-picker/picker-tools";
import * as T from "../../types";
import { getVerbInfo } from "../../lib/verb-info";
-import { isPerfectTense } from "../../lib/phrase-building/vp-tools";
export function makeVPSelectionState(
verb: T.VerbEntry,
@@ -46,28 +45,15 @@ export function makeVPSelectionState(
: "dynamic" in info
? { entry: info.dynamic.auxVerb } as T.VerbEntry
: undefined;
- const tenseSelection = ((): { tenseCategory: "perfect", tense: T.PerfectTense } | {
- tenseCategory: "basic" | "modal",
- tense: T.VerbTense,
- } => {
- if (!os) {
- return { tense: "presentVerb", tenseCategory: "basic" };
- }
- if (os.verb.tenseCategory === "modal") {
- return { tenseCategory: "modal", tense: isPerfectTense(os.verb.tense) ? "presentVerb" : os.verb.tense };
- }
- if (os.verb.tenseCategory === "basic") {
- return { tenseCategory: "basic", tense: isPerfectTense(os.verb.tense) ? "presentVerb" : os.verb.tense };
- }
- return { tenseCategory: "perfect", tense: isPerfectTense(os.verb.tense) ? os.verb.tense : "present perfect" };
- })();
return {
subject,
verb: {
type: "verb",
verb: verb,
dynAuxVerb,
- ...tenseSelection,
+ verbTense: os ? os.verb.verbTense : "presentVerb",
+ perfectTense: os ? os.verb.perfectTense : "presentPerfect",
+ tenseCategory: os ? os.verb.tenseCategory : "basic",
object,
transitivity,
isCompound,
diff --git a/src/lib/pashto-inflector.test.ts b/src/lib/pashto-inflector.test.ts
index 289ae85..3c91a47 100644
--- a/src/lib/pashto-inflector.test.ts
+++ b/src/lib/pashto-inflector.test.ts
@@ -674,6 +674,22 @@ const nouns: Array<{
}
}
},
+ // TODO: uncomment this
+ // {
+ // in: {"ts":1527812591,"i":6286,"p":"دواړه","f":"dwáaRu","g":"dwaaRu","e":"both","c":"n. m. pl. unisex / adj."},
+ // out: {
+ // plural: {
+ // masc: [
+ // [{ p: "دواړه", f: "dwáaRu" }],
+ // [{ p: "دواړو", f: "dwáaRo" }],
+ // ],
+ // fem: [
+ // [{ p: "دواړې", f: "dwáaRe" }],
+ // [{ p: "دواړو", f: "dwáaRo" }],
+ // ],
+ // }
+ // }
+ // },
// Masculine non-inflecting
{
in: {
diff --git a/src/lib/phrase-building/compile-vp.ts b/src/lib/phrase-building/compile-vp.ts
index 94f90b3..b8e65a0 100644
--- a/src/lib/phrase-building/compile-vp.ts
+++ b/src/lib/phrase-building/compile-vp.ts
@@ -12,6 +12,7 @@ import {
removeBa,
removeDuplicates,
} from "./vp-tools";
+import { isModalTense, isPerfectTense } from "../type-predicates";
type Form = T.FormVersion & { OSV?: boolean };
export function compileVP(VP: T.VPRendered, form: Form): { ps: T.SingleOrLengthOpts, e?: string [] };
@@ -129,7 +130,7 @@ function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {
}
function arrangeVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], V: T.VerbRendered): Segment[][] {
- const hasLeapfrog = V.tenseCategory === "modal" || V.tenseCategory === "perfect";
+ const hasLeapfrog = isPerfectTense(V.tense) || isModalTense(V.tense);
const rest = (() => {
if (hasLeapfrog) {
const [restF, restLast] = splitOffLeapfrogWord(restRaw);
diff --git a/src/lib/phrase-building/english-vp-rendering.ts b/src/lib/phrase-building/english-vp-rendering.ts
index c4f69d3..478d2a9 100644
--- a/src/lib/phrase-building/english-vp-rendering.ts
+++ b/src/lib/phrase-building/english-vp-rendering.ts
@@ -1,6 +1,11 @@
import * as T from "../../types";
import { getVerbBlockPosFromPerson, parseEc } from "../misc-helpers";
import * as grammarUnits from "../grammar-units";
+import {
+ isPerfectTense,
+ isVerbTense,
+ // isModalTense,
+} from "../type-predicates";
function engHave(s: T.Person): string {
function isThirdPersonSing(p: T.Person): boolean {
@@ -15,7 +20,7 @@ function engHave(s: T.Person): string {
export function renderEnglishVPBase({ subjectPerson, object, vs }: {
subjectPerson: T.Person,
object: T.NPSelection | T.ObjectNP,
- vs: T.VerbSelection,
+ vs: T.VerbSelectionComplete,
}): string[] {
const ec = parseEc(vs.verb.entry.ec || "");
const ep = vs.verb.entry.ep;
@@ -79,34 +84,34 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
]),
};
const modalBuilders: Record<
- T.VerbTense,
+ T.ModalTense,
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
> = {
- presentVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ can${n ? "'t" : ""} ${isToBe(v) ? "be" : v[0]}`,
]),
- subjunctiveVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ subjunctiveVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`that $SUBJ can${n ? "'t" : ""} ${isToBe(v) ? "be" : v[0]}`,
]),
- imperfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ imperfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ will${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
]),
- perfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ perfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ will${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
]),
- imperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ imperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ ${engEquative("past", s)} ${n ? " not" : ""} able to ${isToBe(v) ? "be" : v[0]}`,
`$SUBJ could${n ? " not" : ""} ${v[0]}`,
]),
- perfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ perfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ ${engEquative("past", s)} ${n ? " not" : ""} able to ${isToBe(v) ? "be" : v[0]}`,
`$SUBJ could${n ? " not" : ""} ${isToBe(v) ? "be" : v[0]}`,
]),
- habitualImperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ habitualImperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ used to ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
`$SUBJ would ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
]),
- habitualPerfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ habitualPerfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ used to ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
`$SUBJ would ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
]),
@@ -115,25 +120,25 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
T.PerfectTense,
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
> = {
- "present perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ presentPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ ${engHave(s)}${n ? " not" : ""} ${v[4]}`,
]),
- "past perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ pastPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ had${n ? " not" : ""} ${v[4]}`,
]),
- "habitual perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ habitualPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ ${engHave(s)}${n ? " not" : ""} ${v[4]}`,
]),
- "subjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ subjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`that $SUBJ will have${n ? " not" : ""} ${v[4]}`,
]),
- "future perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ futurePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ will${n ? " not" : ""} have ${v[4]}`,
]),
- "wouldBe perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ wouldBePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ would${n ? " not" : ""} have ${v[4]}`,
]),
- "pastSubjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ pastSubjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ would${n ? " not" : ""} have ${v[4]}`,
`$SUBJ should${n ? " not" : ""} have ${v[4]}`,
]),
@@ -173,65 +178,65 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
T.PerfectTense,
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
> = {
- "present perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ presentPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ ${engHave(s)}${n ? " not" : ""} been ${v[4]}`,
]),
- "past perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ pastPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ had${n ? " not" : ""} been ${v[4]}`,
]),
- "habitual perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ habitualPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ ${engHave(s)}${n ? " not" : ""} been ${v[4]}`,
]),
- "subjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ subjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`that $SUBJ will${n ? " not" : ""} have been ${v[4]}`,
]),
- "future perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ futurePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ will${n ? " not" : ""} have been ${v[4]}`,
]),
- "wouldBe perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ wouldBePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ will${n ? " not" : ""} have been ${v[4]}`,
]),
- "pastSubjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ pastSubjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ would${n ? " not" : ""} have been ${v[4]}`,
]),
}
const passiveModalBuilders: Record<
- T.VerbTense,
+ T.ModalTense,
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
> = {
- presentVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ can${n ? " not" : ""} be ${v[4]}`,
`$SUBJ ${engEquative("present", s)}${n ? " not" : ""} able to be ${v[4]}`,
]),
- subjunctiveVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ subjunctiveVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`that $SUBJ will${n ? " not" : ""} be able to be ${v[4]}`,
`that $SUBJ ${n ? " not" : ""} be able to be ${v[4]}`,
]),
- imperfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ imperfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ will${n ? " not" : ""} be able to be ${v[4]}`,
]),
- perfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ perfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ will${n ? " not" : ""} be able to be ${v[4]}`,
]),
- imperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ imperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ would${n ? " not" : ""} be able to be ${v[4]}`,
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} being able to be ${v[4]}`,
]),
- perfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ perfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} able to be ${v[4]}`,
]),
- habitualPerfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ habitualPerfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ would${n ? " not" : ""} be able to be ${v[4]}`,
]),
- habitualImperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
+ habitualImperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
`$SUBJ would${n ? " not" : ""} be able to be ${v[4]}`,
]),
};
const base = (
- (vs.tenseCategory === "perfect")
- ? (vs.voice === "active" ? perfectBuilders : passivePerfectBuilders)[vs.tense]
- : vs.tenseCategory === "basic"
- ? (vs.voice === "active" ? basicBuilders : passiveBasicBuilders)[vs.tense]
- : (vs.voice === "active" ? modalBuilders : passiveModalBuilders)[vs.tense])(subjectPerson, ec, vs.negative);
+ isPerfectTense(vs.tense)
+ ? (vs.voice === "active" ? perfectBuilders : passivePerfectBuilders)[vs.tense]
+ : isVerbTense(vs.tense)
+ ? (vs.voice === "active" ? basicBuilders : passiveBasicBuilders)[vs.tense]
+ : (vs.voice === "active" ? modalBuilders : passiveModalBuilders)[vs.tense])(subjectPerson, ec, vs.negative);
return base.map(b => `${b}${typeof object === "object" ? " $OBJ" : ""}${ep ? ` ${ep}` : ""}`);
}
diff --git a/src/lib/phrase-building/render-vp.ts b/src/lib/phrase-building/render-vp.ts
index ad91477..3e21f3b 100644
--- a/src/lib/phrase-building/render-vp.ts
+++ b/src/lib/phrase-building/render-vp.ts
@@ -19,10 +19,12 @@ import {
getPersonFromNP,
removeBa,
isPastTense,
- isPerfectTense,
getTenseVerbForm,
} from "./vp-tools";
-import { isPattern4Entry } from "../type-predicates";
+import {
+ isPattern4Entry,
+ isPerfectTense,
+} from "../type-predicates";
import { renderEnglishVPBase } from "./english-vp-rendering";
// TODO: ISSUE GETTING SPLIT HEAD NOT MATCHING WITH FUTURE VERBS
@@ -129,7 +131,7 @@ function renderParticipleSelection(p: T.ParticipleSelection, inflected: boolean)
};
}
-function renderVerbSelection(vs: T.VerbSelection, person: T.Person, objectPerson: T.Person | undefined): T.VerbRendered {
+function renderVerbSelection(vs: T.VerbSelectionComplete, person: T.Person, objectPerson: T.Person | undefined): T.VerbRendered {
const v = vs.dynAuxVerb || vs.verb;
const conjugations = conjugateVerb(v.entry, v.complement);
// TODO: error handle this?
@@ -148,14 +150,14 @@ function renderVerbSelection(vs: T.VerbSelection, person: T.Person, objectPerson
}
}
-function getPsVerbConjugation(conj: T.VerbConjugation, vs: T.VerbSelection, person: T.Person, objectPerson: T.Person | undefined): {
+function getPsVerbConjugation(conj: T.VerbConjugation, vs: T.VerbSelectionComplete, person: T.Person, objectPerson: T.Person | undefined): {
ps: {
head: T.PsString | undefined,
rest: T.SingleOrLengthOpts,
},
hasBa: boolean,
} {
- const f = getTenseVerbForm(conj, vs.tense, vs.tenseCategory, vs.voice);
+ const f = getTenseVerbForm(conj, vs.tense, vs.voice);
const block = getMatrixBlock(f, objectPerson, person);
const perfective = isPerfective(vs.tense);
const verbForm = getVerbFromBlock(block, person);
@@ -324,7 +326,7 @@ function isFirstOrSecondPersPronoun(o: "none" | T.NPSelection | T.Person.ThirdPl
return [0,1,2,3,6,7,8,9].includes(o.person);
}
-function isPerfective(t: T.VerbTense | T.PerfectTense): boolean {
+function isPerfective(t: T.VerbTense | T.PerfectTense | T.ModalTense): boolean {
if (isPerfectTense(t)) return false;
if (t === "presentVerb" || t === "imperfectiveFuture" || t === "imperfectivePast" || t === "habitualImperfectivePast") {
return false;
@@ -332,6 +334,9 @@ function isPerfective(t: T.VerbTense | T.PerfectTense): boolean {
if (t === "perfectiveFuture" || t === "subjunctiveVerb" || t === "perfectivePast" || t === "habitualPerfectivePast") {
return true;
}
+ if (t === "perfectiveFutureModal" || t === "subjunctiveVerbModal" || t === "perfectivePastModal" || t === "habitualPerfectivePastModal") {
+ return true;
+ }
throw new Error("tense not implemented yet");
}
diff --git a/src/lib/phrase-building/vp-tools.ts b/src/lib/phrase-building/vp-tools.ts
index 245b937..a1200e8 100644
--- a/src/lib/phrase-building/vp-tools.ts
+++ b/src/lib/phrase-building/vp-tools.ts
@@ -4,6 +4,7 @@ import {
psRemove,
psStringEquals,
} from "../../lib/p-text-helpers";
+import { isPerfectTense } from "../type-predicates";
import * as grammarUnits from "../../lib/grammar-units";
export function isInvalidSubjObjCombo(subj: T.Person, obj: T.Person): boolean {
@@ -26,79 +27,75 @@ export function isInvalidSubjObjCombo(subj: T.Person, obj: T.Person): boolean {
);
}
-export function getTenseVerbForm(conjR: T.VerbConjugation, tense: T.VerbTense | T.PerfectTense, tenseCategory: "basic" | "modal" | "perfect", voice: "active" | "passive"): T.VerbForm {
+export function getTenseVerbForm(conjR: T.VerbConjugation, tense: T.VerbTense | T.PerfectTense | T.ModalTense, voice: "active" | "passive"): T.VerbForm {
const conj = (voice === "passive" && conjR.passive) ? conjR.passive : conjR;
- if (tenseCategory === "basic") {
- if (tense === "presentVerb") {
- return conj.imperfective.nonImperative;
- }
- if (tense === "subjunctiveVerb") {
- return conj.perfective.nonImperative;
- }
- if (tense === "imperfectiveFuture") {
- return conj.imperfective.future;
- }
- if (tense === "perfectiveFuture") {
- return conj.perfective.future;
- }
- if (tense === "imperfectivePast") {
- return conj.imperfective.past;
- }
- if (tense === "perfectivePast") {
- return conj.perfective.past;
- }
- if (tense === "habitualImperfectivePast") {
- return conj.imperfective.habitualPast;
- }
- if (tense === "habitualPerfectivePast") {
- return conj.perfective.habitualPast;
- }
+ if (tense === "presentVerb") {
+ return conj.imperfective.nonImperative;
}
- if (tenseCategory === "modal") {
- if (tense === "presentVerb") {
- return conj.imperfective.modal.nonImperative;
- }
- if (tense === "subjunctiveVerb") {
- return conj.perfective.modal.nonImperative;
- }
- if (tense === "imperfectiveFuture") {
- return conj.imperfective.modal.future;
- }
- if (tense === "perfectiveFuture") {
- return conj.perfective.modal.future;
- }
- if (tense === "imperfectivePast") {
- return conj.imperfective.modal.past;
- }
- if (tense === "perfectivePast") {
- return conj.perfective.modal.past;
- }
- if (tense === "habitualImperfectivePast") {
- return conj.imperfective.modal.habitualPast;
- }
- if (tense === "habitualPerfectivePast") {
- return conj.perfective.modal.habitualPast;
- }
+ if (tense === "subjunctiveVerb") {
+ return conj.perfective.nonImperative;
}
- if (tense === "present perfect") {
+ if (tense === "imperfectiveFuture") {
+ return conj.imperfective.future;
+ }
+ if (tense === "perfectiveFuture") {
+ return conj.perfective.future;
+ }
+ if (tense === "imperfectivePast") {
+ return conj.imperfective.past;
+ }
+ if (tense === "perfectivePast") {
+ return conj.perfective.past;
+ }
+ if (tense === "habitualImperfectivePast") {
+ return conj.imperfective.habitualPast;
+ }
+ if (tense === "habitualPerfectivePast") {
+ return conj.perfective.habitualPast;
+ }
+ if (tense === "presentVerbModal") {
+ return conj.imperfective.modal.nonImperative;
+ }
+ if (tense === "subjunctiveVerbModal") {
+ return conj.perfective.modal.nonImperative;
+ }
+ if (tense === "imperfectiveFutureModal") {
+ return conj.imperfective.modal.future;
+ }
+ if (tense === "perfectiveFutureModal") {
+ return conj.perfective.modal.future;
+ }
+ if (tense === "imperfectivePastModal") {
+ return conj.imperfective.modal.past;
+ }
+ if (tense === "perfectivePastModal") {
+ return conj.perfective.modal.past;
+ }
+ if (tense === "habitualImperfectivePastModal") {
+ return conj.imperfective.modal.habitualPast;
+ }
+ if (tense === "habitualPerfectivePastModal") {
+ return conj.perfective.modal.habitualPast;
+ }
+ if (tense === "presentPerfect") {
return conj.perfect.present;
}
- if (tense === "past perfect") {
+ if (tense === "pastPerfect") {
return conj.perfect.past;
}
- if (tense === "future perfect") {
+ if (tense === "futurePerfect") {
return conj.perfect.future;
}
- if (tense === "habitual perfect") {
+ if (tense === "habitualPerfect") {
return conj.perfect.habitual;
}
- if (tense === "subjunctive perfect") {
+ if (tense === "subjunctivePerfect") {
return conj.perfect.subjunctive;
}
- if (tense === "wouldBe perfect") {
+ if (tense === "wouldBePerfect") {
return conj.perfect.affirmational;
}
- if (tense === "pastSubjunctive perfect") {
+ if (tense === "pastSubjunctivePerfect") {
return conj.perfect.pastSubjunctiveHypothetical;
}
throw new Error("unknown tense");
@@ -126,23 +123,45 @@ export function removeBa(ps: T.PsString): T.PsString {
return psRemove(ps, concatPsString(grammarUnits.baParticle, " "));
}
-export function isEquativeTense(t: T.VerbTense | T.EquativeTense | T.PerfectTense): t is T.EquativeTense {
- return (t === "present" || t === "future" || t === "habitual" || t === "past" || t === "wouldBe" || t === "subjunctive" || t === "pastSubjunctive");
+export function getTenseFromVerbSelection(vs: T.VerbSelection): T.VerbTense | T.PerfectTense | T.ModalTense {
+ function verbTenseToModalTense(tn: T.VerbTense): T.ModalTense {
+ if (tn === "presentVerb") {
+ return "presentVerbModal";
+ }
+ if (tn === "subjunctiveVerb") {
+ return "subjunctiveVerbModal";
+ }
+ if (tn === "imperfectiveFuture") {
+ return "imperfectiveFutureModal";
+ }
+ if (tn === "perfectiveFuture") {
+ return "perfectiveFutureModal";
+ }
+ if (tn === "perfectivePast") {
+ return "perfectiveFutureModal";
+ }
+ if (tn === "imperfectivePast") {
+ return "imperfectivePastModal";
+ }
+ if (tn === "habitualImperfectivePast") {
+ return "habitualImperfectivePastModal";
+ }
+ if (tn === "habitualPerfectivePast") {
+ return "habitualPerfectivePastModal";
+ }
+ throw new Error("can't convert non verbTense to modalTense");
+ }
+ if (vs.tenseCategory === "basic") {
+ return vs.verbTense;
+ }
+ if (vs.tenseCategory === "perfect") {
+ return vs.perfectTense;
+ }
+ // vs.tenseCategory === "modal"
+ return verbTenseToModalTense(vs.verbTense);
}
-export function isPerfectTense(t: T.VerbTense | T.EquativeTense | T.PerfectTense): t is T.PerfectTense {
- return (
- t === "present perfect" ||
- t === "habitual perfect" ||
- t === "future perfect" ||
- t === "past perfect" ||
- t === "wouldBe perfect" ||
- t === "subjunctive perfect" ||
- t === "pastSubjunctive perfect"
- );
-}
-
-export function isPastTense(tense: T.VerbTense | T.PerfectTense): boolean {
+export function isPastTense(tense: T.VerbTense | T.PerfectTense | T.ModalTense): boolean {
if (isPerfectTense(tense)) return true;
return tense.toLowerCase().includes("past");
}
@@ -155,15 +174,52 @@ export function removeDuplicates(psv: T.PsString[]): T.PsString[] {
));
}
-export function switchSubjObj({ subject, verb }: T.VPSelection): T.VPSelection {
- if (!subject|| !verb || !verb.object || !(typeof verb.object === "object")) {
- return { subject, verb };
+export function switchSubjObj(vps: T.VPSelection): T.VPSelection;
+export function switchSubjObj(vps: T.VPSelectionComplete): T.VPSelectionComplete;
+export function switchSubjObj(vps: T.VPSelection | T.VPSelectionComplete): T.VPSelection | T.VPSelectionComplete {
+ if ("tenseCategory" in vps.verb) {
+ if (!vps.subject || !(typeof vps.verb.object === "object")) {
+ return vps;
+ }
+ return {
+ ...vps,
+ subject: vps.verb.object,
+ verb: {
+ ...vps.verb,
+ object: vps.subject,
+ },
+ };
+ }
+ if (!vps.subject|| !vps.verb || !(typeof vps.verb.object === "object")) {
+ return vps;
}
return {
- subject: verb.object,
+ ...vps,
+ subject: vps.verb.object,
verb: {
- ...verb,
- object: subject,
+ ...vps.verb,
+ object: vps.subject,
}
};
+}
+
+export function completeVPSelection(vps: T.VPSelection): T.VPSelectionComplete | undefined {
+ if (vps.subject === undefined) {
+ return undefined;
+ }
+ if (vps.verb.object === undefined) {
+ return undefined;
+ }
+ // necessary for this version on typscript ...
+ const verb: T.VerbSelectionComplete = {
+ ...vps.verb,
+ object: vps.verb.object,
+ tense: getTenseFromVerbSelection(vps.verb),
+ };
+ const subject = vps.subject;
+ return {
+ ...vps,
+ subject,
+ verb,
+ };
}
\ No newline at end of file
diff --git a/src/lib/type-predicates.ts b/src/lib/type-predicates.ts
index eaa6ab3..e9400a9 100644
--- a/src/lib/type-predicates.ts
+++ b/src/lib/type-predicates.ts
@@ -160,9 +160,30 @@ export function isArrayOneOrMore(a: U[]): a is T.ArrayOneOrMore {
return a.length > 0;
}
-export function isVPSelectionComplete(vps: T.VPSelection | T.VPSelectionComplete): vps is T.VPSelectionComplete {
- if ((vps.subject !== undefined) && (vps.verb.object !== undefined)) {
- return true;
- }
- return false;
+export function isPerfectTense(tense: T.VerbTense | T.EquativeTense | T.ModalTense | T.PerfectTense): tense is T.PerfectTense {
+ return tense.endsWith("Perfect");
}
+
+export function isVerbTense(tense: T.VerbTense | T.EquativeTense | T.ModalTense | T.PerfectTense): tense is T.VerbTense {
+ const verbTenses: T.VerbTense[] = [
+ "presentVerb",
+ "subjunctiveVerb",
+ "perfectiveFuture",
+ "imperfectiveFuture",
+ "perfectivePast",
+ "imperfectivePast",
+ "habitualPerfectivePast",
+ "habitualImperfectivePast",
+ ];
+ return verbTenses.some(x => x === tense);
+}
+
+export function isModalTense(tense: T.VerbTense | T.EquativeTense | T.ModalTense | T.PerfectTense): tense is T.ModalTense {
+ return tense.endsWith("Modal");
+}
+
+export function isEquativeTense(t: T.VerbTense | T.EquativeTense | T.PerfectTense | T.ModalTense): t is T.EquativeTense {
+ return (t === "present" || t === "future" || t === "habitual" || t === "past" || t === "wouldBe" || t === "subjunctive" || t === "pastSubjunctive");
+}
+
+
diff --git a/src/types.ts b/src/types.ts
index 3e58cd6..737e161 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -535,7 +535,8 @@ export type VerbTense = "presentVerb"
export type EquativeTense = "present" | "subjunctive" | "habitual" | "past" | "future" | "wouldBe" | "pastSubjunctive";
export type NounNumber = "singular" | "plural";
-export type PerfectTense = `${EquativeTense} perfect`;
+export type PerfectTense = `${EquativeTense}Perfect`;
+export type ModalTense = `${VerbTense}Modal`;
export type VPSelection = {
subject: NPSelection | undefined,
@@ -547,9 +548,10 @@ export type VPSelectionComplete = {
verb: VerbSelectionComplete,
};
-export type VerbSelectionComplete = Exclude & {
+export type VerbSelectionComplete = Omit & {
object: Exclude,
-};
+ tense: VerbTense | PerfectTense | ModalTense,
+}
export type VerbSelection = {
type: "verb",
@@ -565,15 +567,12 @@ export type VerbSelection = {
// TODO: changeStativeDynamic
// TODO: add in aspect element here??
negative: boolean,
-} & ({
- tense: VerbTense,
- tenseCategory: "basic" | "modal",
-} | {
- tense: PerfectTense,
- tenseCategory: "perfect"
-});
+ verbTense: VerbTense,
+ perfectTense: PerfectTense,
+ tenseCategory: "basic" | "modal" | "perfect",
+};
-export type VerbRendered = Omit & {
+export type VerbRendered = Omit & {
ps: {
head: PsString | undefined,
rest: SingleOrLengthOpts<