UNPKG

@zsnout/ithkuil

Version:

A set of tools which can generate and parse romanized Ithkuil text and which can generate Ithkuil script from text and JSON data.

126 lines (125 loc) 4.26 kB
import { DCLeaf, DCStress, DCWord } from "../decompose.js"; import { dcMoodOrCaseScope, parseMoodOrCaseScope, } from "../formative/mood-or-case-scope.js"; import { dcAspect, dcNonAspectualVn, parseAspect, parseNonAspectualVn, } from "../formative/vn.js"; import { modularAdjunct } from "../lex/adjunct/modular.js"; import { VowelForm } from "../vowel-form.js"; const VH_TO_SCOPE = { a: "CASE/MOOD+ILL/VAL", e: "CASE/MOOD", i: "FORMATIVE", u: "FORMATIVE", o: "ADJACENT", }; /** * Builds a modular adjunct. * * @param word The word to be built. * @param stress The stress of the adjunct. * @returns Either a parsed `ModularAdjunct` indicating a success, or * `undefined` indicating a tokenization failure. Throws if the adjunct was * successfully tokenized but had another error in it (e.g. invalid Vn slot, * etc.). */ export function buildModularAdjunct(word, stress) { const match = modularAdjunct.exec(word); if (!match) { return; } const type = match[1] == "w" ? "PARENT" : match[1] == "y" ? "CONCAT" : undefined; if (!(match[2] || match[4])) { return { type, vn1: parseAspect(VowelForm.parseOrThrow(match[6])), }; } const [cn, isVnAspectual] = parseMoodOrCaseScope(match[3]); const vn1 = isVnAspectual ? parseAspect(VowelForm.parseOrThrow(match[2])) : parseNonAspectualVn(VowelForm.parseOrThrow(match[2])); let vn2; if (match[4]) { vn2 = match[5] == "n" ? parseAspect(VowelForm.parseOrThrow(match[4])) : parseNonAspectualVn(VowelForm.parseOrThrow(match[4])); } let scope; if (stress == "ultimate") { scope = VH_TO_SCOPE[match[6]]; if (scope == null) { throw new Error("Invalid Vh slot: " + match[6] + "."); } if (vn2) { return { type, vn1, cn, vn2, scope, }; } return { type, vn1, cn, scope, }; } if (vn2) { return { type, vn1, cn, vn2, vn3: parseNonAspectualVn(VowelForm.parseOrThrow(match[6])), }; } return { type, vn1, cn, vn3: parseNonAspectualVn(VowelForm.parseOrThrow(match[6])), }; } /** * Builds a modular adjunct. * * @param word The word to be decomposed. * @param stress The stress of the adjunct. * @returns Either a parsed array of decompositions indicating a success, or * `undefined` indicating a tokenization failure. Throws if the adjunct was * successfully tokenized but had another error in it (e.g. invalid Vn slot, * etc.). */ export function dcModularAdjunct(word, stress) { const match = modularAdjunct.exec(word); if (!match) { return; } const type = match[1] == "w" ? [new DCLeaf("w", "C*", "modularType", "PARENT")] : match[1] == "y" ? [new DCLeaf("y", "C*", "modularType", "CONCAT")] : []; if (!(match[2] || match[4])) { return new DCWord("adjModular", new DCStress("monosyllabic", "VN"), ...type, new DCLeaf(match[6], "Vn", "aspect", parseAspect(VowelForm.parseOrThrow(match[6])))); } const [cn, isVnAspectual] = dcMoodOrCaseScope(match[3]); const vn1 = isVnAspectual ? dcAspect(match[2]) : dcNonAspectualVn(match[2]); const vn2 = match[5] == "n" ? [dcAspect(match[4]), new DCLeaf("n", "Cm", "modularCm", "ASPECT")] : match[5] == "ň" ? [ dcNonAspectualVn(match[4]), new DCLeaf("ň", "Cm", "modularCm", "NON-ASPECT"), ] : []; if (stress == "ultimate") { const scope = VH_TO_SCOPE[match[6]]; if (scope == null) { throw new Error("Invalid Vh slot: " + match[6] + "."); } return new DCWord("adjModular", new DCStress(stress, "VH"), ...type, vn1, cn, ...vn2, new DCLeaf(match[6], "Vh", "modularScope", scope)); } return new DCWord("adjModular", new DCStress(stress, "VN"), ...type, vn1, cn, ...vn2, dcNonAspectualVn(match[6])); }