[YARP] Implement compilation for Regex / InterpolatedRegex (#8396)

This commit is contained in:
Jemma Issroff 2023-09-08 12:09:30 -04:00 коммит произвёл GitHub
Родитель 8807b0dc96
Коммит af5df9ee5e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 45 добавлений и 4 удалений

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

@ -168,6 +168,12 @@ module YARP
assert_equal "1", compile('$yct = 1; "#$yct"') assert_equal "1", compile('$yct = 1; "#$yct"')
end end
def test_InterpolatedRegularExpressionNode
assert_equal /1 1 1/, compile('$yct = 1; /1 #$yct 1/')
assert_equal /1 3 1/, compile('/1 #{1 + 2} 1/')
assert_equal /1 2 3 1/, compile('/1 #{"2"} #{1 + 2} 1/')
end
def test_InterpolatedStringNode def test_InterpolatedStringNode
assert_equal "1 1 1", compile('$yct = 1; "1 #$yct 1"') assert_equal "1 1 1", compile('$yct = 1; "1 #$yct 1"')
assert_equal "1 3 1", compile('"1 #{1 + 2} 1"') assert_equal "1 3 1", compile('"1 #{1 + 2} 1"')
@ -183,6 +189,10 @@ module YARP
assert_equal "100", compile('`printf "100"`') assert_equal "100", compile('`printf "100"`')
end end
def test_RegularExpressionNode
assert_equal /yct/, compile('/yct/')
end
def test_StringConcatNode def test_StringConcatNode
# assert_equal "YARP::CompilerTest", compile('"YARP" "::" "CompilerTest"') # assert_equal "YARP::CompilerTest", compile('"YARP" "::" "CompilerTest"')
end end

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

@ -358,10 +358,6 @@ yp_interpolated_node_compile(yp_node_list_t parts, rb_iseq_t *iseq, NODE dummy_l
ADD_INSN(ret, &dummy_line_node, anytostring); ADD_INSN(ret, &dummy_line_node, anytostring);
} }
} }
if (parts_size > 1) {
ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
}
} }
else { else {
ADD_INSN(ret, &dummy_line_node, putnil); ADD_INSN(ret, &dummy_line_node, putnil);
@ -1298,15 +1294,34 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
} }
return; return;
} }
case YP_NODE_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
yp_interpolated_regular_expression_node_t *interp_regular_expression_node= (yp_interpolated_regular_expression_node_t *) node;
yp_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)));
}
return;
}
case YP_NODE_INTERPOLATED_STRING_NODE: { case YP_NODE_INTERPOLATED_STRING_NODE: {
yp_interpolated_string_node_t *interp_string_node = (yp_interpolated_string_node_t *) node; yp_interpolated_string_node_t *interp_string_node = (yp_interpolated_string_node_t *) node;
yp_interpolated_node_compile(interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); yp_interpolated_node_compile(interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context);
size_t parts_size = interp_string_node->parts.size;
if (parts_size > 1) {
ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
}
return; return;
} }
case YP_NODE_INTERPOLATED_SYMBOL_NODE: { case YP_NODE_INTERPOLATED_SYMBOL_NODE: {
yp_interpolated_symbol_node_t *interp_symbol_node = (yp_interpolated_symbol_node_t *) node; yp_interpolated_symbol_node_t *interp_symbol_node = (yp_interpolated_symbol_node_t *) node;
yp_interpolated_node_compile(interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); yp_interpolated_node_compile(interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context);
size_t parts_size = interp_symbol_node->parts.size;
if (parts_size > 1) {
ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
}
if (!popped) { if (!popped) {
ADD_INSN(ret, &dummy_line_node, intern); ADD_INSN(ret, &dummy_line_node, intern);
} }
@ -1321,6 +1336,12 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN(ret, &dummy_line_node, putself); ADD_INSN(ret, &dummy_line_node, putself);
yp_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, compile_context); yp_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, compile_context);
size_t parts_size = interp_x_string_node->parts.size;
if (parts_size > 1) {
ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
}
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE)); ADD_SEND_WITH_FLAG(ret, &dummy_line_node, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
if (popped) { if (popped) {
ADD_INSN(ret, &dummy_line_node, pop); ADD_INSN(ret, &dummy_line_node, pop);
@ -1631,6 +1652,16 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label); ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label);
return; return;
} }
case YP_NODE_REGULAR_EXPRESSION_NODE: {
if (!popped) {
yp_regular_expression_node_t *regular_expression_node = (yp_regular_expression_node_t *) node;
VALUE regex_str = parse_string(&regular_expression_node->unescaped);
// TODO: Replace 0 with regex options
VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), 0);
ADD_INSN1(ret, &dummy_line_node, putobject, regex);
}
return;
}
case YP_NODE_RETURN_NODE: { case YP_NODE_RETURN_NODE: {
yp_arguments_node_t *arguments = ((yp_return_node_t *)node)->arguments; yp_arguments_node_t *arguments = ((yp_return_node_t *)node)->arguments;