LiquidProxy Lua Edition
at master 125 lines 3.1 kB view raw
1--[[ 2make lua functions for each operator. 3it looks like i'm mapping 1-1 between metamethods and fields in this table. 4useful for using Lua as a functional language. 5 6TODO rename to 'ops'? 7--]] 8 9--local load = require 'string'.load -- string.load = loadstring or load 10local load = loadstring or load 11 12-- test if we hae lua 5.3 bitwise operators 13-- orrr I could just try each op and bail out on error 14-- and honestly I should be defaulting to the 'bit' library anyways, esp in the case of luajit where it is translated to an asm opcode 15local lua53 = _VERSION >= 'Lua 5.3' 16 17local symbolscode = [[ 18 19 -- which fields are unary operators 20 local unary = { 21 unm = true, 22 bnot = true, 23 len = true, 24 lnot = true, 25 } 26 27 local symbols = { 28 add = '+', 29 sub = '-', 30 mul = '*', 31 div = '/', 32 mod = '%', 33 pow = '^', 34 unm = '-', -- unary 35 concat = '..', 36 eq = '==', 37 ne = '~=', 38 lt = '<', 39 le = '<=', 40 gt = '>', 41 ge = '>=', 42 land = 'and', -- non-overloadable 43 lor = 'or', -- non-overloadable 44 len = '#', -- unary 45 lnot = 'not', -- non-overloadable, unary 46]] 47if lua53 then 48 symbolscode = symbolscode .. [[ 49 idiv = '//', -- 5.3 50 band = '&', -- 5.3 51 bor = '|', -- 5.3 52 bxor = '~', -- 5.3 53 shl = '<<', -- 5.3 54 shr = '>>', -- 5.3 55 bnot = '~', -- 5.3, unary 56]] 57--[[ alternatively, luajit 'bit' library: 58I should probably include all of these instead 59would there be a perf hit from directly assigning these functions to my own table, 60 as there is a perf hit for assigning from ffi.C func ptrs to other variables? probably. 61 how about as a tail call / vararg forwarding? 62I wonder if luajit adds extra metamethods 63 64luajit 2.0 lua 5.2 lua 5.3 65band band & 66bnot bnot ~ 67bor bor | 68bxor bxor ~ 69lshift lshift << 70rshift rshift >> 71arshift arshift 72rol lrotate 73ror rrotate 74bswap (reverses 32-bit integer endian-ness of bytes) 75tobit (converts from lua number to its signed 32-bit value) 76tohex (string conversion) 77 btest (does some bitflag stuff) 78 extract (same) 79 replace (same) 80--]] 81end 82symbolscode = symbolscode .. [[ 83 } 84]] 85 86local symbols, unary = assert(load(symbolscode..' return symbols, unary'))() 87 88local code = symbolscode .. [[ 89 -- functions for operators 90 local ops 91 ops = { 92]] 93for name,symbol in pairs(symbols) do 94 if unary[name] then 95 code = code .. [[ 96 ]]..name..[[ = function(a) return ]]..symbol..[[ a end, 97]] 98 else 99 code = code .. [[ 100 ]]..name..[[ = function(a,b) return a ]]..symbol..[[ b end, 101]] 102 end 103end 104code = code .. [[ 105 index = function(t, k) return t[k] end, 106 newindex = function(t, k, v) 107 t[k] = v 108 return t, k, v -- ? should it return anything ? 109 end, 110 call = function(f, ...) return f(...) end, 111 112 symbols = symbols, 113 114 -- special pcall wrapping index, thanks luajit. thanks. 115 -- while i'm here, multiple indexing, so it bails out nil early, so it's a chained .? operator 116 safeindex = function(t, ...) 117 if select('#', ...) == 0 then return t end 118 local res, v = pcall(ops.index, t, ...) 119 if not res then return nil, v end 120 return ops.safeindex(v, select(2, ...)) 121 end, 122 } 123 return ops 124]] 125return assert(load(code))()