Project

General

Profile

Feature #14973 ยป hash_expand.patch

osyo (manga osyo), 08/07/2018 03:00 PM

View differences:

ext/ripper/eventids2.c
ID ripper_id_words_beg;
ID ripper_id_qwords_beg;
ID ripper_id_qsymbols_beg;
ID ripper_id_hashexpand_beg;
ID ripper_id_symbols_beg;
ID ripper_id_words_sep;
ID ripper_id_rational;
......
set_id2(words_beg);
set_id2(qwords_beg);
set_id2(qsymbols_beg);
set_id2(hashexpand_beg);
set_id2(symbols_beg);
set_id2(words_sep);
set_id2(rational);
......
{tPOW, O(op)},
{tQWORDS_BEG, O(qwords_beg)},
{tQSYMBOLS_BEG, O(qsymbols_beg)},
{tHASHEXPAND_BEG, O(hashexpand_beg)},
{tSYMBOLS_BEG, O(symbols_beg)},
{tRATIONAL, O(rational)},
{tREGEXP_BEG, O(regexp_beg)},
parse.y
%type <node> singleton strings string string1 xstring regexp
%type <node> string_contents xstring_contents regexp_contents string_content
%type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
%type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word hashexpand hashexpand_list
%type <node> literal numeric simple_numeric dsym cpath
%type <node> top_compstmt top_stmts top_stmt begin_block
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
......
%token tDSTAR "**arg"
%token tAMPER "&"
%token tLAMBDA "->"
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tHASHEXPAND_BEG
%token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG tLABEL_END
/*
......
| qwords
| symbols
| qsymbols
| hashexpand
| var_ref
| backref
| tFID
......
| qwords
| symbols
| qsymbols
| hashexpand
| keyword_variable
{
/*%%%*/
......
}
;
hashexpand : tHASHEXPAND_BEG ' ' hashexpand_list tSTRING_END
{
/*%%%*/
$$ = new_hash(p, $3, &@$);
/*% %*/
/*% ripper: hash!($3) %*/
}
;
hashexpand_list : /* none */
{
/*%%%*/
$$ = 0;
/*% %*/
/*% ripper: hashexpand_new! %*/
}
| hashexpand_list string_content ' '
{
/*%%%*/
NODE *key, *val, *estr;
estr = evstr2dstr(p, $2);
estr = $2;
key = NEW_CALL(estr, rb_intern("to_sym"), 0, &@$);
val = NEW_FCALL(rb_intern("eval"), NEW_LIST(estr, &@$), &@$);
$$ = list_append(p, list_append(p, $1, key), val);
/*% %*/
/*% ripper: hashexpand_add!($1, $2) %*/
}
;
string_contents : /* none */
{
/*%%%*/
......
SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);
return tSYMBEG;
case 'h':
p->lex.strterm = NEW_STRTERM(str_dword, term, paren);
return tHASHEXPAND_BEG;
default:
yyerror0("unknown type of %string");
return 0;
test/ripper/dummyparser.rb
symbols.push Node::Sym.new(symbol)
end
def on_hashexpand_new
# NodeList.new
Node.new('assoc')
end
def on_hashexpand_add(hashexpand, str)
pp hashexpand
# hashexpand.push Node::Sym.new(str)
# hashexpand.push str
end
def on_mlhs_new
NodeList.new
end
test/ripper/test_parser_events.rb
assert_equal '[array([:a])]', tree
end
def test_hashexpand_add
thru_hasexpand_add = false
a = 1
b = 2
tree = parse('%h[a,b]', :on_hashexpand_add) {thru_hasexpand_add = true}
pp tree
# assert_equal true, thru_hasexpand_add
# assert_equal '[hash([:a,a,:b,b])]', tree
end
def test_qwords_new
thru_qwords_new = false
parse('%w[]', :on_qwords_new) {thru_qwords_new = true}
......
assert_equal true, thru_symbols_new
end
def test_hashexpand_new
thru_hashexpand_new = false
parse('%h[]', :on_hashexpand_new) {thru_hashexpand_new = true}
assert_equal true, thru_hashexpand_new
end
def test_redo
thru_redo = false
parse('redo', :on_redo) {thru_redo = true}
test/ripper/test_scanner_events.rb
scan('symbols_beg', "%I(\nw)")
end
def test_hashexpand_beg
assert_equal [],
scan('hashexpand_beg', '')
assert_equal ['%h('],
scan('hashexpand_beg', '%h()')
assert_equal ['%h('],
scan('hashexpand_beg', '%h(w w w)')
assert_equal ['%h('],
scan('hashexpand_beg', '%h( w w w )')
assert_equal ['%h('],
scan('hashexpand_beg', "%h(\nw)")
end
def test_words_sep
assert_equal [],
scan('words_sep', '')
test/ruby/test_parse.rb
assert_valid_syntax('let () { m(a) do; end }')
end
def test_hashexpand_meth
"test_hashexpand_meth"
end
def test_hashexpand
hoge = 1
foo = "str"
bar = nil
@test_hashexpand_value = { a: 1 }
@@test_hashexpand_value = [1, 2]
hash = %h(hoge foo bar @test_hashexpand_value @@test_hashexpand_value test_hashexpand_meth)
assert_equal(
hash,
{ hoge: 1, foo: "str", bar: nil, "@test_hashexpand_value": { a: 1}, "@@test_hashexpand_value": [1, 2], test_hashexpand_meth: "test_hashexpand_meth" }
)
assert_equal(
hash.keys,
%i(hoge foo bar @test_hashexpand_value @@test_hashexpand_value test_hashexpand_meth)
)
str = 42
pp %h(#{foo})
assert_equal(%h(#{foo}), { str: 42 })
assert_operator(Hash, :===, hash)
proc { |value|
hoge = -1
assert_equal(%h(hoge foo value), { hoge: -1, foo: "str", value: 42 })
}.call 42
assert_equal(%h(hoge foo hoge), { hoge: hoge, foo: foo })
assert_equal(%h(hoge foo hoge).keys, %i(hoge foo))
assert_raise(NameError) do
%h(not_found)
end
end
=begin
def test_past_scope_variable
assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}}
    (1-1/1)