Skip to content
Permalink
Browse files
Change in the syntax of attributes
Attributes changed to posfixed ('x <const>', instead of '<const> x'),
and "toclose" renamed to "close". Posfixed attributes seem to make it
clearer that it applies to only one variable when there are multiple
variables.
  • Loading branch information
roberto-ieru committed Jul 30, 2019
1 parent b80077b commit 0d52913
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 102 deletions.
@@ -190,7 +190,7 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
** Create a new local variable with the given 'name'. Return its index
** in the function.
*/
static int new_localvar (LexState *ls, TString *name, int kind) {
static int new_localvar (LexState *ls, TString *name) {
lua_State *L = ls->L;
FuncState *fs = ls->fs;
Dyndata *dyd = ls->dyd;
@@ -200,14 +200,14 @@ static int new_localvar (LexState *ls, TString *name, int kind) {
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
var = &dyd->actvar.arr[dyd->actvar.n++];
var->vd.kind = kind;
var->vd.kind = VDKREG; /* default */
var->vd.name = name;
return dyd->actvar.n - 1 - fs->firstlocal;
}

#define new_localvarliteral(ls,v) \
new_localvar(ls, \
luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1), VDKREG);
luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));



@@ -947,7 +947,7 @@ static void parlist (LexState *ls) {
do {
switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */
new_localvar(ls, str_checkname(ls), VDKREG);
new_localvar(ls, str_checkname(ls));
nparams++;
break;
}
@@ -1553,7 +1553,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for state)");
new_localvar(ls, varname, VDKREG);
new_localvar(ls, varname);
checknext(ls, '=');
exp1(ls); /* initial value */
checknext(ls, ',');
@@ -1582,9 +1582,9 @@ static void forlist (LexState *ls, TString *indexname) {
new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for state)");
/* create declared variables */
new_localvar(ls, indexname, VDKREG);
new_localvar(ls, indexname);
while (testnext(ls, ',')) {
new_localvar(ls, str_checkname(ls), VDKREG);
new_localvar(ls, str_checkname(ls));
nvars++;
}
checknext(ls, TK_IN);
@@ -1708,7 +1708,7 @@ static void localfunc (LexState *ls) {
expdesc b;
FuncState *fs = ls->fs;
int fvar = fs->nactvar; /* function's variable index */
new_localvar(ls, str_checkname(ls), VDKREG); /* new local variable */
new_localvar(ls, str_checkname(ls)); /* new local variable */
adjustlocalvars(ls, 1); /* enter its scope */
body(ls, &b, 0, ls->linenumber); /* function created in next register */
/* debug information will only see the variable after this point! */
@@ -1723,7 +1723,7 @@ static int getlocalattribute (LexState *ls) {
checknext(ls, '>');
if (strcmp(attr, "const") == 0)
return RDKCONST; /* read-only variable */
else if (strcmp(attr, "toclose") == 0)
else if (strcmp(attr, "close") == 0)
return RDKTOCLOSE; /* to-be-closed variable */
else
luaK_semerror(ls,
@@ -1748,13 +1748,14 @@ static void localstat (LexState *ls) {
FuncState *fs = ls->fs;
int toclose = -1; /* index of to-be-closed variable (if any) */
Vardesc *var; /* last variable */
int ivar; /* index of last variable */
int ivar, kind; /* index and kind of last variable */
int nvars = 0;
int nexps;
expdesc e;
do {
int kind = getlocalattribute(ls);
ivar = new_localvar(ls, str_checkname(ls), kind);
ivar = new_localvar(ls, str_checkname(ls));
kind = getlocalattribute(ls);
getlocalvardesc(fs, ivar)->vd.kind = kind;
if (kind == RDKTOCLOSE) { /* to-be-closed? */
if (toclose != -1) /* one already present? */
luaK_semerror(ls, "multiple to-be-closed variables in local list");
@@ -1203,7 +1203,7 @@ end)
testamem("to-be-closed variables", function()
local flag
do
local <toclose> x =
local x <close> =
setmetatable({}, {__close = function () flag = true end})
flag = false
local x = {}
@@ -8,22 +8,22 @@ end
print "testing code generation and optimizations"

-- to test constant propagation
local <const> k0aux = 0
local <const> k0 = k0aux
local <const> k1 = 1
local <const> k3 = 3
local <const> k6 = k3 + (k3 << k0)
local <const> kFF0 = 0xFF0
local <const> k3_78 = 3.78
local <const> x, <const> k3_78_4 = 10, k3_78 / 4
local k0aux <const> = 0
local k0 <const> = k0aux
local k1 <const> = 1
local k3 <const> = 3
local k6 <const> = k3 + (k3 << k0)
local kFF0 <const> = 0xFF0
local k3_78 <const> = 3.78
local x, k3_78_4 <const> = 10, k3_78 / 4
assert(x == 10)

local <const> kx = "x"
local kx <const> = "x"

local <const> kTrue = true
local <const> kFalse = false
local kTrue <const> = true
local kFalse <const> = false

local <const> kNil = nil
local kNil <const> = nil

-- this code gave an error for the code checker
do
@@ -105,7 +105,7 @@ end, 'CLOSURE', 'NEWTABLE', 'EXTRAARG', 'GETTABUP', 'CALL',

-- sequence of LOADNILs
check(function ()
local <const> kNil = nil
local kNil <const> = nil
local a,b,c
local d; local e;
local f,g,h;
@@ -173,7 +173,7 @@ end,

-- "get/set table" with numeric indices
check(function (a)
local <const> k255 = 255
local k255 <const> = 255
a[1] = a[100]
a[k255] = a[256]
a[256] = 5
@@ -276,14 +276,14 @@ checkI(function () return ((100 << k6) << -4) >> 2 end, 100)

-- borders around MAXARG_sBx ((((1 << 17) - 1) >> 1) == 65535)
local a = 17; local sbx = ((1 << a) - 1) >> 1 -- avoid folding
local <const> border = 65535
local border <const> = 65535
checkI(function () return border end, sbx)
checkI(function () return -border end, -sbx)
checkI(function () return border + 1 end, sbx + 1)
checkK(function () return border + 2 end, sbx + 2)
checkK(function () return -(border + 1) end, -(sbx + 1))

local <const> border = 65535.0
local border <const> = 65535.0
checkF(function () return border end, sbx + 0.0)
checkF(function () return -border end, -sbx + 0.0)
checkF(function () return border + 1 end, (sbx + 1.0))
@@ -411,9 +411,9 @@ checkequal(function () return 6 and true or nil end,


do -- string constants
local <const> k0 = "00000000000000000000000000000000000000000000000000"
local k0 <const> = "00000000000000000000000000000000000000000000000000"
local function f1 ()
local <const> k = k0
local k <const> = k0
return function ()
return function () return k end
end
@@ -211,15 +211,15 @@ assert(a==1 and b==nil)
print'+';

do -- testing constants
local <const> prog = [[local <XXX> x = 10]]
local prog <const> = [[local x <XXX> = 10]]
checkload(prog, "unknown attribute 'XXX'")

checkload([[local <const> xxx = 20; xxx = 10]],
checkload([[local xxx <const> = 20; xxx = 10]],
":1: attempt to assign to const variable 'xxx'")

checkload([[
local xx;
local <const> xxx = 20;
local xxx <const> = 20;
local yyy;
local function foo ()
local abc = xx + yyy + xxx;
@@ -228,7 +228,7 @@ do -- testing constants
]], ":6: attempt to assign to const variable 'xxx'")

checkload([[
local <toclose> x = nil
local x <close> = nil
x = io.open()
]], ":2: attempt to assign to const variable 'x'")
end
@@ -304,15 +304,15 @@ if _ENV.GLOB1 == 0 then
basiccases[2][1] = "F" -- constant false

prog = [[
local <const> F = false
local F <const> = false
if %s then IX = true end
return %s
]]
else
basiccases[4][1] = "k10" -- constant 10

prog = [[
local <const> k10 = 10
local k10 <const> = 10
if %s then IX = true end
return %s
]]
@@ -322,12 +322,12 @@ print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')')


-- operators with their respective values
local <const> binops = {
local binops <const> = {
{" 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 <const> cases = {}
local cases <const> = {}

-- creates all combinations of '(cases[i] op cases[n-i])' plus
-- 'not(cases[i] op cases[n-i])' (syntax + value)
@@ -151,7 +151,7 @@ do
end

co = coroutine.create(function ()
local <toclose> x = func2close(function (self, err)
local x <close> = func2close(function (self, err)
assert(err == nil); X = false
end)
X = true
@@ -165,12 +165,12 @@ do
-- error closing a coroutine
local x = 0
co = coroutine.create(function()
local <toclose> y = func2close(function (self,err)
local y <close> = func2close(function (self,err)
if (err ~= 111) then os.exit(false) end -- should not happen
x = 200
error(200)
end)
local <toclose> x = func2close(function (self, err)
local x <close> = func2close(function (self, err)
assert(err == nil); error(111)
end)
coroutine.yield()
@@ -356,7 +356,7 @@ do

local X = false
A = coroutine.wrap(function()
local <toclose> _ = setmetatable({}, {__close = function () X = true end})
local _ <close> = setmetatable({}, {__close = function () X = true end})
return pcall(A, 1)
end)
st, res = A()
@@ -125,7 +125,7 @@ do
-- closing file by scope
local F = nil
do
local <toclose> f = assert(io.open(file, "w"))
local f <close> = assert(io.open(file, "w"))
F = f
end
assert(tostring(F) == "file (closed)")
@@ -135,7 +135,7 @@ assert(os.remove(file))

do
-- test writing/reading numbers
local <toclose> f = assert(io.open(file, "w"))
local f <close> = assert(io.open(file, "w"))
f:write(maxint, '\n')
f:write(string.format("0X%x\n", maxint))
f:write("0xABCp-3", '\n')
@@ -144,7 +144,7 @@ do
f:write(string.format("0x%X\n", -maxint))
f:write("-0xABCp-3", '\n')
assert(f:close())
local <toclose> f = assert(io.open(file, "r"))
local f <close> = assert(io.open(file, "r"))
assert(f:read("n") == maxint)
assert(f:read("n") == maxint)
assert(f:read("n") == 0xABCp-3)
@@ -158,7 +158,7 @@ assert(os.remove(file))

-- testing multiple arguments to io.read
do
local <toclose> f = assert(io.open(file, "w"))
local f <close> = assert(io.open(file, "w"))
f:write[[
a line
another line
@@ -170,18 +170,18 @@ three
]]
local l1, l2, l3, l4, n1, n2, c, dummy
assert(f:close())
local <toclose> f = assert(io.open(file, "r"))
local f <close> = 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())
local <toclose> f = assert(io.open(file, "r"))
local f <close> = 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())
local <toclose> f = assert(io.open(file, "r"))
local f <close> = 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)
@@ -258,7 +258,7 @@ do
::L2:: goto L3

::L1:: do
local <toclose> a = setmetatable({}, {__close = function () X = true end})
local a <close> = setmetatable({}, {__close = function () X = true end})
assert(X == nil)
if a then goto L2 end -- jumping back out of scope of 'a'
end

0 comments on commit 0d52913

Please sign in to comment.