aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2021-09-26 14:34:06 -0700
committerBruce Hill <bruce@bruce-hill.com>2021-09-26 14:34:06 -0700
commita96284615b27226f4d34de8dfa7235f0c14ac1d4 (patch)
tree26b22ed8c48297087e8ca6bdcf7516ab4aa88430
parent6b29503e9583f1a598c1fb9d6617d422a7e4f7be (diff)
Added __concat and __div
-rw-r--r--Lua/README.md4
-rw-r--r--Lua/lbp.c51
2 files changed, 51 insertions, 4 deletions
diff --git a/Lua/README.md b/Lua/README.md
index d1d516b..da8b7a6 100644
--- a/Lua/README.md
+++ b/Lua/README.md
@@ -31,7 +31,9 @@ unambiguous.
Pattern objects returned by `bp.compile()` are pre-compiled patterns that are
slightly faster to reuse than just calling `bp.match()` repeatedly. They have
-`:match()`, `:replace()`, and `:matches()` methods as described above.
+`:match()`, `:replace()`, and `:matches()` methods as described above, as well
+as a `:getsource()` method that returns the original source used to make the
+pattern.
All methods will raise an error with a descriptive message if the given pattern
has a syntax error.
diff --git a/Lua/lbp.c b/Lua/lbp.c
index 1ef7684..269e851 100644
--- a/Lua/lbp.c
+++ b/Lua/lbp.c
@@ -52,7 +52,6 @@ static int Lcompile(lua_State *L)
*pat_storage = maybe_pat.value.pat;
lua_pushvalue(L, 1);
lua_setiuservalue(L, -2, 1);
-
lua_pushlightuserdata(L, (void*)&PAT_METATABLE);
lua_gettable(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
@@ -114,7 +113,7 @@ static int Lmatch(lua_State *L)
lua_replace(L, 1);
}
pat_t **at_pat = lua_touserdata(L, 1);
- pat_t *pat = *at_pat;
+ pat_t *pat = at_pat ? *at_pat : NULL;
if (!pat) luaL_error(L, "Not a valid pattern");
size_t textlen;
@@ -150,7 +149,7 @@ static int Lreplace(lua_State *L)
lua_replace(L, 1);
}
pat_t **at_pat = lua_touserdata(L, 1);
- pat_t *pat = *at_pat;
+ pat_t *pat = at_pat ? *at_pat : NULL;
if (!pat) luaL_error(L, "Not a valid pattern");
size_t replen, textlen;
@@ -249,6 +248,50 @@ static int Lpat_gc(lua_State *L)
return 0;
}
+static int Lpat_join(lua_State *L, const char *joiner)
+{
+ if (!lua_isstring(L, 1)) {
+ lua_pushcfunction(L, Lpat_source);
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 1);
+ lua_replace(L, 1);
+ }
+ if (!lua_isstring(L, 2)) {
+ lua_pushcfunction(L, Lpat_source);
+ lua_pushvalue(L, 2);
+ lua_call(L, 1, 1);
+ lua_replace(L, 2);
+ }
+
+ lua_pushcfunction(L, Lcompile);
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ luaL_addstring(&b, "(");
+ lua_pushvalue(L, 1);
+ luaL_addvalue(&b);
+ luaL_addstring(&b, ")");
+ luaL_addstring(&b, joiner);
+ luaL_addstring(&b, "(");
+ lua_pushvalue(L, 2);
+ luaL_addvalue(&b);
+ luaL_addstring(&b, ")");
+
+ luaL_pushresult(&b);
+ lua_call(L, 1, 1);
+
+ return 1;
+}
+
+static int Lpat_concat(lua_State *L)
+{
+ return Lpat_join(L, " ");
+}
+
+static int Lpat_div(lua_State *L)
+{
+ return Lpat_join(L, " / ");
+}
+
static const luaL_Reg match_metamethods[] = {
{"__tostring", Lmatch_tostring},
{NULL, NULL}
@@ -264,6 +307,8 @@ static const luaL_Reg pat_methods[] = {
static const luaL_Reg pat_metamethods[] = {
{"__gc", Lpat_gc},
+ {"__concat", Lpat_concat},
+ {"__div", Lpat_div},
{"__tostring", Lpat_tostring},
{"__index", NULL}, // placeholder for pat_methods
{NULL, NULL}