Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion jsregexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ static int regex_closure(lua_State *lstate)

struct regex *r = lua_touserdata(lstate, lua_upvalueindex(1));
const int global = lre_get_flags(r->bc) & LRE_FLAG_GLOBAL;
const int named_groups = lre_get_flags(r->bc) & LRE_FLAG_NAMED_GROUPS;
const int capture_count = lre_get_capture_count(r->bc);

const uint8_t *input = (uint8_t *) luaL_checkstring(lstate, 1);
Expand Down Expand Up @@ -64,11 +65,32 @@ static int regex_closure(lua_State *lstate)
lua_setfield(lstate, -2, "end_ind");

lua_newtable(lstate);

const char* group_names = NULL;
if (named_groups) {
lua_newtable(lstate);
group_names = lre_get_groupnames(r->bc);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just push the table for named groups here so we don't have to pop it later. Need to switch the stack indexes -2 and -3 in the loop, of course.

Copy link
Author

@nathanrpage97 nathanrpage97 Aug 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhh I’m not quite sure how to do this without having some sort of ternarys to specify stack position based on if named groups is true

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have made this clearer. If the table of the normal indexed matches is on top, one can always access it with rawseti(lstate, -2, ...). If named_groups is true, have the table of named groups below that so it is accessed with setfield(lstate, -3, ...). Just make sure you push a second table when named_groups is true.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated it to work somewhat as you describe. I'm pretty sure you have to do some branching for stack positions as is done here

}
for (int i = 1; i < capture_count; i++) {
lua_pushlstring(lstate, (char *) capture[2 * i], capture[2 * i + 1] - capture[2 * i]);
lua_rawseti(lstate, -2, i);
if (named_groups && group_names != NULL) {
if (*group_names != '\0') { // check if current group is named
lua_pushlstring(lstate, (char *) capture[2 * i], capture[2 * i + 1] - capture[2 * i]);
lua_setfield(lstate, -3, group_names);
group_names += strlen(group_names) + 1; // move to the next group name
} else {
group_names += 1; // move to the next group name
}
}
}

if (named_groups) {
lua_setfield(lstate, -3, "groups");
lua_setfield(lstate, -2, "named_groups");
} else {
lua_setfield(lstate, -2, "groups");
}
lua_setfield(lstate, -2, "groups");

lua_rawseti(lstate, -2, ++nmatch);

Expand Down Expand Up @@ -116,6 +138,7 @@ static int jsregexp_compile(lua_State *lstate)
switch (*(flags++)) {
case 'i': re_flags |= LRE_FLAG_IGNORECASE; break;
case 'g': re_flags |= LRE_FLAG_GLOBAL; break;
case 'n': re_flags |= LRE_FLAG_NAMED_GROUPS; break;
default: /* unknown flag */;
}
}
Expand Down
17 changes: 17 additions & 0 deletions test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ local function test(str, regex, flags, want)
return
end
end
if want.named_groups ~= nil then
if val.named_groups == nil then
fails = fails + 1
return
end
for k,v in pairs(want.named_groups) do
if val.named_groups[k] ~= v then
fails = fails + 1
print(string.format("named group mismatch group '%s': expected '%s', actual '%s'", k, v, val.named_groups[k]))
return
end
end
end
end
successes = successes + 1
elseif not want and not r then
Expand Down Expand Up @@ -77,6 +90,10 @@ test("The quick brown fox jumps over the lazy dog", "\\w+", "", {{"The"}})
test("The quick brown fox jumps over the lazy dog", "\\w+", "g", {{"The"}, {"quick"}, {"brown"}, {"fox"}, {"jumps"}, {"over"}, {"the"}, {"lazy"}, {"dog"}})
test("The quick brown fox jumps over the lazy dog", "[aeiou]{2,}", "g", {{"ui"}})

test("The quick brown fox jumps over the lazy dog", "(?<first_word>\\w+) (\\w+) (?<third_word>\\w+)", "n",
{{"The quick brown", groups={"The", "quick", "brown"}, named_groups={first_word="The", third_word="brown"}}}
)

local bold_green = "\27[1;32m"
local bold_red = "\27[1;31m"
local normal = "\27[0m"
Expand Down