summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2023-09-28 10:18:43 -0400
committerKevin Newton <kddnewton@gmail.com>2023-09-28 14:11:34 -0400
commit5a376f0f71e8ecc8a6cc0b9f35e63a8367275988 (patch)
tree0df85eb75767314b37eaf3afaa0cff1c9f17de67
parentd3574c117a637a4456aa3ee78e24d8df510b9355 (diff)
Consolidate regexp options, interpolated match last line
-rw-r--r--prism_compile.c82
-rw-r--r--test/ruby/test_compile_prism.rb5
2 files changed, 50 insertions, 37 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 0e224f9044..3e88459d6a 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -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_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 *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)));
- }
+ 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;
-
- if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
- flags |= ONIG_OPTION_IGNORECASE;
- }
+ pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) 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_str = parse_string(&cast->unescaped);
+ VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node));
- 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;
-
- if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
- flags |= ONIG_OPTION_IGNORECASE;
- }
-
- if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
- flags |= ONIG_OPTION_MULTILINE;
- }
+ pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
- if (regular_expression_node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
- flags |= ONIG_OPTION_EXTEND;
- }
+ VALUE regex_str = parse_string(&cast->unescaped);
+ VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node));
- VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), flags);
ADD_INSN1(ret, &dummy_line_node, putobject, regex);
}
return;
diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb
index 2116218c69..d5a00a2a8e 100644
--- a/test/ruby/test_compile_prism.rb
+++ b/test/ruby/test_compile_prism.rb
@@ -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