compiler: text keys (phase 26.2) - k"pause.resume" / kn"catch.count" of the builtin type Key (not a string, and no string one; == compares), its run-time value the key after a marker byte (1, or 2 for a plural); package.ludic's lang "assets/lang" en and a gettext .po reader; every key literal checked against en.po (a kn"" one wants a msgid_plural), trf / trn and a template's t('key', ...) against the English's holes, a component's template words and a @Text row's English as "English left" (warnings, english_left in ludic deps), a @Text Key field a compiled row leaves out filled with its derived key <registry>.<row>.<field> (or @TextKey's prefix; maps.<map>.<table>.<row>.<field> for a @PerMap row, checked), one English under several undescribed keys warned at en.po's line; the schema's "lang" (keys and their sites, unused, undescribed, split, and every other language's missing / fuzzy / extra); k"" in .lres data, @PerMap rows included (lres_key); ludic-fmt keeps a key literal whole; reseeded, bootstrap-cfree fixpoint holds

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 23:33:52 +03:00
parent 82c652ca31
commit cc1ea0f4ae
28 changed files with 139268 additions and 109746 deletions

View file

@ -10,6 +10,7 @@ const TK_NL: int = 4
const TK_EOF: int = 5
const TK_FLOAT: int = 6
const TK_INTERP: int = 7 # `text {expr} text` — raw content, split by the parser
const TK_KEY: int = 8 # k"pause.resume" / kn"catch.count" — a text key (i18n.ludic); ival 1 or 2
property Tok { kind: int = 0, text: pointer = null, ival: int = 0, line: int = 0, pos: int = -1, end: int = -1, col: int = 0, off: int = -1, oend: int = -1 }
# col: the token's column (1-based) on its line; off / oend: where it starts and ends in the text
@ -244,6 +245,23 @@ function lex_at(src: pointer, first_line: int) -> void {
if char_is_alpha(c) {
let start = i
while i < n and char_is_alnum(src[i]) { i += 1 }
# `k"..."` / `kn"..."`: a key literal, the name written against the quote (`k "x"` is a name
# and a string, as it always was)
let kw = i - start
if i < n and src[i] == '"' and ((kw == 1 and c == 'k') or (kw == 2 and c == 'k' and src[start + 1] == 'n')) {
i += 1
let kout = bytes(n)
var kj = 0
while i < n and src[i] != '"' and src[i] != '\n' {
if src[i] == CH_BACKSLASH { kout[kj] = unescape(src[i + 1]); kj += 1; i += 2 }
else { kout[kj] = src[i]; kj += 1; i += 1 }
}
if i >= n or src[i] != '"' { lex_fail(line, "a key literal is never closed with \" on its line") }
i += 1
kout[kj] = 0
tok_push(TK_KEY, kout, kw, line)
continue
}
tok_push(TK_ID, src[start..i], 0, line)
continue
}