parse.y: rb_parser_set_options

* parse.y (yycompile0): append top-level addenda before appending
  prelude nodes.

* parse.y (rb_parser_set_options): set top-level addendum options
  before parsing.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60393 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-10-24 07:41:48 +00:00
Родитель 184845f2cd
Коммит 30f5c55890
3 изменённых файлов: 41 добавлений и 74 удалений

3
node.h
Просмотреть файл

@ -448,8 +448,7 @@ VALUE rb_parser_encoding(VALUE);
VALUE rb_parser_get_yydebug(VALUE);
VALUE rb_parser_set_yydebug(VALUE, VALUE);
VALUE rb_parser_dump_tree(NODE *node, int comment);
NODE *rb_parser_append_print(VALUE, NODE *);
NODE *rb_parser_while_loop(VALUE, NODE *, int, int);
void rb_parser_set_options(VALUE, int, int, int, int);
NODE *rb_parser_compile_cstr(VALUE, const char*, const char*, int, int);
NODE *rb_parser_compile_string(VALUE, const char*, VALUE, int);

99
parse.y
Просмотреть файл

@ -234,6 +234,11 @@ struct parser_params {
#ifndef RIPPER
/* Ruby core only */
unsigned int do_print: 1;
unsigned int do_loop: 1;
unsigned int do_chomp: 1;
unsigned int do_split: 1;
NODE *eval_tree_begin;
NODE *eval_tree;
VALUE error_buffer;
@ -5398,6 +5403,8 @@ vtable_included(const struct vtable * tbl, ID id)
static void parser_prepare(struct parser_params *parser);
#ifndef RIPPER
static NODE *parser_append_options(struct parser_params *parser, NODE *node);
static VALUE
debug_lines(VALUE fname)
{
@ -5492,10 +5499,11 @@ yycompile0(VALUE arg)
else {
VALUE opt = parser->compile_option;
NODE *prelude;
NODE *body = parser_append_options(parser, tree->nd_body);
if (!opt) opt = rb_obj_hide(rb_ident_hash_new());
rb_hash_aset(opt, rb_sym_intern_ascii_cstr("coverage_enabled"), cov);
prelude = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body, opt);
nd_set_column(prelude, nd_column(tree->nd_body));
prelude = NEW_PRELUDE(ruby_eval_tree_begin, body, opt);
nd_set_column(prelude, nd_column(body));
tree->nd_body = prelude;
}
return (VALUE)tree;
@ -11237,78 +11245,43 @@ parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALUE *
#endif
#ifndef RIPPER
NODE*
rb_parser_append_print(VALUE vparser, NODE *node)
void
rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
{
NODE *prelude = 0;
NODE *scope = node;
struct parser_params *parser;
if (!node) return node;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
node = node->nd_body;
if (nd_type(node) == NODE_PRELUDE) {
prelude = node;
node = node->nd_body;
}
node = block_append(node,
new_fcall(rb_intern("print"),
NEW_ARRAY(new_gvar(idLASTLINE, 0)), 0),
0);
if (prelude) {
prelude->nd_body = node;
scope->nd_body = prelude;
}
else {
scope->nd_body = node;
}
return scope;
parser->do_print = print;
parser->do_loop = loop;
parser->do_chomp = chomp;
parser->do_split = split;
}
NODE *
rb_parser_while_loop(VALUE vparser, NODE *node, int chomp, int split)
static NODE *
parser_append_options(struct parser_params *parser, NODE *node)
{
NODE *prelude = 0;
NODE *scope = node;
struct parser_params *parser;
if (!node) return node;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
node = node->nd_body;
if (nd_type(node) == NODE_PRELUDE) {
prelude = node;
node = node->nd_body;
}
if (split) {
node = block_append(NEW_GASGN(rb_intern("$F"),
new_call(new_gvar(idLASTLINE, 0),
rb_intern("split"), 0, 0)),
node, 0);
}
if (chomp) {
node = block_append(new_call(new_gvar(idLASTLINE, 0),
rb_intern("chomp!"), 0, 0), node, 0);
if (parser->do_print) {
node = block_append(node,
new_fcall(rb_intern("print"),
NEW_ARRAY(new_gvar(idLASTLINE, 0)), 0),
0);
}
node = NEW_OPT_N(node);
if (parser->do_loop) {
if (parser->do_split) {
node = block_append(NEW_GASGN(rb_intern("$F"),
new_call(new_gvar(idLASTLINE, 0),
rb_intern("split"), 0, 0)),
node, 0);
}
if (parser->do_chomp) {
node = block_append(new_call(new_gvar(idLASTLINE, 0),
rb_intern("chomp!"), 0, 0), node, 0);
}
if (prelude) {
prelude->nd_body = node;
scope->nd_body = prelude;
}
else {
scope->nd_body = node;
node = NEW_OPT_N(node);
}
return scope;
return node;
}
void

13
ruby.c
Просмотреть файл

@ -1646,6 +1646,10 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
/* need to acquire env from toplevel_binding each time, since it
* may update after eval() */
base_block = toplevel_context(toplevel_binding);
rb_parser_set_context(parser, base_block, TRUE);
rb_parser_set_options(parser, opt->do_print, opt->do_loop, opt->do_line, opt->do_split);
if (opt->e_script) {
VALUE progname = rb_progname;
rb_encoding *eenc;
@ -1669,15 +1673,10 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
require_libraries(&opt->req_list);
}
ruby_set_script_name(progname);
base_block = toplevel_context(toplevel_binding);
rb_parser_set_context(parser, base_block, TRUE);
tree = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
}
else {
VALUE f;
base_block = toplevel_context(toplevel_binding);
rb_parser_set_context(parser, base_block, TRUE);
f = open_load_file(script_name, &opt->xflag);
tree = load_file(parser, opt->script_name, f, 1, opt);
}
@ -1715,11 +1714,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
if (!dump) return Qtrue;
}
if (opt->do_print) {
tree = rb_parser_append_print(parser, tree);
}
if (opt->do_loop) {
tree = rb_parser_while_loop(parser, tree, opt->do_line, opt->do_split);
rb_define_global_function("sub", rb_f_sub, -1);
rb_define_global_function("gsub", rb_f_gsub, -1);
rb_define_global_function("chop", rb_f_chop, 0);