Question

Lua conditional evaluation of new language operators

I'm writing a Wireshark dissector in Lua for a custom packet type and Wireshark versions including Lua 5.2 and below (current release versions) have the BitOp library included, whereas upcoming releases will have Lua 5.3 or greater and will use builtin bitwise operations.

My goal is to have this changeover automatically handled by Lua version without having to update the dissector for each version. My current code is:

local bit = nil
if tonumber(string.sub(_VERSION, 5)) < 5.3 then
    bit = require("bit")
end

local version_byte = 0xaf
if bit then
    print("BitOp method")
else
    print((version_byte >> 4) * 10 + (version_byte & 0xf))
end

The issue is that Lua 5.2 (of course) doesn't recognize the bitwise shift and & operators and throws unexpected symbol near '>'. Is there a way to conditionally evaluate something like this?

 3  94  3
1 Jan 1970

Solution

 3

You could write a couple of compatibility shim modules that define a common interface to the bit operations: one that defines functions that perform bit operations in pre-5.3 Lua, and one that defines functions for 5.3 and later which use the built-in operators under the hood:

-- bit_shim_5_2.lua
-- Defines a common interface to bit operations.
local M = {}

function M.bitop ()
   print("Lua pre-5.3 bit ops")
end

return M
-- bit_shim_5_3.lua
-- Defines a common interface to bit operations.
local M = {}

function M.bitop ()
   print("built-in Lua 5.3 bit ops")
end

return M
-- main.lua
local bit = nil
local version = tonumber(string.sub(_VERSION, 5))
if version < 5.3 then
   bit = require("bit_shim_5_2")
else
   bit = require("bit_shim_5_3")
end

bit.bitop()

Running this program on Lua 5.4.7 yields:

$ lua main.lua
built-in Lua 5.3 bit ops
2024-07-05
ad absurdum

Solution

 2

This is conditional compilation. Of course, you can.

if bit then
    print("BitOp method")
else
    load[[
        -- arbitrary chunk of code
        print((version_byte >> 4) * 10 + (version_byte & 0xf))
    ]]()
end

However, this will cause problems with access to locals (e.g. local version_byte). So you'll have to rewrite your code accordingly.

2024-07-05
Matt