From 3a264c4a3f0a3073b5e594760028ce71eb6c914c Mon Sep 17 00:00:00 2001 From: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> Date: Fri, 3 Jul 2026 11:31:02 +0300 Subject: [PATCH] registry: split buildRegistry into per-category functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 290-line function is now registerCoreVocab / registerUnits / registerAreaVolume / registerCurrencies / registerExtraUnits / registerCrypto / registerCompletions, called in the same order — phrase-collision priority depends on that order, unchanged. Pure reorganization, no behavior change. --- src/engine/registry.ts | 48 ++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/engine/registry.ts b/src/engine/registry.ts index 5344538..b4b0166 100644 --- a/src/engine/registry.ts +++ b/src/engine/registry.ts @@ -156,10 +156,22 @@ function addUnitPhrases(reg: Registry, phrases: string[], unit: Unit, opts: { ca for (const p of phrases) reg.addPhrase(p, { t: "unit", unit }, opts); } +interface LengthPhrase { phrase: string; unit: Unit; caseSensitive?: boolean } + export function buildRegistry(): Registry { const reg = new Registry(); + registerCoreVocab(reg); + const lengthPhrases = registerUnits(reg); + registerAreaVolume(reg, lengthPhrases); + registerCurrencies(reg); + registerExtraUnits(reg); + registerCrypto(reg); + registerCompletions(reg); + return reg; +} - // operators, percent, dates, numerals, scales, aggregates +// operators, percent, dates, numerals, scales, aggregates, built-in functions +function registerCoreVocab(reg: Registry): void { const ops: Array<[string, Payload]> = [ ["plus", { t: "op", op: "plus" }], ["minus", { t: "op", op: "minus" }], @@ -255,9 +267,11 @@ export function buildRegistry(): Registry { reg.addPhrase("полторы", { t: "const", name: "onehalf" }, { caseSensitive: false }); for (const f of BUILTIN_FUNCS) reg.addPhrase(f, { t: "func", name: f }, { caseSensitive: false }); +} - // units, SI/IEC prefixes, area/volume templates - interface LengthPhrase { phrase: string; unit: Unit; caseSensitive?: boolean } +// UNIT_DATA + SI/IEC prefixes; returns the length-dimension phrases the +// area/volume templates need to build "square meter" / "cubic foot" etc. +function registerUnits(reg: Registry): LengthPhrase[] { const lengthPhrases: LengthPhrase[] = []; /** lowercased composed symbol -> unit; null = ambiguous (mm vs Mm) */ const lenientSym = new Map(); @@ -335,7 +349,11 @@ export function buildRegistry(): Registry { if (unit) reg.addPhrase(lower, { t: "unit", unit }, { caseSensitive: false }); } - // Area/volume from templates: "square %@" / "cubic %@" applied to every length phrase + return lengthPhrases; +} + +// "square %@" / "cubic %@" applied to every length phrase from registerUnits +function registerAreaVolume(reg: Registry, lengthPhrases: LengthPhrase[]): void { const applyTemplates = ( templates: string[], fmtTemplate: string, @@ -363,10 +381,11 @@ export function buildRegistry(): Registry { }; applyTemplates(vocab.variants("Area", "area.templates"), vocab.entryEn("Area", "area.format") ?? "%@²", "area", 2, "sq"); applyTemplates(vocab.variants("Volume", "volume.templates"), vocab.entryEn("Volume", "volume.format") ?? "%@³", "volume", 3, "cb"); +} - // currencies - // Major currencies register first so they win generic phrases - // ("доллар" belongs to USD, not TTD which lists it too and sorts earlier). +// Major currencies register first so they win generic phrases +// ("доллар" belongs to USD, not TTD which lists it too and sorts earlier). +function registerCurrencies(reg: Registry): void { const PRIORITY = [ "USD", "EUR", "GBP", "RUB", "JPY", "CNY", "CHF", "CAD", "AUD", "UAH", "BYN", "KZT", "PLN", "TRY", "INR", "BRL", "KRW", "NZD", "SEK", "NOK", @@ -385,8 +404,10 @@ export function buildRegistry(): Registry { if (!variants.some((v) => v.toUpperCase() === code)) variants.push(code); for (const v of variants) reg.addPhrase(v, { t: "currency", code }, { caseSensitive: false }); } +} - // speed, pressure, energy, power, frequency, fuel +// speed, pressure, energy, power, frequency, fuel +function registerExtraUnits(reg: Registry): void { for (const d of EXTRA_UNITS) { const unit: Unit = { id: d.id, @@ -407,9 +428,11 @@ export function buildRegistry(): Registry { } } } +} - // cryptocurrencies (live prices come from the shell) - // codes that collide with common words match case-sensitively only +// live prices come from the shell; codes that collide with common words +// (TON, NEAR, DOT, ...) match case-sensitively only +function registerCrypto(reg: Registry): void { const CRYPTO_STRICT_CODES = new Set(["TON", "NEAR", "ATOM", "LINK", "UNI", "DOT", "SOL"]); for (const c of CRYPTO) { reg.currencyCodes.add(c.code); @@ -420,8 +443,9 @@ export function buildRegistry(): Registry { if (ph) reg.addPhrase(ph, { t: "currency", code: c.code }, { caseSensitive: false }); } } +} - // autocomplete entries +function registerCompletions(reg: Registry): void { const seen = new Set(); const addCompletion = (label: string, type: Completion["type"], detail?: string) => { const k = `${type}:${label.toLowerCase()}`; @@ -440,6 +464,4 @@ export function buildRegistry(): Registry { for (const k of ["sum", "total", "average", "avg", "prev", "today", "tomorrow", "yesterday", "time", "now", "hex", "binary"]) { addCompletion(k, "keyword"); } - - return reg; }