Lunatic translator: qsprintf.

git-svn-id: https://svn.eduke32.com/eduke32@3507 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-02-18 16:07:59 +00:00
parent 740c8d021b
commit d1442ac88e
3 changed files with 90 additions and 7 deletions

View file

@ -486,6 +486,78 @@ function _qstrcat(qdst, qsrc)
cstr_dst[i] = 0
end
local buf = ffi.new("char [?]", MAXQUOTELEN)
function _qsprintf(qdst, qsrc, ...)
local dst = bcheck.quote_idx(qdst)
local src = bcheck.quote_idx(qsrc)
local vals = {...}
local i, j, vi = 0, 0, 0
while (true) do
local ch = src[j]
local didfmt = false
if (ch==0) then
break
end
if (ch=='%') then
local nch = src[j+1]
if (nch=='d' or (nch=='l' and src[j+2]=='d')) then
-- number
didfmt = true
if (vi == #vals) then
break
end
local numstr = tostring(vals[vi])
assert(type(numstr)=="string")
vi = vi+1
local ncopied = math.min(#numstr, MAXQUOTELEN-1-i)
ffi.copy(buf+i, numstr, ncopied)
i = i+ncopied
j = j+1+(nch=='d' and 1 or 2)
elseif (nch=='s') then
-- string
didfmt = true
if (vi == #vals) then
break
end
local k = -1
local tmpsrc = bcheck.quote_idx(vals[vi])
repeat
k = k+1
buf[i] = tmpsrc[k]
i = i+1
until (i < MAXQUOTELEN-1 and tmpsrc[k]~=0)
j = j+2
end
end
if (not didfmt) then
buf[i] = src[j]
i = i+1
j = j+1
end
if (i >= MAXQUOTELEN-1) then
break
end
end
buf[i] = 0
strcpy(dst, buf)
end
function _getkeyname(qdst, gfuncnum, which)
local cstr_dst = bcheck.quote_idx(qdst)

View file

@ -1351,6 +1351,10 @@ local function GetOrSetPerxvarCmd(Setp, Actorp)
end
local function n_s_fmt(n)
return string.rep("%s,", n-1).."%s"
end
-- Various inner command handling functions / string capture strings.
local handle =
{
@ -1398,6 +1402,11 @@ local handle =
v[1] or 0, v[2] or 0, v[3] or 0, v[4] or 0)
end,
qsprintf = function(qdst, qsrc, ...)
local codes = {...}
return format("_con._qsprintf(%d,%d,%s)", qdst, qsrc, table.concat(codes, ','))
end,
move = function(mv, ...)
local flags = {...}
return format(ACS":set_move(%s,%d)", mv, (flags[1] and bit.bor(...)) or 0)
@ -1428,10 +1437,6 @@ local handle =
soundonce = "_con._soundonce(_aci,%1)",
}
local function n_s_fmt(n)
return string.rep("%s,", n-1).."%s"
end
local userdef_common_pat = (arraypat + sp1)/{} * lpeg.Cc(0) * lpeg.Ct(singlememberpat) * sp1
-- NOTE about prefixes: most is handled by all_alt_pattern(), however commands
@ -1750,7 +1755,8 @@ local Cinner = {
/ "%3=_con._findnear(_aci,false,'d2',%1,%2)",
-- quotes
qsprintf = sp1 * tok.rvar * sp1 * tok.rvar * (sp1 * tok.rvar)^-32,
qsprintf = sp1 * tok.rvar * sp1 * tok.rvar * (sp1 * tok.rvar)^-32
/ handle.qsprintf,
qgetsysstr = cmd(R,R)
/ handle.NYI,
qstrcat = cmd(R,R)

View file

@ -51,7 +51,12 @@ onevent EVENT_ENTERLEVEL
getticks t2
subvarvar t2 t
redefinequote 114 %d x four 0..MAXSPITES-1 iterations took %d ms in total
qsprintf 115 114 n t2
// qsprintf test
redefinequote 116 0..MAXSPITES-1
redefinequote 117 in total
redefinequote 114 %d x four %s iterations took %d ms %s
qsprintf 115 /*<-*/ 114 /*args:*/ n 116 t2 117
echo 115
endevent