Skip to content

Commit

Permalink
Fix SEGV in method(arg) { expr }
Browse files Browse the repository at this point in the history
  • Loading branch information
hasumikin committed May 19, 2021
1 parent 5095088 commit 8f98dd2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
18 changes: 12 additions & 6 deletions src/ruby-lemon-parse/parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,12 @@
switch (Node_atomType(a)) {
case ATOM_call:
case ATOM_fcall:
n = a->cons.cdr->cons.cdr->cons.cdr;
/* TODO: Ambiguous node structure should be tidied up */
if (a->cons.cdr->cons.cdr->cons.cdr) {
n = a->cons.cdr->cons.cdr->cons.cdr;
} else {
n = a->cons.cdr->cons.cdr;
}
if (!n->cons.car) {
n->cons.car = new_first_arg(p, b);
} else {
Expand Down Expand Up @@ -713,8 +718,9 @@ command_call ::= block_command.
block_command ::= block_call.

command(A) ::= operation(B) command_args(C). [LOWEST] { A = new_fcall(p, B, C); }
command(A) ::= primary_value(B) call_op(C) operation2(D) command_args(E).
{ A = new_call(p, B, D, E, C); }
command(A) ::= primary_value(B) call_op(C) operation2(D) command_args(E). {
A = new_call(p, B, D, E, C);
}
command(A) ::= KW_return call_args(B). { A = new_return(p, ret_args(p, B)); }
command(A) ::= KW_break call_args(B). { A = new_break(p, ret_args(p, B)); }
command(A) ::= KW_next call_args(B). { A = new_next(p, ret_args(p, B)); }
Expand Down Expand Up @@ -1134,9 +1140,9 @@ f_block_arg(A) ::= blkarg_mark IDENTIFIER(B). {
A = B;
}

//opt_args_tail(A) ::= COMMA args_tail(B). {
// A = B;
// }
opt_args_tail(A) ::= COMMA args_tail(B). {
A = B;
}
opt_args_tail(A) ::= . {
A = new_args_tail(p, 0, 0, 0);
}
Expand Down
20 changes: 18 additions & 2 deletions test/def_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,26 @@ def my_method(arg = 'default')
RUBY

desc "def method with a mandatory arg and an optional arg"
assert_equal(<<~RUBY, "hey\nyou\n")
assert_equal(<<~RUBY, "hey\nyou")
def my_method(marg, opt = 'optional')
puts marg, opt
end
puts my_method('hey', 'you')
my_method('hey', 'you')
RUBY

desc "marg, optarg and block"
assert_equal(<<~RUBY, "1")
def m(a,b,&block)
block.call
end
m(8,9) { puts 1 }
RUBY

desc "marg, optarg and block / part.2"
assert_equal(<<~RUBY, "8\n9")
def m(a,b,&block)
block.call(a,b)
end
m(8,9) { |x, y| puts x, y }
RUBY
end

0 comments on commit 8f98dd2

Please sign in to comment.