parser 2.6.4.1 → 2.7.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +16 -10
- data/CHANGELOG.md +134 -0
- data/README.md +8 -1
- data/doc/AST_FORMAT.md +384 -20
- data/lib/parser.rb +3 -1
- data/lib/parser/ast/processor.rb +19 -0
- data/lib/parser/base.rb +19 -0
- data/lib/parser/builders/default.rb +250 -12
- data/lib/parser/context.rb +4 -0
- data/lib/parser/current.rb +7 -7
- data/lib/parser/current_arg_stack.rb +43 -0
- data/lib/parser/lexer.rl +116 -83
- data/lib/parser/lexer/dedenter.rb +52 -49
- data/lib/parser/macruby.y +1 -1
- data/lib/parser/{lexer/max_numparam_stack.rb → max_numparam_stack.rb} +10 -4
- data/lib/parser/messages.rb +35 -29
- data/lib/parser/meta.rb +7 -2
- data/lib/parser/ruby18.y +1 -1
- data/lib/parser/ruby19.y +1 -1
- data/lib/parser/ruby20.y +1 -1
- data/lib/parser/ruby21.y +1 -1
- data/lib/parser/ruby22.y +1 -1
- data/lib/parser/ruby23.y +1 -1
- data/lib/parser/ruby24.y +1 -1
- data/lib/parser/ruby25.y +1 -1
- data/lib/parser/ruby26.y +1 -1
- data/lib/parser/ruby27.y +496 -36
- data/lib/parser/rubymotion.y +1 -1
- data/lib/parser/source/tree_rewriter.rb +1 -1
- data/lib/parser/source/tree_rewriter/action.rb +2 -2
- data/lib/parser/static_environment.rb +10 -0
- data/lib/parser/variables_stack.rb +32 -0
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +7 -0
- data/test/helper.rb +1 -0
- data/test/parse_helper.rb +3 -0
- data/test/test_lexer.rb +18 -69
- data/test/test_parser.rb +1875 -111
- data/test/test_source_comment_associator.rb +20 -20
- metadata +10 -4
data/lib/parser/macruby.y
CHANGED
@@ -2,17 +2,23 @@
|
|
2
2
|
|
3
3
|
module Parser
|
4
4
|
|
5
|
-
class
|
5
|
+
class MaxNumparamStack
|
6
|
+
attr_reader :stack
|
7
|
+
|
6
8
|
def initialize
|
7
9
|
@stack = []
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
12
|
+
def has_ordinary_params!
|
11
13
|
set(-1)
|
12
14
|
end
|
13
15
|
|
14
|
-
def
|
15
|
-
top
|
16
|
+
def has_ordinary_params?
|
17
|
+
top < 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_numparams?
|
21
|
+
top > 0
|
16
22
|
end
|
17
23
|
|
18
24
|
def register(numparam)
|
data/lib/parser/messages.rb
CHANGED
@@ -31,42 +31,48 @@ module Parser
|
|
31
31
|
:heredoc_id_has_newline => 'here document identifier across newlines, never match',
|
32
32
|
:heredoc_id_ends_with_nl => 'here document identifier ends with a newline',
|
33
33
|
:unterminated_heredoc_id => 'unterminated heredoc id',
|
34
|
-
:leading_zero_in_numparam => 'leading zero is not allowed as a numbered parameter',
|
35
|
-
:numparam_outside_block => 'numbered parameter outside block',
|
36
|
-
:too_large_numparam => 'too large numbered parameter',
|
37
|
-
:ordinary_param_defined => 'ordinary parameter is defined',
|
38
34
|
|
39
35
|
# Lexer warnings
|
40
36
|
:invalid_escape_use => 'invalid character syntax; use ?%{escape}',
|
41
37
|
:ambiguous_literal => 'ambiguous first argument; put parentheses or a space even after the operator',
|
42
38
|
:ambiguous_prefix => "`%{prefix}' interpreted as argument prefix",
|
39
|
+
:triple_dot_at_eol => '... at EOL, should be parenthesized',
|
43
40
|
|
44
41
|
# Parser errors
|
45
|
-
:nth_ref_alias
|
46
|
-
:begin_in_method
|
47
|
-
:backref_assignment
|
48
|
-
:invalid_assignment
|
49
|
-
:module_name_const
|
50
|
-
:unexpected_token
|
51
|
-
:argument_const
|
52
|
-
:argument_ivar
|
53
|
-
:argument_gvar
|
54
|
-
:argument_cvar
|
55
|
-
:duplicate_argument
|
56
|
-
:empty_symbol
|
57
|
-
:odd_hash
|
58
|
-
:singleton_literal
|
59
|
-
:dynamic_const
|
60
|
-
:const_reassignment
|
61
|
-
:module_in_def
|
62
|
-
:class_in_def
|
63
|
-
:unexpected_percent_str
|
64
|
-
:block_and_blockarg
|
65
|
-
:masgn_as_condition
|
66
|
-
:block_given_to_yield
|
67
|
-
:invalid_regexp
|
68
|
-
:invalid_return
|
69
|
-
:csend_in_lhs_of_masgn
|
42
|
+
:nth_ref_alias => 'cannot define an alias for a back-reference variable',
|
43
|
+
:begin_in_method => 'BEGIN in method',
|
44
|
+
:backref_assignment => 'cannot assign to a back-reference variable',
|
45
|
+
:invalid_assignment => 'cannot assign to a keyword',
|
46
|
+
:module_name_const => 'class or module name must be a constant literal',
|
47
|
+
:unexpected_token => 'unexpected token %{token}',
|
48
|
+
:argument_const => 'formal argument cannot be a constant',
|
49
|
+
:argument_ivar => 'formal argument cannot be an instance variable',
|
50
|
+
:argument_gvar => 'formal argument cannot be a global variable',
|
51
|
+
:argument_cvar => 'formal argument cannot be a class variable',
|
52
|
+
:duplicate_argument => 'duplicate argument name',
|
53
|
+
:empty_symbol => 'empty symbol literal',
|
54
|
+
:odd_hash => 'odd number of entries for a hash',
|
55
|
+
:singleton_literal => 'cannot define a singleton method for a literal',
|
56
|
+
:dynamic_const => 'dynamic constant assignment',
|
57
|
+
:const_reassignment => 'constant re-assignment',
|
58
|
+
:module_in_def => 'module definition in method body',
|
59
|
+
:class_in_def => 'class definition in method body',
|
60
|
+
:unexpected_percent_str => '%{type}: unknown type of percent-literal',
|
61
|
+
:block_and_blockarg => 'both block argument and literal block are passed',
|
62
|
+
:masgn_as_condition => 'multiple assignment in conditional context',
|
63
|
+
:block_given_to_yield => 'block given to yield',
|
64
|
+
:invalid_regexp => '%{message}',
|
65
|
+
:invalid_return => 'Invalid return in class/module body',
|
66
|
+
:csend_in_lhs_of_masgn => '&. inside multiple assignment destination',
|
67
|
+
:cant_assign_to_numparam => 'cannot assign to numbered parameter %{name}',
|
68
|
+
:ordinary_param_defined => 'ordinary parameter is defined',
|
69
|
+
:numparam_used_in_outer_scope => 'numbered parameter is already used in an outer scope',
|
70
|
+
:circular_argument_reference => 'circular argument reference %{var_name}',
|
71
|
+
:pm_interp_in_var_name => 'symbol literal with interpolation is not allowed',
|
72
|
+
:lvar_name => "`%{name}' is not allowed as a local variable name",
|
73
|
+
:undefined_lvar => "no such local variable: `%{name}'",
|
74
|
+
:duplicate_variable_name => 'duplicate variable name %{name}',
|
75
|
+
:duplicate_pattern_key => 'duplicate hash pattern key %{name}',
|
70
76
|
|
71
77
|
# Parser warnings
|
72
78
|
:useless_else => 'else without rescue is useless',
|
data/lib/parser/meta.rb
CHANGED
@@ -24,9 +24,14 @@ module Parser
|
|
24
24
|
kwbegin begin retry preexe postexe iflipflop eflipflop
|
25
25
|
shadowarg complex rational __FILE__ __LINE__ __ENCODING__
|
26
26
|
ident root lambda indexasgn index procarg0
|
27
|
-
|
27
|
+
restarg_expr blockarg_expr
|
28
28
|
objc_kwarg objc_restarg objc_varargs
|
29
|
-
numargs numblock
|
29
|
+
numargs numblock forward_args forwarded_args
|
30
|
+
case_match in_match in_pattern
|
31
|
+
match_var pin match_alt match_as match_rest
|
32
|
+
array_pattern match_with_trailing_comma array_pattern_with_tail
|
33
|
+
hash_pattern const_pattern if_guard unless_guard match_nil_pattern
|
34
|
+
empty_else
|
30
35
|
).map(&:to_sym).to_set.freeze
|
31
36
|
|
32
37
|
end # Meta
|
data/lib/parser/ruby18.y
CHANGED
data/lib/parser/ruby19.y
CHANGED
data/lib/parser/ruby20.y
CHANGED
data/lib/parser/ruby21.y
CHANGED
data/lib/parser/ruby22.y
CHANGED
data/lib/parser/ruby23.y
CHANGED
data/lib/parser/ruby24.y
CHANGED
data/lib/parser/ruby25.y
CHANGED
data/lib/parser/ruby26.y
CHANGED
data/lib/parser/ruby27.y
CHANGED
@@ -17,7 +17,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
|
|
17
17
|
tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
|
18
18
|
tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
|
19
19
|
tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
|
20
|
-
tRATIONAL tIMAGINARY tLABEL_END tANDDOT
|
20
|
+
tRATIONAL tIMAGINARY tLABEL_END tANDDOT tBDOT2 tBDOT3
|
21
21
|
|
22
22
|
prechigh
|
23
23
|
right tBANG tTILDE tUPLUS
|
@@ -39,7 +39,7 @@ prechigh
|
|
39
39
|
nonassoc kDEFINED
|
40
40
|
right kNOT
|
41
41
|
left kOR kAND
|
42
|
-
nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
|
42
|
+
nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD kIN
|
43
43
|
nonassoc tLBRACE_ARG
|
44
44
|
nonassoc tLOWEST
|
45
45
|
preclow
|
@@ -87,7 +87,7 @@ rule
|
|
87
87
|
else_t, else_ = val[2]
|
88
88
|
ensure_t, ensure_ = val[3]
|
89
89
|
|
90
|
-
if rescue_bodies.empty? && !
|
90
|
+
if rescue_bodies.empty? && !else_t.nil?
|
91
91
|
diagnostic :error, :useless_else, nil, else_t
|
92
92
|
end
|
93
93
|
|
@@ -283,7 +283,21 @@ rule
|
|
283
283
|
{
|
284
284
|
result = @builder.not_op(val[0], nil, val[1], nil)
|
285
285
|
}
|
286
|
-
| arg
|
286
|
+
| arg kIN
|
287
|
+
{
|
288
|
+
@lexer.state = :expr_beg
|
289
|
+
@lexer.command_start = false
|
290
|
+
pattern_variables.push
|
291
|
+
|
292
|
+
result = @lexer.in_kwarg
|
293
|
+
@lexer.in_kwarg = true
|
294
|
+
}
|
295
|
+
p_expr
|
296
|
+
{
|
297
|
+
@lexer.in_kwarg = val[2]
|
298
|
+
result = @builder.in_match(val[0], val[1], val[3])
|
299
|
+
}
|
300
|
+
| arg =tLBRACE_ARG
|
287
301
|
|
288
302
|
expr_value: expr
|
289
303
|
|
@@ -843,6 +857,14 @@ rule
|
|
843
857
|
{
|
844
858
|
result = val
|
845
859
|
}
|
860
|
+
| tLPAREN2 args_forward rparen
|
861
|
+
{
|
862
|
+
unless @static_env.declared_forward_args?
|
863
|
+
diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1]
|
864
|
+
end
|
865
|
+
|
866
|
+
result = [val[0], [@builder.forwarded_args(val[1])], val[2]]
|
867
|
+
}
|
846
868
|
|
847
869
|
opt_paren_args: # nothing
|
848
870
|
{
|
@@ -1133,6 +1155,14 @@ rule
|
|
1133
1155
|
when_bodies, else_t, else_body,
|
1134
1156
|
val[3])
|
1135
1157
|
}
|
1158
|
+
| kCASE expr_value opt_terms p_case_body kEND
|
1159
|
+
{
|
1160
|
+
*in_bodies, (else_t, else_body) = *val[3]
|
1161
|
+
|
1162
|
+
result = @builder.case_match(val[0], val[1],
|
1163
|
+
in_bodies, else_t, else_body,
|
1164
|
+
val[4])
|
1165
|
+
}
|
1136
1166
|
| kFOR for_var kIN expr_value_do compstmt kEND
|
1137
1167
|
{
|
1138
1168
|
result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5])
|
@@ -1200,6 +1230,7 @@ rule
|
|
1200
1230
|
@lexer.cmdarg.push(false)
|
1201
1231
|
@lexer.cond.push(false)
|
1202
1232
|
@context.push(:def)
|
1233
|
+
@current_arg_stack.push(nil)
|
1203
1234
|
}
|
1204
1235
|
f_arglist bodystmt kEND
|
1205
1236
|
{
|
@@ -1210,6 +1241,7 @@ rule
|
|
1210
1241
|
@lexer.cond.pop
|
1211
1242
|
@static_env.unextend
|
1212
1243
|
@context.pop
|
1244
|
+
@current_arg_stack.pop
|
1213
1245
|
}
|
1214
1246
|
| kDEF singleton dot_or_colon
|
1215
1247
|
{
|
@@ -1221,6 +1253,7 @@ rule
|
|
1221
1253
|
@lexer.cmdarg.push(false)
|
1222
1254
|
@lexer.cond.push(false)
|
1223
1255
|
@context.push(:defs)
|
1256
|
+
@current_arg_stack.push(nil)
|
1224
1257
|
}
|
1225
1258
|
f_arglist bodystmt kEND
|
1226
1259
|
{
|
@@ -1231,6 +1264,7 @@ rule
|
|
1231
1264
|
@lexer.cond.pop
|
1232
1265
|
@static_env.unextend
|
1233
1266
|
@context.pop
|
1267
|
+
@current_arg_stack.pop
|
1234
1268
|
}
|
1235
1269
|
| kBREAK
|
1236
1270
|
{
|
@@ -1248,10 +1282,6 @@ rule
|
|
1248
1282
|
{
|
1249
1283
|
result = @builder.keyword_cmd(:retry, val[0])
|
1250
1284
|
}
|
1251
|
-
| primary_value tMETHREF operation2
|
1252
|
-
{
|
1253
|
-
result = @builder.method_ref(val[0], val[1], val[2])
|
1254
|
-
}
|
1255
1285
|
|
1256
1286
|
primary_value: primary
|
1257
1287
|
|
@@ -1469,17 +1499,14 @@ opt_block_args_tail:
|
|
1469
1499
|
|
1470
1500
|
block_param_def: tPIPE opt_bv_decl tPIPE
|
1471
1501
|
{
|
1472
|
-
@
|
1502
|
+
@max_numparam_stack.has_ordinary_params!
|
1503
|
+
@current_arg_stack.set(nil)
|
1473
1504
|
result = @builder.args(val[0], val[1], val[2])
|
1474
1505
|
}
|
1475
|
-
| tOROP
|
1476
|
-
{
|
1477
|
-
@lexer.max_numparam_stack.cant_have_numparams!
|
1478
|
-
result = @builder.args(val[0], [], val[0])
|
1479
|
-
}
|
1480
1506
|
| tPIPE block_param opt_bv_decl tPIPE
|
1481
1507
|
{
|
1482
|
-
@
|
1508
|
+
@max_numparam_stack.has_ordinary_params!
|
1509
|
+
@current_arg_stack.set(nil)
|
1483
1510
|
result = @builder.args(val[0], val[1].concat(val[2]), val[3])
|
1484
1511
|
}
|
1485
1512
|
|
@@ -1510,7 +1537,7 @@ opt_block_args_tail:
|
|
1510
1537
|
|
1511
1538
|
lambda: {
|
1512
1539
|
@static_env.extend_dynamic
|
1513
|
-
@
|
1540
|
+
@max_numparam_stack.push
|
1514
1541
|
@context.push(:lambda)
|
1515
1542
|
}
|
1516
1543
|
f_larglist
|
@@ -1520,23 +1547,23 @@ opt_block_args_tail:
|
|
1520
1547
|
}
|
1521
1548
|
lambda_body
|
1522
1549
|
{
|
1523
|
-
args = @
|
1550
|
+
args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1]
|
1524
1551
|
result = [ args, val[3] ]
|
1525
1552
|
|
1526
|
-
@
|
1553
|
+
@max_numparam_stack.pop
|
1527
1554
|
@static_env.unextend
|
1528
1555
|
@lexer.cmdarg.pop
|
1529
1556
|
}
|
1530
1557
|
|
1531
1558
|
f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
|
1532
1559
|
{
|
1533
|
-
@
|
1560
|
+
@max_numparam_stack.has_ordinary_params!
|
1534
1561
|
result = @builder.args(val[0], val[1].concat(val[2]), val[3])
|
1535
1562
|
}
|
1536
1563
|
| f_args
|
1537
1564
|
{
|
1538
1565
|
if val[0].any?
|
1539
|
-
@
|
1566
|
+
@max_numparam_stack.has_ordinary_params!
|
1540
1567
|
end
|
1541
1568
|
result = @builder.args(nil, val[0], nil)
|
1542
1569
|
}
|
@@ -1672,30 +1699,30 @@ opt_block_args_tail:
|
|
1672
1699
|
|
1673
1700
|
brace_body: {
|
1674
1701
|
@static_env.extend_dynamic
|
1675
|
-
@
|
1702
|
+
@max_numparam_stack.push
|
1676
1703
|
}
|
1677
1704
|
opt_block_param compstmt
|
1678
1705
|
{
|
1679
|
-
args = @
|
1706
|
+
args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1]
|
1680
1707
|
result = [ args, val[2] ]
|
1681
1708
|
|
1682
|
-
@
|
1709
|
+
@max_numparam_stack.pop
|
1683
1710
|
@static_env.unextend
|
1684
1711
|
}
|
1685
1712
|
|
1686
1713
|
do_body: {
|
1687
1714
|
@static_env.extend_dynamic
|
1688
|
-
@
|
1715
|
+
@max_numparam_stack.push
|
1689
1716
|
}
|
1690
1717
|
{
|
1691
1718
|
@lexer.cmdarg.push(false)
|
1692
1719
|
}
|
1693
1720
|
opt_block_param bodystmt
|
1694
1721
|
{
|
1695
|
-
args = @
|
1722
|
+
args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2]
|
1696
1723
|
result = [ args, val[3] ]
|
1697
1724
|
|
1698
|
-
@
|
1725
|
+
@max_numparam_stack.pop
|
1699
1726
|
@static_env.unextend
|
1700
1727
|
@lexer.cmdarg.pop
|
1701
1728
|
}
|
@@ -1712,6 +1739,387 @@ opt_block_args_tail:
|
|
1712
1739
|
}
|
1713
1740
|
| case_body
|
1714
1741
|
|
1742
|
+
p_case_body: kIN
|
1743
|
+
{
|
1744
|
+
@lexer.state = :expr_beg
|
1745
|
+
@lexer.command_start = false
|
1746
|
+
@pattern_variables.push
|
1747
|
+
@pattern_hash_keys.push
|
1748
|
+
|
1749
|
+
result = @lexer.in_kwarg
|
1750
|
+
@lexer.in_kwarg = true
|
1751
|
+
}
|
1752
|
+
p_top_expr then
|
1753
|
+
{
|
1754
|
+
@lexer.in_kwarg = val[1]
|
1755
|
+
}
|
1756
|
+
compstmt p_cases
|
1757
|
+
{
|
1758
|
+
result = [ @builder.in_pattern(val[0], *val[2], val[3], val[5]),
|
1759
|
+
*val[6] ]
|
1760
|
+
}
|
1761
|
+
|
1762
|
+
p_cases: opt_else
|
1763
|
+
{
|
1764
|
+
result = [ val[0] ]
|
1765
|
+
}
|
1766
|
+
| p_case_body
|
1767
|
+
|
1768
|
+
p_top_expr: p_top_expr_body
|
1769
|
+
{
|
1770
|
+
result = [ val[0], nil ]
|
1771
|
+
}
|
1772
|
+
| p_top_expr_body kIF_MOD expr_value
|
1773
|
+
{
|
1774
|
+
result = [ val[0], @builder.if_guard(val[1], val[2]) ]
|
1775
|
+
}
|
1776
|
+
| p_top_expr_body kUNLESS_MOD expr_value
|
1777
|
+
{
|
1778
|
+
result = [ val[0], @builder.unless_guard(val[1], val[2]) ]
|
1779
|
+
}
|
1780
|
+
|
1781
|
+
p_top_expr_body: p_expr
|
1782
|
+
| p_expr tCOMMA
|
1783
|
+
{
|
1784
|
+
# array patterns that end with comma
|
1785
|
+
# like 1, 2,
|
1786
|
+
# must be emitted as `array_pattern_with_tail`
|
1787
|
+
item = @builder.match_with_trailing_comma(val[0])
|
1788
|
+
result = @builder.array_pattern(nil, [ item ], nil)
|
1789
|
+
}
|
1790
|
+
| p_expr tCOMMA p_args
|
1791
|
+
{
|
1792
|
+
result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil)
|
1793
|
+
}
|
1794
|
+
| p_args_tail
|
1795
|
+
{
|
1796
|
+
result = @builder.array_pattern(nil, val[0], nil)
|
1797
|
+
}
|
1798
|
+
| p_kwargs
|
1799
|
+
{
|
1800
|
+
result = @builder.hash_pattern(nil, val[0], nil)
|
1801
|
+
}
|
1802
|
+
|
1803
|
+
p_expr: p_as
|
1804
|
+
|
1805
|
+
p_as: p_expr tASSOC p_variable
|
1806
|
+
{
|
1807
|
+
result = @builder.match_as(val[0], val[1], val[2])
|
1808
|
+
}
|
1809
|
+
| p_alt
|
1810
|
+
|
1811
|
+
p_alt: p_alt tPIPE p_expr_basic
|
1812
|
+
{
|
1813
|
+
result = @builder.match_alt(val[0], val[1], val[2])
|
1814
|
+
}
|
1815
|
+
| p_expr_basic
|
1816
|
+
|
1817
|
+
p_lparen: tLPAREN2
|
1818
|
+
{
|
1819
|
+
result = val[0]
|
1820
|
+
@pattern_hash_keys.push
|
1821
|
+
}
|
1822
|
+
|
1823
|
+
p_lbracket: tLBRACK2
|
1824
|
+
{
|
1825
|
+
result = val[0]
|
1826
|
+
@pattern_hash_keys.push
|
1827
|
+
}
|
1828
|
+
|
1829
|
+
p_expr_basic: p_value
|
1830
|
+
| p_const p_lparen p_args rparen
|
1831
|
+
{
|
1832
|
+
@pattern_hash_keys.pop
|
1833
|
+
pattern = @builder.array_pattern(nil, val[2], nil)
|
1834
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[3])
|
1835
|
+
}
|
1836
|
+
| p_const p_lparen p_kwargs rparen
|
1837
|
+
{
|
1838
|
+
@pattern_hash_keys.pop
|
1839
|
+
pattern = @builder.hash_pattern(nil, val[2], nil)
|
1840
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[3])
|
1841
|
+
}
|
1842
|
+
| p_const tLPAREN2 rparen
|
1843
|
+
{
|
1844
|
+
pattern = @builder.array_pattern(val[1], nil, val[2])
|
1845
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[2])
|
1846
|
+
}
|
1847
|
+
| p_const p_lbracket p_args rbracket
|
1848
|
+
{
|
1849
|
+
@pattern_hash_keys.pop
|
1850
|
+
pattern = @builder.array_pattern(nil, val[2], nil)
|
1851
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[3])
|
1852
|
+
}
|
1853
|
+
| p_const p_lbracket p_kwargs rbracket
|
1854
|
+
{
|
1855
|
+
@pattern_hash_keys.pop
|
1856
|
+
pattern = @builder.hash_pattern(nil, val[2], nil)
|
1857
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[3])
|
1858
|
+
}
|
1859
|
+
| p_const tLBRACK2 rbracket
|
1860
|
+
{
|
1861
|
+
pattern = @builder.array_pattern(val[1], nil, val[2])
|
1862
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[2])
|
1863
|
+
}
|
1864
|
+
| tLBRACK
|
1865
|
+
{
|
1866
|
+
@pattern_hash_keys.push
|
1867
|
+
}
|
1868
|
+
p_args rbracket
|
1869
|
+
{
|
1870
|
+
@pattern_hash_keys.pop
|
1871
|
+
result = @builder.array_pattern(val[0], val[2], val[3])
|
1872
|
+
}
|
1873
|
+
| tLBRACK rbracket
|
1874
|
+
{
|
1875
|
+
result = @builder.array_pattern(val[0], [], val[1])
|
1876
|
+
}
|
1877
|
+
| tLBRACE
|
1878
|
+
{
|
1879
|
+
@pattern_hash_keys.push
|
1880
|
+
}
|
1881
|
+
p_kwargs tRCURLY
|
1882
|
+
{
|
1883
|
+
@pattern_hash_keys.pop
|
1884
|
+
result = @builder.hash_pattern(val[0], val[2], val[3])
|
1885
|
+
}
|
1886
|
+
| tLBRACE tRCURLY
|
1887
|
+
{
|
1888
|
+
result = @builder.hash_pattern(val[0], [], val[1])
|
1889
|
+
}
|
1890
|
+
| tLPAREN
|
1891
|
+
{
|
1892
|
+
@pattern_hash_keys.push
|
1893
|
+
}
|
1894
|
+
p_expr rparen
|
1895
|
+
{
|
1896
|
+
@pattern_hash_keys.pop
|
1897
|
+
result = @builder.begin(val[0], val[2], val[3])
|
1898
|
+
}
|
1899
|
+
|
1900
|
+
p_args: p_expr
|
1901
|
+
{
|
1902
|
+
result = [ val[0] ]
|
1903
|
+
}
|
1904
|
+
| p_args_head
|
1905
|
+
{
|
1906
|
+
result = val[0]
|
1907
|
+
}
|
1908
|
+
| p_args_head p_arg
|
1909
|
+
{
|
1910
|
+
result = [ *val[0], val[1] ]
|
1911
|
+
}
|
1912
|
+
| p_args_head tSTAR tIDENTIFIER
|
1913
|
+
{
|
1914
|
+
match_rest = @builder.match_rest(val[1], val[2])
|
1915
|
+
result = [ *val[0], match_rest ]
|
1916
|
+
}
|
1917
|
+
| p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
|
1918
|
+
{
|
1919
|
+
match_rest = @builder.match_rest(val[1], val[2])
|
1920
|
+
result = [ *val[0], match_rest, *val[4] ]
|
1921
|
+
}
|
1922
|
+
| p_args_head tSTAR
|
1923
|
+
{
|
1924
|
+
result = [ *val[0], @builder.match_rest(val[1]) ]
|
1925
|
+
}
|
1926
|
+
| p_args_head tSTAR tCOMMA p_args_post
|
1927
|
+
{
|
1928
|
+
result = [ *val[0], @builder.match_rest(val[1]), *val[3] ]
|
1929
|
+
}
|
1930
|
+
| p_args_tail
|
1931
|
+
|
1932
|
+
p_args_head: p_arg tCOMMA
|
1933
|
+
{
|
1934
|
+
# array patterns that end with comma
|
1935
|
+
# like [1, 2,]
|
1936
|
+
# must be emitted as `array_pattern_with_tail`
|
1937
|
+
item = @builder.match_with_trailing_comma(val[0])
|
1938
|
+
result = [ item ]
|
1939
|
+
}
|
1940
|
+
| p_args_head p_arg tCOMMA
|
1941
|
+
{
|
1942
|
+
# array patterns that end with comma
|
1943
|
+
# like [1, 2,]
|
1944
|
+
# must be emitted as `array_pattern_with_tail`
|
1945
|
+
last_item = @builder.match_with_trailing_comma(val[1])
|
1946
|
+
result = [ *val[0], last_item ]
|
1947
|
+
}
|
1948
|
+
|
1949
|
+
p_args_tail: tSTAR tIDENTIFIER
|
1950
|
+
{
|
1951
|
+
match_rest = @builder.match_rest(val[0], val[1])
|
1952
|
+
result = [ match_rest ]
|
1953
|
+
}
|
1954
|
+
| tSTAR tIDENTIFIER tCOMMA p_args_post
|
1955
|
+
{
|
1956
|
+
match_rest = @builder.match_rest(val[0], val[1])
|
1957
|
+
result = [ match_rest, *val[3] ]
|
1958
|
+
}
|
1959
|
+
| tSTAR
|
1960
|
+
{
|
1961
|
+
match_rest = @builder.match_rest(val[0])
|
1962
|
+
result = [ match_rest ]
|
1963
|
+
}
|
1964
|
+
| tSTAR tCOMMA p_args_post
|
1965
|
+
{
|
1966
|
+
match_rest = @builder.match_rest(val[0])
|
1967
|
+
result = [ match_rest, *val[2] ]
|
1968
|
+
}
|
1969
|
+
|
1970
|
+
p_args_post: p_arg
|
1971
|
+
{
|
1972
|
+
result = [ val[0] ]
|
1973
|
+
}
|
1974
|
+
| p_args_post tCOMMA p_arg
|
1975
|
+
{
|
1976
|
+
result = [ *val[0], val[2] ]
|
1977
|
+
}
|
1978
|
+
|
1979
|
+
p_arg: p_expr
|
1980
|
+
|
1981
|
+
p_kwargs: p_kwarg tCOMMA p_kwrest
|
1982
|
+
{
|
1983
|
+
result = [ *val[0], *val[2] ]
|
1984
|
+
}
|
1985
|
+
| p_kwarg
|
1986
|
+
{
|
1987
|
+
result = val[0]
|
1988
|
+
}
|
1989
|
+
| p_kwrest
|
1990
|
+
{
|
1991
|
+
result = val[0]
|
1992
|
+
}
|
1993
|
+
| p_kwarg tCOMMA p_kwnorest
|
1994
|
+
{
|
1995
|
+
result = [ *val[0], *val[2] ]
|
1996
|
+
}
|
1997
|
+
| p_kwnorest
|
1998
|
+
{
|
1999
|
+
result = [ *val[0], *val[2] ]
|
2000
|
+
}
|
2001
|
+
|
2002
|
+
p_kwarg: p_kw
|
2003
|
+
{
|
2004
|
+
result = [ val[0] ]
|
2005
|
+
}
|
2006
|
+
| p_kwarg tCOMMA p_kw
|
2007
|
+
{
|
2008
|
+
result = [ *val[0], val[2] ]
|
2009
|
+
}
|
2010
|
+
|
2011
|
+
p_kw: p_kw_label p_expr
|
2012
|
+
{
|
2013
|
+
result = @builder.match_pair(*val[0], val[1])
|
2014
|
+
}
|
2015
|
+
| p_kw_label
|
2016
|
+
{
|
2017
|
+
result = @builder.match_label(*val[0])
|
2018
|
+
}
|
2019
|
+
|
2020
|
+
p_kw_label: tLABEL
|
2021
|
+
{
|
2022
|
+
check_kwarg_name(val[0])
|
2023
|
+
result = [:label, val[0]]
|
2024
|
+
}
|
2025
|
+
| tSTRING_BEG string_contents tLABEL_END
|
2026
|
+
{
|
2027
|
+
result = [:quoted, [val[0], val[1], val[2]]]
|
2028
|
+
}
|
2029
|
+
|
2030
|
+
p_kwrest: kwrest_mark tIDENTIFIER
|
2031
|
+
{
|
2032
|
+
result = [ @builder.match_rest(val[0], val[1]) ]
|
2033
|
+
}
|
2034
|
+
| kwrest_mark
|
2035
|
+
{
|
2036
|
+
result = [ @builder.match_rest(val[0], nil) ]
|
2037
|
+
}
|
2038
|
+
|
2039
|
+
p_kwnorest: kwrest_mark kNIL
|
2040
|
+
{
|
2041
|
+
result = [ @builder.match_nil_pattern(val[0], val[1]) ]
|
2042
|
+
}
|
2043
|
+
|
2044
|
+
p_value: p_primitive
|
2045
|
+
| p_primitive tDOT2 p_primitive
|
2046
|
+
{
|
2047
|
+
result = @builder.range_inclusive(val[0], val[1], val[2])
|
2048
|
+
}
|
2049
|
+
| p_primitive tDOT3 p_primitive
|
2050
|
+
{
|
2051
|
+
result = @builder.range_exclusive(val[0], val[1], val[2])
|
2052
|
+
}
|
2053
|
+
| p_primitive tDOT2
|
2054
|
+
{
|
2055
|
+
result = @builder.range_inclusive(val[0], val[1], nil)
|
2056
|
+
}
|
2057
|
+
| p_primitive tDOT3
|
2058
|
+
{
|
2059
|
+
result = @builder.range_exclusive(val[0], val[1], nil)
|
2060
|
+
}
|
2061
|
+
| p_variable
|
2062
|
+
| p_var_ref
|
2063
|
+
| p_const
|
2064
|
+
| tBDOT2 p_primitive
|
2065
|
+
{
|
2066
|
+
result = @builder.range_inclusive(nil, val[0], val[1])
|
2067
|
+
}
|
2068
|
+
| tBDOT3 p_primitive
|
2069
|
+
{
|
2070
|
+
result = @builder.range_exclusive(nil, val[0], val[1])
|
2071
|
+
}
|
2072
|
+
|
2073
|
+
p_primitive: literal
|
2074
|
+
| strings
|
2075
|
+
| xstring
|
2076
|
+
| regexp
|
2077
|
+
| words
|
2078
|
+
| qwords
|
2079
|
+
| symbols
|
2080
|
+
| qsymbols
|
2081
|
+
| keyword_variable
|
2082
|
+
{
|
2083
|
+
result = @builder.accessible(val[0])
|
2084
|
+
}
|
2085
|
+
| tLAMBDA lambda
|
2086
|
+
{
|
2087
|
+
lambda_call = @builder.call_lambda(val[0])
|
2088
|
+
|
2089
|
+
args, (begin_t, body, end_t) = val[1]
|
2090
|
+
result = @builder.block(lambda_call,
|
2091
|
+
begin_t, args, body, end_t)
|
2092
|
+
}
|
2093
|
+
|
2094
|
+
p_variable: tIDENTIFIER
|
2095
|
+
{
|
2096
|
+
result = @builder.match_var(val[0])
|
2097
|
+
}
|
2098
|
+
|
2099
|
+
p_var_ref: tCARET tIDENTIFIER
|
2100
|
+
{
|
2101
|
+
name = val[1][0]
|
2102
|
+
unless static_env.declared?(name)
|
2103
|
+
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
|
2104
|
+
end
|
2105
|
+
|
2106
|
+
lvar = @builder.accessible(@builder.ident(val[1]))
|
2107
|
+
result = @builder.pin(val[0], lvar)
|
2108
|
+
}
|
2109
|
+
|
2110
|
+
p_const: tCOLON3 cname
|
2111
|
+
{
|
2112
|
+
result = @builder.const_global(val[0], val[1])
|
2113
|
+
}
|
2114
|
+
| p_const tCOLON2 cname
|
2115
|
+
{
|
2116
|
+
result = @builder.const_fetch(val[0], val[1], val[2])
|
2117
|
+
}
|
2118
|
+
| tCONSTANT
|
2119
|
+
{
|
2120
|
+
result = @builder.const(val[0])
|
2121
|
+
}
|
2122
|
+
|
1715
2123
|
opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
|
1716
2124
|
{
|
1717
2125
|
assoc_t, exc_var = val[2]
|
@@ -1918,10 +2326,6 @@ regexp_contents: # nothing
|
|
1918
2326
|
{
|
1919
2327
|
result = @builder.cvar(val[0])
|
1920
2328
|
}
|
1921
|
-
| tNUMPARAM
|
1922
|
-
{
|
1923
|
-
result = @builder.numparam(val[0])
|
1924
|
-
}
|
1925
2329
|
| backref
|
1926
2330
|
|
1927
2331
|
symbol: ssym
|
@@ -1994,10 +2398,6 @@ regexp_contents: # nothing
|
|
1994
2398
|
{
|
1995
2399
|
result = @builder.cvar(val[0])
|
1996
2400
|
}
|
1997
|
-
| tNUMPARAM
|
1998
|
-
{
|
1999
|
-
result = @builder.numparam(val[0])
|
2000
|
-
}
|
2001
2401
|
|
2002
2402
|
keyword_variable: kNIL
|
2003
2403
|
{
|
@@ -2030,6 +2430,46 @@ keyword_variable: kNIL
|
|
2030
2430
|
|
2031
2431
|
var_ref: user_variable
|
2032
2432
|
{
|
2433
|
+
if (node = val[0]) && node.type == :ident
|
2434
|
+
name = node.children[0]
|
2435
|
+
|
2436
|
+
if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && context.in_dynamic_block?
|
2437
|
+
# definitely an implicit param
|
2438
|
+
location = node.loc.expression
|
2439
|
+
|
2440
|
+
if max_numparam_stack.has_ordinary_params?
|
2441
|
+
diagnostic :error, :ordinary_param_defined, nil, [nil, location]
|
2442
|
+
end
|
2443
|
+
|
2444
|
+
raw_context = context.stack.dup
|
2445
|
+
raw_max_numparam_stack = max_numparam_stack.stack.dup
|
2446
|
+
|
2447
|
+
# ignore current block scope
|
2448
|
+
raw_context.pop
|
2449
|
+
raw_max_numparam_stack.pop
|
2450
|
+
|
2451
|
+
raw_context.reverse_each do |outer_scope|
|
2452
|
+
if outer_scope == :block || outer_scope == :lambda
|
2453
|
+
outer_scope_has_numparams = raw_max_numparam_stack.pop > 0
|
2454
|
+
|
2455
|
+
if outer_scope_has_numparams
|
2456
|
+
diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location]
|
2457
|
+
else
|
2458
|
+
# for now it's ok, but an outer scope can also be a block
|
2459
|
+
# with numparams, so we need to continue
|
2460
|
+
end
|
2461
|
+
else
|
2462
|
+
# found an outer scope that can't have numparams
|
2463
|
+
# like def/class/etc
|
2464
|
+
break
|
2465
|
+
end
|
2466
|
+
end
|
2467
|
+
|
2468
|
+
static_env.declare(name)
|
2469
|
+
max_numparam_stack.register(name[1].to_i)
|
2470
|
+
end
|
2471
|
+
end
|
2472
|
+
|
2033
2473
|
result = @builder.accessible(val[0])
|
2034
2474
|
}
|
2035
2475
|
| keyword_variable
|
@@ -2072,6 +2512,13 @@ keyword_variable: kNIL
|
|
2072
2512
|
{
|
2073
2513
|
result = @builder.args(val[0], val[1], val[2])
|
2074
2514
|
|
2515
|
+
@lexer.state = :expr_value
|
2516
|
+
}
|
2517
|
+
| tLPAREN2 args_forward rparen
|
2518
|
+
{
|
2519
|
+
result = @builder.forward_args(val[0], val[1], val[2])
|
2520
|
+
@static_env.declare_forward_args
|
2521
|
+
|
2075
2522
|
@lexer.state = :expr_value
|
2076
2523
|
}
|
2077
2524
|
| {
|
@@ -2204,6 +2651,11 @@ keyword_variable: kNIL
|
|
2204
2651
|
result = []
|
2205
2652
|
}
|
2206
2653
|
|
2654
|
+
args_forward: tBDOT3
|
2655
|
+
{
|
2656
|
+
result = val[0]
|
2657
|
+
}
|
2658
|
+
|
2207
2659
|
f_bad_arg: tCONSTANT
|
2208
2660
|
{
|
2209
2661
|
diagnostic :error, :argument_const, nil, val[0]
|
@@ -2226,18 +2678,20 @@ keyword_variable: kNIL
|
|
2226
2678
|
{
|
2227
2679
|
@static_env.declare val[0][0]
|
2228
2680
|
|
2229
|
-
@
|
2681
|
+
@max_numparam_stack.has_ordinary_params!
|
2230
2682
|
|
2231
2683
|
result = val[0]
|
2232
2684
|
}
|
2233
2685
|
|
2234
2686
|
f_arg_asgn: f_norm_arg
|
2235
2687
|
{
|
2688
|
+
@current_arg_stack.set(val[0][0])
|
2236
2689
|
result = val[0]
|
2237
2690
|
}
|
2238
2691
|
|
2239
2692
|
f_arg_item: f_arg_asgn
|
2240
2693
|
{
|
2694
|
+
@current_arg_stack.set(0)
|
2241
2695
|
result = @builder.arg(val[0])
|
2242
2696
|
}
|
2243
2697
|
| tLPAREN f_margs rparen
|
@@ -2260,17 +2714,21 @@ keyword_variable: kNIL
|
|
2260
2714
|
|
2261
2715
|
@static_env.declare val[0][0]
|
2262
2716
|
|
2263
|
-
@
|
2717
|
+
@max_numparam_stack.has_ordinary_params!
|
2718
|
+
|
2719
|
+
@current_arg_stack.set(val[0][0])
|
2264
2720
|
|
2265
2721
|
result = val[0]
|
2266
2722
|
}
|
2267
2723
|
|
2268
2724
|
f_kw: f_label arg_value
|
2269
2725
|
{
|
2726
|
+
@current_arg_stack.set(nil)
|
2270
2727
|
result = @builder.kwoptarg(val[0], val[1])
|
2271
2728
|
}
|
2272
2729
|
| f_label
|
2273
2730
|
{
|
2731
|
+
@current_arg_stack.set(nil)
|
2274
2732
|
result = @builder.kwarg(val[0])
|
2275
2733
|
}
|
2276
2734
|
|
@@ -2321,11 +2779,13 @@ keyword_variable: kNIL
|
|
2321
2779
|
|
2322
2780
|
f_opt: f_arg_asgn tEQL arg_value
|
2323
2781
|
{
|
2782
|
+
@current_arg_stack.set(0)
|
2324
2783
|
result = @builder.optarg(val[0], val[1], val[2])
|
2325
2784
|
}
|
2326
2785
|
|
2327
2786
|
f_block_opt: f_arg_asgn tEQL primary_value
|
2328
2787
|
{
|
2788
|
+
@current_arg_stack.set(0)
|
2329
2789
|
result = @builder.optarg(val[0], val[1], val[2])
|
2330
2790
|
}
|
2331
2791
|
|