[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: adding match state to Lpeg
- From: "Fabio Mascarenhas" <mascarenhas@...>
- Date: Wed, 23 Jan 2008 05:00:40 -0200
I also have a suggestion for Lpeg, an optional parameter to match, a Lua object that gets passed as the first argument in any function captures, if present:
lpeg.match(_expression_, subject, idx, state)
If state is nil the function captures receive only the captures, as usual. This lets you write Lpeg parsers that have match-local state, instead of having to fake this with closures. It is specially useful with re-based parsers.
A patch to lpeg.c that implements this is attached.
--
Fabio Mascarenhas
--- lpeg.c 2007-10-10 15:56:59.000000000 -0300
+++ ../lpeg-0.7-patched/lpeg.c 2008-01-23 04:38:33.000000000 -0200
@@ -1648,6 +1648,7 @@
lua_State *L;
const char *s; /* original string */
int valuecached; /* value stored in cache slot */
+ int state;
} CapState;
@@ -1756,10 +1757,14 @@
static int functioncap (CapState *cs) {
- int n;
+ int n = 0;
int top = lua_gettop(cs->L);
pushluaval(cs);
- n = pushallcaptures(cs, 0);
+ if(cs->state != LUA_REFNIL) {
+ lua_rawgeti(cs->L, LUA_REGISTRYINDEX, cs->state);
+ n++;
+ }
+ n += pushallcaptures(cs, 0);
lua_call(cs->L, n, LUA_MULTRET);
return lua_gettop(cs->L) - top;
}
@@ -1883,17 +1888,18 @@
}
-static int getcaptures (lua_State *L, const char *s, const char *r) {
+static int getcaptures (lua_State *L, const char *s, const char *r, int state) {
Capture *capture = (Capture *)lua_touserdata(L, CAPLISTIDX);
CapState cs;
int n = 0;
- cs.cap = capture; cs.L = L; cs.s = s; cs.valuecached = 0;
+ cs.cap = capture; cs.L = L; cs.s = s; cs.valuecached = 0; cs.state = state;
while (!isclosecap(cs.cap))
n += pushcapture(&cs);
if (n == 0) { /* no captures? */
lua_pushinteger(L, r - s + 1); /* return only end position */
n = 1;
}
+ if(state != LUA_REFNIL) luaL_unref(L, LUA_REGISTRYINDEX, state);
return n;
}
@@ -1923,11 +1929,14 @@
static int matchl (lua_State *L) {
Capture capture[IMAXCAPTURES];
+ int state;
const char *r;
size_t l;
Instruction *p = getpatt(L, 1, NULL);
const char *s = luaL_checklstring(L, SUBJIDX, &l);
lua_Integer i = luaL_optinteger(L, 3, 1);
+ lua_pushvalue(L, 4);
+ state = luaL_ref(L, LUA_REGISTRYINDEX);
i = (i > 0) ?
((i <= (lua_Integer)l) ? i - 1 : (lua_Integer)l) :
(((lua_Integer)l + i >= 0) ? (lua_Integer)l + i : 0);
@@ -1940,7 +1949,7 @@
return 1;
}
assert(lua_gettop(L) == PENVIDX);
- return getcaptures(L, s, r);
+ return getcaptures(L, s, r, state);
}