Skip to content

Commit

Permalink
[wip] + ruby28.y: endless method definition
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Apr 20, 2020
1 parent fcc3c26 commit 04769a4
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 5 deletions.
25 changes: 25 additions & 0 deletions doc/AST_FORMAT.md
Expand Up @@ -802,6 +802,31 @@ Format:
~~~~~~~~~~~~~~~~~ expression
~~~

### "Endless" method

Format:

~~~
(def_head :foo (args) (int 42))
"def foo = 42"
~~~ keyword
~~~ name
~~~~~~~~~~~~ expression
~~~


### "Endless" singleton method

Format:

~~~
(defs_head (self) :foo (args) (int 42))
"def self.foo = 42"
~~~ keyword
~~~ name
~~~~~~~~~~~~ expression
~~~

### Undefinition

Format:
Expand Down
2 changes: 1 addition & 1 deletion lib/parser/meta.rb
Expand Up @@ -16,7 +16,7 @@ module Meta
op_asgn and_asgn ensure rescue arg_expr
or_asgn back_ref nth_ref
match_with_lvasgn match_current_line
module class sclass def defs undef alias args
module class sclass def defs def_e defs_e undef alias args
cbase arg optarg restarg blockarg block_pass kwarg kwoptarg
kwrestarg kwnilarg send csend super zsuper yield block
and not or if when case while until while_post
Expand Down
26 changes: 22 additions & 4 deletions lib/parser/ruby28.y
Expand Up @@ -1232,10 +1232,10 @@ rule
@context.push(:def)
@current_arg_stack.push(nil)
}
f_arglist bodystmt kEND
f_args_body
{
result = @builder.def_method(val[0], val[1],
val[3], val[4], val[5])
*val[3])
@lexer.cmdarg.pop
@lexer.cond.pop
Expand All @@ -1255,10 +1255,10 @@ rule
@context.push(:defs)
@current_arg_stack.push(nil)
}
f_arglist bodystmt kEND
f_args_body
{
result = @builder.def_singleton(val[0], val[1], val[2],
val[4], val[6], val[7], val[8])
val[4], *val[6])
@lexer.cmdarg.pop
@lexer.cond.pop
Expand Down Expand Up @@ -2515,6 +2515,24 @@ keyword_variable: kNIL
result = nil
}
f_args_body: f_arglist bodystmt kEND
{
result = [ val[0], val[1], val[2] ]
}
| opt_f_arglist tEQL arg
{
result = [ val[0], val[2], nil ]
}
opt_f_arglist: f_arglist
{
result = [ val[0] ]
}
| # nothing
{
result = [@builder.args(nil, [], nil)]
}
f_arglist: tLPAREN2 f_args rparen
{
result = @builder.args(val[0], val[1], val[2])
Expand Down
10 changes: 10 additions & 0 deletions test/test_lexer.rb
Expand Up @@ -3569,6 +3569,16 @@ def test_ambiguous_integer_re
:tIDENTIFIER, 're', [1, 3])
end

def test_endless_method
setup_lexer(28)

assert_scanned('def foo = 42',
:kDEF, "def", [0, 3],
:tIDENTIFIER, 'foo', [4, 7],
:tEQL, "=", [8, 9],
:tINTEGER, 42, [10, 12])
end

def lex_numbered_parameter(input)
@lex.max_numparam_stack.push

Expand Down
50 changes: 50 additions & 0 deletions test/test_parser.rb
Expand Up @@ -9428,4 +9428,54 @@ def test_parser_bug_645
%{},
SINCE_1_9)
end

def test_endless_method
assert_parses(
s(:def_e, :foo,
s(:args),
s(:int, 42)),
%q{def foo = 42},
%q{~~~ keyword
| ~~~ name
|~~~~~~~~~~~~ expression},
SINCE_2_8)

assert_parses(
s(:def_e, :inc,
s(:args, s(:arg, :x)),
s(:send,
s(:lvar, :x), :+,
s(:int, 1))),
%q{def inc(x) = x + 1},
%q{~~~ keyword
| ~~~ name
| ~~~ args
|~~~~~~~~~~~~~~~~~~ expression},
SINCE_2_8)

assert_parses(
s(:defs_e, s(:send, nil, :obj), :foo,
s(:args),
s(:int, 42)),
%q{def obj.foo = 42},
%q{~~~ keyword
| ^ operator
| ~~~ name
|~~~~~~~~~~~~~~~~ expression},
SINCE_2_8)

assert_parses(
s(:defs_e, s(:send, nil, :obj), :inc,
s(:args, s(:arg, :x)),
s(:send,
s(:lvar, :x), :+,
s(:int, 1))),
%q{def obj.inc(x) = x + 1},
%q{~~~ keyword
| ~~~ name
| ^ operator
| ~~~ args
|~~~~~~~~~~~~~~~~~~~~~~ expression},
SINCE_2_8)
end
end

0 comments on commit 04769a4

Please sign in to comment.