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
 }