I wants me my data types!!Posted: March 22, 2012
One of the challenges of programming in Lua is having precise control of data types. Or, rather, having the typical set of data types built in. The built in data types for Lua are quite sparse. For example, there is ‘number’, which is essentially a double. There is no separation for byte, short, int, float, just ‘number’. There is ‘string’, and that’s a catch all for bytes in general as it is 8-bit clean, as they say. But, what if I really want the semantics of an unsigned char, or short?
Well, that’s where LuaJIT can really be useful. First, you can do the following to declare some basic data types:
typedef unsigned char Byte;
typedef short Int16;
typedef int Int32;
typedef float Single;
typedef double Double;
Byte = ffi.typeof("Byte")
Int16 = ffi.typeof("Int16")
Int32 = ffi.typeof("Int32")
Single = ffi.typeof("Single")
Double = ffi.typeof("Double")
Then you can do the following to create instances of those types:
local val1 = Int16(30)
local val2 = Byte(15)
local val3 = Double(val1 + val2)
I think this is useful. You can go ahead and use the variables with the expected semantics of each type. It would be nice if you could go further and actually use bitwise operators, but, since that’s not really baked into Lua, you can’t really do it. The bitwise operators are defined against the ‘number’ type, so, you have to convert back tonumber, in order to use them:
local bits1 = Byte(0x01)
local bits2 = Byte(0x10)
local bitsor = bor(tonumber(bits1), tonumber(bits2))
local bitsand = band(tonumber(bits1), tonumber(bits2))
local bitsplus = bits1+bits2
But, if you’re not dealing with bitwise operators, and you’re just passing things around, consuming them, doing calculations and the like, you can actually get away with doing things as I’ve done here. So, it depends on how you’re programming. If you find yourself doing a lot of interop programming, you might find it useful to create these native data type declarations. That way, when it comes time to martial, you won’t always be converting from number, and your interop will be faster. If you are spending most of your time within Lua, not doing interop, then it’s probably better just to stick with the native ‘number’ type instead.
And so it goes. If you want a more traditional feel to your programming, LuaJIT makes it fairly easy. Otherwise, you can just stick with the standard way of doing things. In some sense, LuaJIT seems like the new “C” to me. It allows you to construct any manner of higher level abstractions, while at the same time allowing you to get down pretty low to the machine representation of things.
There is another gem in the LuaJIT firmament, and that is the Dynasm assembler. Not something you can use from LuaJIT directly, but with it you can fairly easily incorporate C and assembly routines together, and that’s got to be useful as well. But, another time.