ludic.i18n: inside a bracket an argument's bytes ride raw - trf escapes a 27 or 31 only outside brackets, and the decoder unescapes only there, so a bracketed line carrying a key with holes (Ada's brief: its legend line's escaped arguments) keeps its own escapes whichever way it was put in (a game's txt_key raw, or trf). 81e1f7d8 unescaped inside the bracket and split the legend's arguments out of the brief. nest_test holds a key whose hole holds a key with two holes: bare, bracketed raw, bracketed through trf, and escaped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
81e1f7d8e6
commit
986fba3586
3 changed files with 35 additions and 6 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
# keyed_args.ludic - a key's arguments as the decoder reads them: unescaped, looked up while still English, a count
|
# keyed_args.ludic - a key's arguments as the decoder reads them: unescaped, looked up while still English, a count
|
||||||
|
|
||||||
# an argument as it was handed in: each 27 before a 27 or a 31 taken off
|
# an argument as it was handed in: each 27 before a 27 or a 31 taken off, outside a bracket only (a
|
||||||
|
# bracketed line inside it was carried raw, and its own escapes are its own)
|
||||||
@alloc_ok("a key made into text (a cache miss): an argument that held a key with holes")
|
@alloc_ok("a key made into text (a cache miss): an argument that held a key with holes")
|
||||||
function kr_unescape(s: string) -> string {
|
function kr_unescape(s: string) -> string {
|
||||||
var esc = false
|
var esc = false
|
||||||
|
|
@ -8,9 +9,11 @@ function kr_unescape(s: string) -> string {
|
||||||
if not esc { return s }
|
if not esc { return s }
|
||||||
let buf = buffer(len(s))
|
let buf = buffer(len(s))
|
||||||
var n = 0
|
var n = 0
|
||||||
|
var d = 0
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < len(s) {
|
while i < len(s) {
|
||||||
if s[i] == I18N_ESC and i + 1 < len(s) { i += 1 }
|
d = kx_depth(d, s[i])
|
||||||
|
if d == 0 and s[i] == I18N_ESC and i + 1 < len(s) { i += 1 }
|
||||||
buf[n] = s[i]
|
buf[n] = s[i]
|
||||||
n += 1
|
n += 1
|
||||||
i += 1
|
i += 1
|
||||||
|
|
|
||||||
|
|
@ -63,16 +63,23 @@ function kx_sep(buf: []byte, at: int) -> int {
|
||||||
buf[at] = I18N_SEP
|
buf[at] = I18N_SEP
|
||||||
return at + 1
|
return at + 1
|
||||||
}
|
}
|
||||||
# an argument's bytes, a 27 before each 27 or 31 of its own, so a key with holes can be one
|
# an argument's bytes, a 27 before each 27 or 31 of its own outside any bracket (a bracketed line's
|
||||||
|
# bytes are its own and ride raw, 29 .. 30 delimit it), so a key with holes can be one
|
||||||
function kx_len(s: string) -> int {
|
function kx_len(s: string) -> int {
|
||||||
var n = len(s)
|
var n = len(s)
|
||||||
for i in 0 .. len(s) { if s[i] == I18N_SEP or s[i] == I18N_ESC { n += 1 } }
|
var d = 0
|
||||||
|
for i in 0 .. len(s) {
|
||||||
|
d = kx_depth(d, s[i])
|
||||||
|
if d == 0 and (s[i] == I18N_SEP or s[i] == I18N_ESC) { n += 1 }
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
function kx_arg(buf: []byte, at: int, s: string) -> int {
|
function kx_arg(buf: []byte, at: int, s: string) -> int {
|
||||||
var j = at
|
var j = at
|
||||||
|
var d = 0
|
||||||
for i in 0 .. len(s) {
|
for i in 0 .. len(s) {
|
||||||
if s[i] == I18N_SEP or s[i] == I18N_ESC {
|
d = kx_depth(d, s[i])
|
||||||
|
if d == 0 and (s[i] == I18N_SEP or s[i] == I18N_ESC) {
|
||||||
buf[j] = I18N_ESC
|
buf[j] = I18N_ESC
|
||||||
j += 1
|
j += 1
|
||||||
}
|
}
|
||||||
|
|
@ -81,6 +88,12 @@ function kx_arg(buf: []byte, at: int, s: string) -> int {
|
||||||
}
|
}
|
||||||
return j
|
return j
|
||||||
}
|
}
|
||||||
|
# how deep in brackets a byte leaves the reader
|
||||||
|
function kx_depth(d: int, c: int) -> int {
|
||||||
|
if c == I18N_OPEN { return d + 1 }
|
||||||
|
if c == I18N_CLOSE and d > 0 { return d - 1 }
|
||||||
|
return d
|
||||||
|
}
|
||||||
function kx_put(buf: []byte, at: int, s: string) -> int {
|
function kx_put(buf: []byte, at: int, s: string) -> int {
|
||||||
for i in 0 .. len(s) { buf[at + i] = s[i] }
|
for i in 0 .. len(s) { buf[at + i] = s[i] }
|
||||||
return at + len(s)
|
return at + len(s)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ program I18nNestTest {
|
||||||
numbers float
|
numbers float
|
||||||
function q(s: string) -> string { return "\"" + s + "\"" }
|
function q(s: string) -> string { return "\"" + s + "\"" }
|
||||||
function po_line(id: string, tr: string) -> string { return "msgid " + q(id) + "\nmsgstr " + q(tr) + "\n\n" }
|
function po_line(id: string, tr: string) -> string { return "msgid " + q(id) + "\nmsgstr " + q(tr) + "\n\n" }
|
||||||
function en() -> string { return po_line("hud.day", "Day {1}") + po_line("pause.quit", "Quit") + po_line("shop.ada", "Ada: {1}") }
|
function en() -> string { return po_line("hud.day", "Day {1}") + po_line("pause.quit", "Quit") + po_line("shop.ada", "Ada: {1}") + po_line("lore.talk", "{1} is back, {2}.") + po_line("lore.brief", "{1} {2} {3}") }
|
||||||
function tt() -> string { return po_line("hud.day", "{1}. Gun") + po_line("pause.quit", "Cik") + po_line("Settings", "Ayarlar") }
|
function tt() -> string { return po_line("hud.day", "{1}. Gun") + po_line("pause.quit", "Cik") + po_line("Settings", "Ayarlar") }
|
||||||
function b(s: string) -> string {
|
function b(s: string) -> string {
|
||||||
let o = buffer(1)
|
let o = buffer(1)
|
||||||
|
|
@ -39,4 +39,17 @@ program I18nNestTest {
|
||||||
expect(L(i18n_st, "Quit" + text_of(c, 1)) == "Quit")
|
expect(L(i18n_st, "Quit" + text_of(c, 1)) == "Quit")
|
||||||
expect(kx_nested("Quit") == false)
|
expect(kx_nested("Quit") == false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "a key whose hole holds a key with two holes, bare, bracketed as a game's txt_key puts it, or in trf" (i18n_st: mut I18nState) {
|
||||||
|
start(i18n_st)
|
||||||
|
let talk = trf(k"lore.talk", "Old Maroon", "under the far shore", "", "")
|
||||||
|
let brief = trf(k"lore.brief", "Lightning.", talk, tr(k"pause.quit"), "")
|
||||||
|
let whole = "Lightning. Old Maroon is back, under the far shore. Quit"
|
||||||
|
expect(L(i18n_st, brief) == whole)
|
||||||
|
let sep = buffer(1)
|
||||||
|
sep[0] = I18N_SEP
|
||||||
|
expect(L(i18n_st, b(tr(k"shop.ada") + text_of(sep, 1) + b(brief))) == "Ada: " + whole) # txt_key's shape: raw inside
|
||||||
|
expect(L(i18n_st, trf(k"shop.ada", b(brief), "", "", "")) == "Ada: " + whole)
|
||||||
|
expect(L(i18n_st, trf(k"shop.ada", brief, "", "", "")) == "Ada: " + whole)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue