diff --git a/src/bindings/lua/hammer.lua b/src/bindings/lua/hammer.lua index 2ee1656a098633801610a4ee181366d13dd69d10..d2c3632b958ae1d3b012883f264335d7652f5c57 100644 --- a/src/bindings/lua/hammer.lua +++ b/src/bindings/lua/hammer.lua @@ -140,11 +140,51 @@ local function append(a, ...) return helper(a, select('#', ...), ...) end +-- Exponents do a lot of heavy lifting in Lpeg, +-- which is the overloading template we're going to follow +local function __exp(rule, power) + assert(type(power) == "number") + if power == 0 then + return h.h_many(rule) + elseif power == 1 then + return h.h_many1(rule) + elseif power == -1 then + return h.h_optional(rule) + end +end + + local mt = { __index = { parse = function(p, str) return h.h_parse(p, str, #str) end, }, + __add = function(left, right) + return h.h_choice(left, right) + end, + __mul = function(left, right) + return h.h_sequence(left, right) + end, + __exp = __exp, + __len = function(rule) + return h.h_and(rule) + end, + __unm = function(rule) + return h.h_not(rule) + end, + __sub = function(left, right) + return h.h_sequence(left, h.h_not(right)) + end, + -- Lpeg doesn't use modulus, let's use it for n number of + -- repetitions + __mod = function(rule, reps) + assert(type(reps) == "number") + return h.h_repeat_n(rule, reps) + end, + __div = function(rule, cb) + return hammer.action(rule, cb) + end } + local hammer = {} hammer.parser = ffi.metatype("HParser", mt) @@ -155,10 +195,10 @@ local arr_mt = { end, __len = function(table) return table.used end, __ipairs = function(table) - local i, n = 0, #table + local i, n = -1, #table return function() i = i + 1 - if i <= n then + if i < n then return i, table.elements[i] end end @@ -166,7 +206,7 @@ local arr_mt = { __call = function(self) ret = {} for i, v in ipairs(self) - do ret[#ret+1] = v + do ret[#ret+1] = v() end return ret end @@ -196,7 +236,7 @@ local tok_mt = { elseif self.token_type == ffi.C.TT_UINT then return tonumber(ffi.cast("uintptr_t", ffi.cast("void *", self.uint))) elseif self.token_type == ffi.C.TT_SEQUENCE then - return self.seq() + return self.seq end end }