finding undefined globals

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

finding undefined globals

Luiz Henrique de Figueiredo
Motivated by a thread in the chat room (#lua) last week, I wrote a quick
hack for doing static analysis of Lua programs and flagging the use of
undefined globals. See the attached script, globals.lua. Since this
script performs static analysis based on the bytecode, it cannot find
all uses of undefined globals. For a tool that does that at run time,
see etc/strict.lua in the distribution. Enjoy.
--lhf
-- find undefined global vars
-- typical usage: luac -p -l *.lua | lua globals.lua

local S={}
local G={}
local F

while true do
 local s=io.read()
 if s==nil then break end
 local ok,_,f=string.find(s,"^[mf].-<(.-):%d+,%d+>")
 if ok then F=f end
 local ok,_,l,op,g=string.find(s,"%[%-?(%d*)%]%s*([GS])ETGLOBAL.-;%s+(.*)$")
 if ok then
  if op=="S" then S[g]=true else G[g]=F..":"..l end
 end
end

for k,v in next,G do
 if not S[k] and not _G[k] then
  io.write(k," may be undefined in ",v,"\n")
 end
end
Reply | Threaded
Open this post in threaded view
|

Re: finding undefined globals

Norman Ramsey-2
 > Motivated by a thread in the chat room (#lua) last week, I wrote a quick
 > hack for doing static analysis of Lua programs and flagging the use of
 > undefined globals. See the attached script, globals.lua. Since this
 > script performs static analysis based on the bytecode, it cannot find
 > all uses of undefined globals. For a tool that does that at run time,
 > see etc/strict.lua in the distribution. Enjoy.

Sweet.  To make it work for 5.0, change '%d+,%d+' to '[%d,]+'.


Norman

Reply | Threaded
Open this post in threaded view
|

Re: finding undefined globals

Luiz Henrique de Figueiredo
> To make it work for 5.0, change '%d+,%d+' to '[%d,]+'.

Yes, sorry, I forgot to mention that.  Thanks.

With a sightly bigger (and uglier) change, it can be made to work in
both versions. Something like this (untested):

 local F,P
 if string.find(_VERSION,"Lua 5%.0") then
  P="^[mf].-<(.-):%d+>"
 else
  P="^[mf].-<(.-):%d+,%d+>"
 end

 ...
  local ok,_,f=string.find(s,P)

Or perhaps just change the pattern to this (also untested):
  local ok,_,f=string.find(s,"^[mf].-<(.-):%d+,?%d*>")

--lhf

Reply | Threaded
Open this post in threaded view
|

Re: finding undefined globals

Luiz Henrique de Figueiredo
> > To make it work for 5.0, change '%d+,%d+' to '[%d,]+'.

Oops, I hadn't noticed the square brackets. A clever touch that makes
it work in both versions! --lhf

Reply | Threaded
Open this post in threaded view
|

Re: finding undefined globals

Fabian Peña
In reply to this post by Luiz Henrique de Figueiredo
This work are similar to lualint ?

http://lua-users.org/wiki/LuaLint

or specific for lua 5.1 ?







Luiz Henrique de Figueiredo wrote:
> Motivated by a thread in the chat room (#lua) last week, I wrote a quick
> hack for doing static analysis of Lua programs and flagging the use of
> undefined globals. See the attached script, globals.lua. Since this
> script performs static analysis based on the bytecode, it cannot find
> all uses of undefined globals. For a tool that does that at run time,
> see etc/strict.lua in the distribution. Enjoy.
> --lhf
> 
> 
> ------------------------------------------------------------------------
> 
> -- find undefined global vars
> -- typical usage: luac -p -l *.lua | lua globals.lua
> 
> local S={}
> local G={}
> local F
> 
> while true do
>  local s=io.read()
>  if s==nil then break end
>  local ok,_,f=string.find(s,"^[mf].-<(.-):%d+,%d+>")
>  if ok then F=f end
>  local ok,_,l,op,g=string.find(s,"%[%-?(%d*)%]%s*([GS])ETGLOBAL.-;%s+(.*)$")
>  if ok then
>   if op=="S" then S[g]=true else G[g]=F..":"..l end
>  end
> end
> 
> for k,v in next,G do
>  if not S[k] and not _G[k] then
>   io.write(k," may be undefined in ",v,"\n")
>  end
> end


Reply | Threaded
Open this post in threaded view
|

Re: finding undefined globals

Luiz Henrique de Figueiredo
> This work are similar to lualint ?
> 
> http://lua-users.org/wiki/LuaLint
> 
> or specific for lua 5.1 ?

Yes, it is similar but looks simpler than lualint. No, it's not specific
for Lua 5.1, as Norman pointed out. --lhf