diff options
author | Kevin Newton <kddnewton@gmail.com> | 2023-09-28 10:18:43 -0400 |
---|---|---|
committer | Kevin Newton <kddnewton@gmail.com> | 2023-09-28 14:11:34 -0400 |
commit | 5a376f0f71e8ecc8a6cc0b9f35e63a8367275988 (patch) | |
tree | 0df85eb75767314b37eaf3afaa0cff1c9f17de67 | |
parent | d3574c117a637a4456aa3ee78e24d8df510b9355 (diff) | |
download | ruby-5a376f0f71e8ecc8a6cc0b9f35e63a8367275988.tar.gz |
Consolidate regexp options, interpolated match last line
-rw-r--r-- | prism_compile.c | 82 | ||||
-rw-r--r-- | test/ruby/test_compile_prism.rb | 5 |
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(®ular_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(®ular_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 |