First implementation for 'const' variables

A variable can be declared const, which means it cannot be assigned to,
with the syntax 'local <const> name = exp'.
This commit is contained in:
Roberto Ierusalimschy
2019-05-17 11:11:44 -03:00
parent 347d6961ac
commit d9f40e3f6f
7 changed files with 207 additions and 58 deletions

View File

@@ -59,6 +59,41 @@ assert((x>y) and x or y == 2);
assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891)
do -- testing operators with diffent kinds of constants
-- operands to consider:
-- * fit in register
-- * constant doesn't fit in register
-- * floats with integral values
local operand = {3, 100, 5.0, -10, -5.0, 10000, -10000}
local operator = {"+", "-", "*", "/", "//", "%", "^",
"&", "|", "^", "<<", ">>",
"==", "~=", "<", ">", "<=", ">=",}
for _, op in ipairs(operator) do
local f = assert(load(string.format([[return function (x,y)
return x %s y
end]], op)))();
for _, o1 in ipairs(operand) do
for _, o2 in ipairs(operand) do
local gab = f(o1, o2)
_ENV.XX = o1
code = string.format("return XX %s %s", op, o2)
res = assert(load(code))()
assert(res == gab)
_ENV.XX = o2
local code = string.format("return (%s) %s XX", o1, op)
local res = assert(load(code))()
assert(res == gab)
code = string.format("return (%s) %s %s", o1, op, o2)
res = assert(load(code))()
assert(res == gab)
end
end
end
end
-- silly loops
repeat until 1; repeat until true;
@@ -175,6 +210,28 @@ assert(a==1 and b==nil)
print'+';
do -- testing constants
local <const> prog = [[local <XXX> x = 10]]
checkload(prog, "unknown attribute 'XXX'")
checkload([[local <const> xxx = 20; xxx = 10]],
":1: assignment to const variable 'xxx'")
checkload([[
local xx;
local <const> xxx = 20;
local yyy;
local function foo ()
local abc = xx + yyy + xxx;
return function () return function () xxx = yyy end end
end
]], ":6: assignment to const variable 'xxx'")
checkload([[
local <toclose> x = nil
x = io.open()
]], ":2: assignment to const variable 'x'")
end
f = [[
return function ( a , b , c , d , e )
@@ -245,12 +302,12 @@ print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')')
-- operators with their respective values
local binops = {
local <const> binops = {
{" and ", function (a,b) if not a then return a else return b end end},
{" or ", function (a,b) if a then return a else return b end end},
}
local cases = {}
local <const> cases = {}
-- creates all combinations of '(cases[i] op cases[n-i])' plus
-- 'not(cases[i] op cases[n-i])' (syntax + value)

View File

@@ -144,7 +144,7 @@ do
f:write(string.format("0x%X\n", -maxint))
f:write("-0xABCp-3", '\n')
assert(f:close())
f = assert(io.open(file, "r"))
local <toclose> f = assert(io.open(file, "r"))
assert(f:read("n") == maxint)
assert(f:read("n") == maxint)
assert(f:read("n") == 0xABCp-3)
@@ -170,18 +170,18 @@ three
]]
local l1, l2, l3, l4, n1, n2, c, dummy
assert(f:close())
f = assert(io.open(file, "r"))
local <toclose> f = assert(io.open(file, "r"))
l1, l2, n1, n2, dummy = f:read("l", "L", "n", "n")
assert(l1 == "a line" and l2 == "another line\n" and
n1 == 1234 and n2 == 3.45 and dummy == nil)
assert(f:close())
f = assert(io.open(file, "r"))
local <toclose> f = assert(io.open(file, "r"))
l1, l2, n1, n2, c, l3, l4, dummy = f:read(7, "l", "n", "n", 1, "l", "l")
assert(l1 == "a line\n" and l2 == "another line" and c == '\n' and
n1 == 1234 and n2 == 3.45 and l3 == "one" and l4 == "two"
and dummy == nil)
assert(f:close())
f = assert(io.open(file, "r"))
local <toclose> f = assert(io.open(file, "r"))
-- second item failing
l1, n1, n2, dummy = f:read("l", "n", "n", "l")
assert(l1 == "a line" and n1 == nil)

View File

@@ -3,10 +3,10 @@
print("testing numbers and math lib")
local minint = math.mininteger
local maxint = math.maxinteger
local <const> minint = math.mininteger
local <const> maxint = math.maxinteger
local intbits = math.floor(math.log(maxint, 2) + 0.5) + 1
local <const> intbits = math.floor(math.log(maxint, 2) + 0.5) + 1
assert((1 << intbits) == 0)
assert(minint == 1 << (intbits - 1))