aboutsummaryrefslogtreecommitdiff
path: root/Lua/lbp.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2021-09-24 22:55:39 -0700
committerBruce Hill <bruce@bruce-hill.com>2021-09-24 22:55:39 -0700
commitcfc53ea643156a9993d37e85b0be6611a614704a (patch)
treee2287f5216a54d28045d8df34f1caced00d25cf1 /Lua/lbp.c
parent0c5c4124a2052b017cc5d3e40d5b7f5bb3e3a8eb (diff)
Overhaul of lua API to use tables
Diffstat (limited to 'Lua/lbp.c')
-rw-r--r--Lua/lbp.c153
1 files changed, 76 insertions, 77 deletions
diff --git a/Lua/lbp.c b/Lua/lbp.c
index e45e8f3..9e5176e 100644
--- a/Lua/lbp.c
+++ b/Lua/lbp.c
@@ -51,78 +51,84 @@ static void push_matchstring(lua_State *L, match_t *m)
fclose(out);
}
-static int Ltostring(lua_State *L)
-{
- match_t **m = (match_t**)lua_touserdata(L, 1);
- push_matchstring(L, *m);
- return 1;
-}
+static void push_match(lua_State *L, match_t *m);
-static int Lgc(lua_State *L)
+static void set_capture_fields(lua_State *L, match_t *m, int *n)
{
- match_t **m = (match_t**)lua_touserdata(L, 1);
- recycle_if_unused(m);
- return 0;
+ if (m->pat->type == BP_CAPTURE) {
+ if (m->pat->args.capture.namelen > 0) {
+ lua_pushlstring(L, m->pat->args.capture.name, m->pat->args.capture.namelen);
+ push_match(L, m->children[0]);
+ lua_settable(L, -3);
+ } else {
+ push_match(L, m->children[0]);
+ lua_seti(L, -2, *(n++));
+ }
+ } else if (m->children) {
+ for (int i = 0; m->children[i]; i++)
+ set_capture_fields(L, m->children[i], n);
+ }
}
-static int Llen(lua_State *L)
+void push_match(lua_State *L, match_t *m)
{
- match_t **m = (match_t**)lua_touserdata(L, 1);
- lua_pushinteger(L, (int)((*m)->end - (*m)->start));
- return 1;
+ lua_createtable(L, 1, 0);
+ lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ lua_setmetatable(L, -2);
+ push_matchstring(L, m);
+ lua_seti(L, -2, 0);
+ int capture_num = 1;
+ for (int i = 0; m->children && m->children[i]; i++)
+ set_capture_fields(L, m->children[i], &capture_num);
}
-static int Lindex(lua_State *L)
+static int Ltostring(lua_State *L)
{
- match_t **m = (match_t**)lua_touserdata(L, 1);
- int type = lua_type(L, 2);
- match_t *ret = NULL;
- if (type == LUA_TNUMBER) {
- int n = luaL_checkinteger(L, 2);
- if (n == 0) {
- push_matchstring(L, *m);
- return 1;
- } else if (n > 0) {
- ret = get_numbered_capture(*m, n);
- }
- } else if (type == LUA_TSTRING) {
- size_t len;
- const char *name = luaL_checklstring(L, 2, &len);
- ret = get_named_capture(*m, name, len);
- }
-
- if (ret) {
- match_t **userdata = (match_t**)lua_newuserdatauv(L, sizeof(match_t*), 0);
- *userdata = ret;
- lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
- lua_gettable(L, LUA_REGISTRYINDEX);
- lua_setmetatable(L, -2);
- return 1;
- }
- return 0;
+ lua_geti(L, 1, 0);
+ return 1;
}
static const luaL_Reg Rinstance_metamethods[] =
{
- {"__len", Llen},
{"__tostring", Ltostring},
- {"__index", Lindex},
- {"__gc", Lgc},
{NULL, NULL}
};
-// static void push_match(lua_State *L, match_t *m)
-// {
-// lua_createtable(L, 0, 1);
-// lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
-// lua_gettable(L, LUA_REGISTRYINDEX);
-// lua_setmetatable(L, -2);
-
-// push_matchstring(L, m);
-// lua_rawseti(L, -2, 0);
-// int n = 1;
-// assign_captures(L, m, &n);
-// }
+static void recursive_free_pat(pat_t *pat)
+{
+ // Do a depth-first traversal, freeing everyting along the way:
+ if (!pat) return;
+ switch (pat->type) {
+ case BP_DEFINITION:
+ recursive_free_pat(pat->args.def.def);
+ recursive_free_pat(pat->args.def.pat);
+ break;
+ case BP_REPEAT:
+ recursive_free_pat(pat->args.repetitions.sep);
+ recursive_free_pat(pat->args.repetitions.repeat_pat);
+ break;
+ case BP_CHAIN: case BP_UPTO: case BP_UPTO_STRICT:
+ case BP_OTHERWISE: case BP_NOT_MATCH: case BP_MATCH:
+ recursive_free_pat(pat->args.multiple.first);
+ recursive_free_pat(pat->args.multiple.second);
+ break;
+ case BP_REPLACE:
+ recursive_free_pat(pat->args.replace.pat);
+ break;
+ case BP_CAPTURE:
+ recursive_free_pat(pat->args.capture.capture_pat);
+ break;
+ case BP_NOT: case BP_AFTER: case BP_BEFORE:
+ recursive_free_pat(pat->args.pat);
+ break;
+ case BP_LEFTRECURSION:
+ recursive_free_pat(pat->args.leftrec.fallback);
+ break;
+ default: break;
+ }
+ free_pat(pat);
+}
static int Lmatch(lua_State *L)
{
@@ -141,27 +147,16 @@ static int Lmatch(lua_State *L)
match_t *m = NULL;
int ret = 0;
- if (next_match(&m, builtins, text, &text[textlen], maybe_pat.value.pat, NULL, false)) {
-
- // lua_createtable(L, 0, 1);
-
- match_t **userdata = (match_t**)lua_newuserdatauv(L, sizeof(match_t*), 0);
- *userdata = m;
- lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
- lua_gettable(L, LUA_REGISTRYINDEX);
- lua_setmetatable(L, -2);
- // push_matchstring(L, text_file, m);
- // lua_rawseti(L, -2, 0);
- // int n = 1;
- // assign_captures(L, text_file, m, &n);
-
- lua_pushinteger(L, (int)(m->start - text) + index);
+ if (next_match(&m, builtins, text+index-1, &text[textlen], maybe_pat.value.pat, NULL, false)) {
+ push_match(L, m);
+ lua_pushinteger(L, (int)(m->start - text) + 1);
lua_pushinteger(L, (int)(m->end - m->start));
-
- // stop_matching(&m);
+ stop_matching(&m);
ret = 3;
}
+ recursive_free_pat(maybe_pat.value.pat);
+
return ret;
}
@@ -180,9 +175,10 @@ static int Lreplace(lua_State *L)
raise_parse_error(L, maybe_pat);
return 0;
}
- maybe_pat = bp_replacement(maybe_pat.value.pat, rep_text, rep_text + replen);
- if (!maybe_pat.success) {
- raise_parse_error(L, maybe_pat);
+ maybe_pat_t maybe_replacement = bp_replacement(maybe_pat.value.pat, rep_text, rep_text + replen);
+ if (!maybe_replacement.success) {
+ recursive_free_pat(maybe_pat.value.pat);
+ raise_parse_error(L, maybe_replacement);
return 0;
}
@@ -191,7 +187,7 @@ static int Lreplace(lua_State *L)
FILE *out = open_memstream(&buf, &size);
int replacements = 0;
const char *prev = text;
- for (match_t *m = NULL; next_match(&m, builtins, text, &text[textlen], maybe_pat.value.pat, NULL, false); ) {
+ for (match_t *m = NULL; next_match(&m, builtins, text, &text[textlen], maybe_replacement.value.pat, NULL, false); ) {
fwrite(prev, sizeof(char), (size_t)(m->start - prev), out);
fprint_match(out, text, m, NULL);
prev = m->end;
@@ -203,6 +199,9 @@ static int Lreplace(lua_State *L)
lua_pushinteger(L, replacements);
fclose(out);
+ // maybe_pat will get freed by this:
+ recursive_free_pat(maybe_replacement.value.pat);
+
return 2;
}