Consolidate regexp options, interpolated match last line

This commit is contained in:
Kevin Newton 2023-09-28 10:18:43 -04:00
Родитель d3574c117a
Коммит 5a376f0f71
2 изменённых файлов: 51 добавлений и 38 удалений

Просмотреть файл

@ -329,8 +329,7 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body,
if (node_body) {
pm_compile_node(iseq, (pm_node_t *)node_body, then_seq, src, popped, compile_context);
PM_POP_IF_POPPED;
}
else {
} else {
PM_PUTNIL_UNLESS_POPPED;
}
@ -589,6 +588,29 @@ pm_compile_multi_write_lhs(rb_iseq_t *iseq, NODE dummy_line_node, const pm_node_
return pushed;
}
/**
* Check the prism flags of a regular expression-like node and return the flags
* that are expected by the CRuby VM.
*/
static int
pm_reg_flags(const pm_node_t *node) {
int flags = 0;
if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
flags |= ONIG_OPTION_IGNORECASE;
}
if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
flags |= ONIG_OPTION_MULTILINE;
}
if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
flags |= ONIG_OPTION_EXTEND;
}
return flags;
}
/*
* Compiles a prism node into instruction sequences
*
@ -1386,13 +1408,23 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
return;
}
case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
pm_interpolated_regular_expression_node_t *interp_regular_expression_node= (pm_interpolated_regular_expression_node_t *) node;
pm_interpolated_node_compile(interp_regular_expression_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context);
if (interp_regular_expression_node->parts.size > 1) {
ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(0), INT2FIX((int)(interp_regular_expression_node->parts.size)));
}
case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: {
pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node;
pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, compile_context);
ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX((int) (cast->parts.size)));
ADD_INSN2(ret, &dummy_line_node, getspecial, INT2FIX(0), INT2FIX(0));
ADD_SEND(ret, &dummy_line_node, idEqTilde, INT2NUM(1));
PM_POP_IF_POPPED;
return;
}
case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node;
pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, compile_context);
ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX((int) (cast->parts.size)));
PM_POP_IF_POPPED;
return;
}
@ -1573,23 +1605,11 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
case PM_MATCH_LAST_LINE_NODE: {
if (!popped) {
pm_match_last_line_node_t *regular_expression_node = (pm_match_last_line_node_t *) node;
VALUE regex_str = parse_string(&regular_expression_node->unescaped);
int flags = 0;
pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node;
if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
flags |= ONIG_OPTION_IGNORECASE;
}
VALUE regex_str = parse_string(&cast->unescaped);
VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node));
if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
flags |= ONIG_OPTION_MULTILINE;
}
if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
flags |= ONIG_OPTION_EXTEND;
}
VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), flags);
ADD_INSN1(ret, &dummy_line_node, putobject, regex);
ADD_INSN2(ret, &dummy_line_node, getspecial, INT2FIX(0), INT2FIX(0));
ADD_SEND(ret, &dummy_line_node, idEqTilde, INT2NUM(1));
@ -1858,23 +1878,11 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
case PM_REGULAR_EXPRESSION_NODE: {
if (!popped) {
pm_regular_expression_node_t *regular_expression_node = (pm_regular_expression_node_t *) node;
VALUE regex_str = parse_string(&regular_expression_node->unescaped);
int flags = 0;
pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
flags |= ONIG_OPTION_IGNORECASE;
}
VALUE regex_str = parse_string(&cast->unescaped);
VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node));
if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
flags |= ONIG_OPTION_MULTILINE;
}
if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
flags |= ONIG_OPTION_EXTEND;
}
VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), flags);
ADD_INSN1(ret, &dummy_line_node, putobject, regex);
}
return;

Просмотреть файл

@ -245,8 +245,13 @@ module Prism
test_prism_eval('$pit = 1; "#$pit"')
end
def test_InterpolatedMatchLastLineNode
test_prism_eval("$pit = '.oo'; if /\#$pit/mix; end")
end
def test_InterpolatedRegularExpressionNode
test_prism_eval('$pit = 1; /1 #$pit 1/')
test_prism_eval('$pit = 1; /#$pit/i')
test_prism_eval('/1 #{1 + 2} 1/')
test_prism_eval('/1 #{"2"} #{1 + 2} 1/')
end