compiler: text keys below a row, trf padding and tr's cast (ECS's 26.4 gaps) - a @Text Key in a record nested in a row, or in each item of a list of them, is filled with its derived key <registry>.<row>.<field>.<i>.<field> as a top-level one is, and a @Text []Key a row leaves out takes <...>.0, .1, ... for as many as en.po has (so no .lres spells a key; the manifest and en.po are now read before the parse that fills the rows); field: null is no text; trf / trn's trailing "" literals are padding, not counted against the English's holes; and string(x) of a string or a Key is x itself to the escape analysis, no allocation site, so tr(key) passes arena strict (a template's lone hole still copies); examples/lang/i18n_nested and its feat_case (added, not run); LANGUAGE.md and the changeset; reseeded, bootstrap-cfree fixpoint holds

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-30 00:41:05 +03:00
parent 9a0011c38f
commit 10a394ae6c
12 changed files with 75642 additions and 73902 deletions

View file

@ -0,0 +1,4 @@
# i18n_nested.ludic's raids: no row spells a key - a nested record's @Text Key, a list of them and a
# @Text []Key are all derived; `null` says a row has no text there
camp { arrive: { steps: [ { need: 2 }, { need: 5 } ] } }
quiet { arrive: { steps: [ { need: 1 } ] }, said: null }

View file

@ -0,0 +1,35 @@
# i18n_nested.ludic — derived text keys below a row (LANGUAGE.md, "Text keys"): a nested record's
# @Text Key is <registry>.<row>.<field>.<field>, a list item's adds .<index>, and a @Text []Key a row
# leaves out takes <...>.0, .1, ... for as many as en.po has. `field: null` is no text. trf's trailing
# "" pad its unused values and are not counted against the English's holes.
#
# Running it prints: raids.camp.arrive.steps.0.text raids.camp.arrive.steps.1.text 2 raids.camp.said.1 0 raids.quiet.arrive.steps.0.text hud.day(3)
program I18nNested {
property Step {
@Text text: Key = null
need: int = 0
}
property Arrive { steps: []Step = null }
property Raid {
key: string = ""
arrive: Arrive = null
@Text said: []Key = null
}
registry Raids of Raid as RD from "data/raids.lres"
function tr(key: Key) -> string {
let s = string(key)
return s[1..len(s)]
}
function trf(key: Key, a: string, b: string, c: string) -> string { return `{tr(key)}({a}{b}{c})` }
function said_n(r: Raid) -> int {
if r.said == null { return 0 }
return len(r.said)
}
entry {
let camp = Raids[RD_CAMP]
let quiet = Raids[RD_QUIET]
var out = `{tr(camp.arrive.steps[0].text)} {tr(camp.arrive.steps[1].text)} {said_n(camp)} {tr(camp.said[1])}`
out = out + ` {said_n(quiet)} {tr(quiet.arrive.steps[0].text)} {trf(k"hud.day", "3", "", "")}`
print(out)
}
}

View file

@ -0,0 +1,28 @@
# The source language of the nested keys example.
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
#. A raid's first step, at the camp.
msgid "raids.camp.arrive.steps.0.text"
msgstr "Find the tracks"
#. A raid's second step, at the camp.
msgid "raids.camp.arrive.steps.1.text"
msgstr "Count {1} footprints"
#. The quiet raid's only step.
msgid "raids.quiet.arrive.steps.0.text"
msgstr "Wait"
#. What Ada says when the camp is raided, first.
msgid "raids.camp.said.0"
msgstr "They came in the night."
#. What Ada says when the camp is raided, second.
msgid "raids.camp.said.1"
msgstr "Check the box."
#. The day on the HUD. {1} = the day number
msgid "hud.day"
msgstr "Day {1}"

View file

@ -0,0 +1,2 @@
# the nested text keys example (i18n_nested.ludic): lang/en.po is the source every key is checked against
lang "lang" en