mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
Lunatic t.: allow hex literals with >9 digits if the high ones are all 'F's.
(Or '0's, but that case is handled automatically.) The resulting generated number is taken by looking at the 8 lower nibbles and interpreting them as a signed 32-bit integer. Also add some number parsing tests to test/nlcf_break.con. git-svn-id: https://svn.eduke32.com/eduke32@3571 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
15d9165199
commit
d909173065
2 changed files with 43 additions and 9 deletions
|
@ -462,21 +462,33 @@ function warnprintf(fmt, ...) -- local
|
|||
end
|
||||
|
||||
local function parse_number(pos, numstr)
|
||||
-- <numstr> is a full number string, potentially prefixed with a minus sign.
|
||||
local num = tonumber((numstr:gsub("h$", "")))
|
||||
-- local onum = num
|
||||
local hex = numstr:match("0[xX]([^h]*)h?") -- get hex digits, if any
|
||||
|
||||
-- num==nil for Rio Lua, which doesn't handle large hex literals.
|
||||
if (num==nil or not (num >= -0x80000000 and num <= 0xffffffff)) then
|
||||
perrprintf(pos, "number %s out of the range of a 32-bit integer", numstr)
|
||||
-- Be careful not to write bound checks like
|
||||
-- "if (i<LOWBOUND or i>HIGHBOUND) then error('...') end":
|
||||
num = NaN
|
||||
elseif (num >= 0x80000000 and numstr:sub(1,2):lower()~="0x") then
|
||||
if (g_warn["number-conversion"]) then
|
||||
-- number is <INT32_MIN or >UINT32_MAX or NaN
|
||||
if (hex and #hex>8 and hex:sub(1,#hex-8):match("^[fF]$")) then
|
||||
-- Too many hex digits, but they're all Fs.
|
||||
pwarnprintf(pos, "number %s truncated to 32 bits", numstr)
|
||||
num = bit.band(num, 0xffffffff)
|
||||
else
|
||||
perrprintf(pos, "number %s out of the range of a 32-bit integer", numstr)
|
||||
-- Be careful not to write bound checks like
|
||||
-- "if (i<LOWBOUND or i>HIGHBOUND) then error('...') end":
|
||||
num = NaN
|
||||
end
|
||||
elseif (num >= 0x80000000) then
|
||||
if (not hex and g_warn["number-conversion"]) then
|
||||
pwarnprintf(pos, "number %s converted to a negative one", numstr)
|
||||
end
|
||||
num = num-(0xffffffff+1)
|
||||
num = bit.band(num, 0xffffffff)
|
||||
end
|
||||
|
||||
-- printf("numstr:%s, num=%d (0x%s) '%s', resnum=%d (0x%s)",
|
||||
-- numstr, onum, bit.tohex(onum), hex, num, bit.tohex(num))
|
||||
return num
|
||||
end
|
||||
|
||||
|
@ -2869,7 +2881,7 @@ local Grammar = Pat{
|
|||
|
||||
t_number = POS() * lpeg.C(
|
||||
tok.maybe_minus * ((Pat("0x") + "0X") * Range("09", "af", "AF")^1 * Pat("h")^-1
|
||||
+ Range("09")^1)
|
||||
+ Range("09")^1)
|
||||
) / parse_number,
|
||||
|
||||
t_identifier_all = lpeg.C(t_broken_identifier + t_good_identifier),
|
||||
|
@ -2935,7 +2947,7 @@ local Grammar = Pat{
|
|||
+ Keyw("whilevarn") * sp1 * tok.rvar * sp1 * tok.define / on.while_begin
|
||||
* sp1 * Var("single_stmt") * (lpeg.Cc(nil) / on.while_end),
|
||||
|
||||
stmt_common = Keyw("{") * sp1 * "}" / "do end" -- space separation of commands in CON is for a reason!
|
||||
stmt_common = Keyw("{") * sp1 * "}" / "" -- space separation of commands in CON is for a reason!
|
||||
+ Keyw("{") * sp1 * lpeg.Ct(stmt_list) * sp1 * "}"
|
||||
+ con_inner_command + Var("switch_stmt") + lpeg.Ct(Var("while_stmt")),
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// NOTE: This file is misnamed, "break" is local control flow, of course.
|
||||
|
||||
state teststate_break
|
||||
ifvare 1 1
|
||||
{
|
||||
|
@ -20,3 +22,23 @@ onevent EVENT_INIT
|
|||
redefinequote 114 STILL LIVE OUTER
|
||||
echo 114
|
||||
endevent
|
||||
|
||||
// Test number parsing
|
||||
gamevar MINUS_ONE -1 0
|
||||
gamevar INT32_MIN 0x80000000 0
|
||||
gamevar INT32_MIN_ -0x80000000 0
|
||||
gamevar INT32_MINh 0x80000000h 0
|
||||
gamevar INT32_MIN_h -0x80000000h 0
|
||||
|
||||
gamevar INT32_MIN_P1 0x80000001 0
|
||||
gamevar INT32_MIN_P1h 0x80000001h 0
|
||||
//gamevar INT32_MAX_ -0x80000001 0 // error
|
||||
|
||||
gamevar INT32_MAX 0x7fffffff 0
|
||||
gamevar INT32_MAXh 0x7fffffffh 0
|
||||
|
||||
// 9 digits? truncate it, but only because there's an F there.
|
||||
gamevar SOMEHEX 0xFFEFC0001 0
|
||||
|
||||
// This one throws an error:
|
||||
//gamevar BADHEX 0xBFEFC0001 0
|
||||
|
|
Loading…
Reference in a new issue