lua-users home
lua-l archive

Re: compile-time globals

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Thomas Lauer <thomas.lauer <at> virgin.net> writes:
> ...I experimented with an extension to the parser to
> enable the declaration of globals at compile time, similar to what the
> local keyword does for local variables....
> However, I've run into a problem ...module() is a runtime feature and
> the compiler knows nothing about it
True, require/module will need to be a compile time construct.
I've updated LuaFish[1] (which was recently announced on this list) to do
something like this. Again, it's quite preliminary, but one of the included
examples is shown below.
First, a simple module is defined as follows:
<snip>
-- msquare.lua
local M = {}; M.__index = M
function M.create(length)
 local self = setmetatable({length = length}, M)
 return self
end
local function area(self) return self.length^2 end
M.area = area
local function perimeter(self) return self.length * 4 end
M.perimeter = perimeter
local function setcolor(self, color)
 SETTYPE(color, 'string') -- static type check argument
 self.color = color
end
M.setcolor = setcolor
-- The function inside the ONCOMPILE macro is executed at
-- compile time.
ONCOMPILE(function(scope) -- scope is a table of references to the
 -- AST's of lexicals at the current
 -- code location
 -- Static type definition of the class.
 local class = {}
 class.area = scope.area -- use static function signatures
 class.perimeter = scope.perimeter
 class.setcolor = scope.setcolor
 registerclass('Square', class)
end)
return M
</snip>
The function in the "ONCOMPILE" macro gets executed at what is effectively
compile time. This particular function builds a table of method names and their
signatures, which makes up the static type of a class that we register.
Next, another Lua program uses that module as follows:
<snip>
-- module_usage_m.lua
-- demonstrates static checking of class methods.
-- The function inside the ONCOMPILE macro is executed at
-- compile time.
ONCOMPILE(function()
 -- load type definitions at compile time to allow
 -- compile-time type checking.
 mrequire 'square_m'
end)
print 'begin'
local mrequire = require 'LuaFish.macro'.require
local Square = mrequire 'square_m'
local m = Square.create(5)
SETTYPE(m, 'Square') -- bind a static type to the lexical
assert(m:area() == 25) -- ok
assert(m:perimeter() == 20) -- ok
m:setcolor('blue') -- ok
-- this gives compile-time error:
-- "method volume absent in class Square"
-- print(m:volume())
-- this gives compile-time error:
-- "argument color type is number but expecting string"
-- m:setcolor(5)
print 'done'
</snip>
Doing the require inside the "ONCOMPILE" macro causes the types and method names
to be loaded at compile time. These types are then bound to a lexical at
compile time via the SETTYPE macro. This then permits compile-time detection of
the errors noted in the commented code at the end.
The ONCOMPILE macro is actually similar to the "BEGIN" block in Perl. Putting a
require inside an ONCOMPILE blocks is analogous to using a "use" [2] v.s.
"require" in Perl.
[1] LuaFish v. 0.2 - http://lua-users.org/wiki/LuaFish
[2] Perl "use" statement - http://perldoc.perl.org/functions/use.html

AltStyle によって変換されたページ (->オリジナル) /