parser 2.6.5.0 → 2.7.0.0
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/CHANGELOG.md +34 -0
- data/README.md +7 -0
- data/doc/AST_FORMAT.md +346 -20
- data/lib/parser.rb +3 -1
- data/lib/parser/ast/processor.rb +15 -0
- data/lib/parser/base.rb +19 -0
- data/lib/parser/builders/default.rb +245 -12
- data/lib/parser/context.rb +4 -0
- data/lib/parser/current.rb +4 -4
- data/lib/parser/current_arg_stack.rb +43 -0
- data/lib/parser/lexer.rl +93 -94
- data/lib/parser/lexer/dedenter.rb +48 -49
- data/lib/parser/{lexer/max_numparam_stack.rb → max_numparam_stack.rb} +10 -4
- data/lib/parser/messages.rb +34 -29
- data/lib/parser/meta.rb +6 -2
- data/lib/parser/ruby27.y +488 -35
- data/lib/parser/static_environment.rb +10 -0
- data/lib/parser/variables_stack.rb +32 -0
- data/lib/parser/version.rb +1 -1
- data/test/helper.rb +1 -0
- data/test/test_lexer.rb +7 -66
- data/test/test_parser.rb +1776 -123
- metadata +5 -3
data/lib/parser/messages.rb
CHANGED
@@ -31,42 +31,47 @@ 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
|
+
:duplicate_variable_name => 'duplicate variable name %{name}',
|
74
|
+
:duplicate_pattern_key => 'duplicate hash pattern key %{name}',
|
70
75
|
|
71
76
|
# Parser warnings
|
72
77
|
:useless_else => 'else without rescue is useless',
|
data/lib/parser/meta.rb
CHANGED
@@ -24,9 +24,13 @@ 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
|
30
34
|
).map(&:to_sym).to_set.freeze
|
31
35
|
|
32
36
|
end # Meta
|
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
|
@@ -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,380 @@ 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
|
+
result = @builder.const_pattern(val[0], val[1], nil, val[2])
|
1845
|
+
}
|
1846
|
+
| p_const p_lbracket p_args rbracket
|
1847
|
+
{
|
1848
|
+
@pattern_hash_keys.pop
|
1849
|
+
pattern = @builder.array_pattern(nil, val[2], nil)
|
1850
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[3])
|
1851
|
+
}
|
1852
|
+
| p_const p_lbracket p_kwargs rbracket
|
1853
|
+
{
|
1854
|
+
@pattern_hash_keys.pop
|
1855
|
+
pattern = @builder.hash_pattern(nil, val[2], nil)
|
1856
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[3])
|
1857
|
+
}
|
1858
|
+
| p_const tLBRACK2 rbracket
|
1859
|
+
{
|
1860
|
+
result = @builder.const_pattern(val[0], val[1], nil, val[2])
|
1861
|
+
}
|
1862
|
+
| tLBRACK
|
1863
|
+
{
|
1864
|
+
@pattern_hash_keys.push
|
1865
|
+
}
|
1866
|
+
p_args rbracket
|
1867
|
+
{
|
1868
|
+
@pattern_hash_keys.pop
|
1869
|
+
result = @builder.array_pattern(val[0], val[2], val[3])
|
1870
|
+
}
|
1871
|
+
| tLBRACK rbracket
|
1872
|
+
{
|
1873
|
+
result = @builder.array_pattern(val[0], [], val[1])
|
1874
|
+
}
|
1875
|
+
| tLBRACE
|
1876
|
+
{
|
1877
|
+
@pattern_hash_keys.push
|
1878
|
+
}
|
1879
|
+
p_kwargs tRCURLY
|
1880
|
+
{
|
1881
|
+
@pattern_hash_keys.pop
|
1882
|
+
result = @builder.hash_pattern(val[0], val[2], val[3])
|
1883
|
+
}
|
1884
|
+
| tLBRACE tRCURLY
|
1885
|
+
{
|
1886
|
+
result = @builder.hash_pattern(val[0], [], val[1])
|
1887
|
+
}
|
1888
|
+
| tLPAREN
|
1889
|
+
{
|
1890
|
+
@pattern_hash_keys.push
|
1891
|
+
}
|
1892
|
+
p_expr rparen
|
1893
|
+
{
|
1894
|
+
@pattern_hash_keys.pop
|
1895
|
+
result = @builder.begin(val[0], val[2], val[3])
|
1896
|
+
}
|
1897
|
+
|
1898
|
+
p_args: p_expr
|
1899
|
+
{
|
1900
|
+
result = [ val[0] ]
|
1901
|
+
}
|
1902
|
+
| p_args_head
|
1903
|
+
{
|
1904
|
+
result = val[0]
|
1905
|
+
}
|
1906
|
+
| p_args_head p_arg
|
1907
|
+
{
|
1908
|
+
result = [ *val[0], val[1] ]
|
1909
|
+
}
|
1910
|
+
| p_args_head tSTAR tIDENTIFIER
|
1911
|
+
{
|
1912
|
+
match_rest = @builder.match_rest(val[1], val[2])
|
1913
|
+
result = [ *val[0], match_rest ]
|
1914
|
+
}
|
1915
|
+
| p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
|
1916
|
+
{
|
1917
|
+
match_rest = @builder.match_rest(val[1], val[2])
|
1918
|
+
result = [ *val[0], match_rest, *val[4] ]
|
1919
|
+
}
|
1920
|
+
| p_args_head tSTAR
|
1921
|
+
{
|
1922
|
+
result = [ *val[0], @builder.match_rest(val[1]) ]
|
1923
|
+
}
|
1924
|
+
| p_args_head tSTAR tCOMMA p_args_post
|
1925
|
+
{
|
1926
|
+
result = [ *val[0], @builder.match_rest(val[1]), *val[3] ]
|
1927
|
+
}
|
1928
|
+
| p_args_tail
|
1929
|
+
|
1930
|
+
p_args_head: p_arg tCOMMA
|
1931
|
+
{
|
1932
|
+
# array patterns that end with comma
|
1933
|
+
# like [1, 2,]
|
1934
|
+
# must be emitted as `array_pattern_with_tail`
|
1935
|
+
item = @builder.match_with_trailing_comma(val[0])
|
1936
|
+
result = [ item ]
|
1937
|
+
}
|
1938
|
+
| p_args_head p_arg tCOMMA
|
1939
|
+
{
|
1940
|
+
# array patterns that end with comma
|
1941
|
+
# like [1, 2,]
|
1942
|
+
# must be emitted as `array_pattern_with_tail`
|
1943
|
+
last_item = @builder.match_with_trailing_comma(val[1])
|
1944
|
+
result = [ *val[0], last_item ]
|
1945
|
+
}
|
1946
|
+
|
1947
|
+
p_args_tail: tSTAR tIDENTIFIER
|
1948
|
+
{
|
1949
|
+
match_rest = @builder.match_rest(val[0], val[1])
|
1950
|
+
result = [ match_rest ]
|
1951
|
+
}
|
1952
|
+
| tSTAR tIDENTIFIER tCOMMA p_args_post
|
1953
|
+
{
|
1954
|
+
match_rest = @builder.match_rest(val[0], val[1])
|
1955
|
+
result = [ match_rest, *val[3] ]
|
1956
|
+
}
|
1957
|
+
| tSTAR
|
1958
|
+
{
|
1959
|
+
match_rest = @builder.match_rest(val[0])
|
1960
|
+
result = [ match_rest ]
|
1961
|
+
}
|
1962
|
+
| tSTAR tCOMMA p_args_post
|
1963
|
+
{
|
1964
|
+
match_rest = @builder.match_rest(val[0])
|
1965
|
+
result = [ match_rest, *val[2] ]
|
1966
|
+
}
|
1967
|
+
|
1968
|
+
p_args_post: p_arg
|
1969
|
+
{
|
1970
|
+
result = [ val[0] ]
|
1971
|
+
}
|
1972
|
+
| p_args_post tCOMMA p_arg
|
1973
|
+
{
|
1974
|
+
result = [ *val[0], val[2] ]
|
1975
|
+
}
|
1976
|
+
|
1977
|
+
p_arg: p_expr
|
1978
|
+
|
1979
|
+
p_kwargs: p_kwarg tCOMMA p_kwrest
|
1980
|
+
{
|
1981
|
+
result = [ *val[0], *val[2] ]
|
1982
|
+
}
|
1983
|
+
| p_kwarg
|
1984
|
+
{
|
1985
|
+
result = val[0]
|
1986
|
+
}
|
1987
|
+
| p_kwrest
|
1988
|
+
{
|
1989
|
+
result = val[0]
|
1990
|
+
}
|
1991
|
+
| p_kwarg tCOMMA p_kwnorest
|
1992
|
+
{
|
1993
|
+
result = [ *val[0], *val[2] ]
|
1994
|
+
}
|
1995
|
+
| p_kwnorest
|
1996
|
+
{
|
1997
|
+
result = [ *val[0], *val[2] ]
|
1998
|
+
}
|
1999
|
+
|
2000
|
+
p_kwarg: p_kw
|
2001
|
+
{
|
2002
|
+
result = [ val[0] ]
|
2003
|
+
}
|
2004
|
+
| p_kwarg tCOMMA p_kw
|
2005
|
+
{
|
2006
|
+
result = [ *val[0], val[2] ]
|
2007
|
+
}
|
2008
|
+
|
2009
|
+
p_kw: p_kw_label p_expr
|
2010
|
+
{
|
2011
|
+
result = @builder.match_pair(*val[0], val[1])
|
2012
|
+
}
|
2013
|
+
| p_kw_label
|
2014
|
+
{
|
2015
|
+
result = @builder.match_label(*val[0])
|
2016
|
+
}
|
2017
|
+
|
2018
|
+
p_kw_label: tLABEL
|
2019
|
+
{
|
2020
|
+
check_kwarg_name(val[0])
|
2021
|
+
result = [:label, val[0]]
|
2022
|
+
}
|
2023
|
+
| tSTRING_BEG string_contents tLABEL_END
|
2024
|
+
{
|
2025
|
+
result = [:quoted, [val[0], val[1], val[2]]]
|
2026
|
+
}
|
2027
|
+
|
2028
|
+
p_kwrest: kwrest_mark tIDENTIFIER
|
2029
|
+
{
|
2030
|
+
result = [ @builder.match_rest(val[0], val[1]) ]
|
2031
|
+
}
|
2032
|
+
| kwrest_mark
|
2033
|
+
{
|
2034
|
+
result = [ @builder.match_rest(val[0], nil) ]
|
2035
|
+
}
|
2036
|
+
|
2037
|
+
p_kwnorest: kwrest_mark kNIL
|
2038
|
+
{
|
2039
|
+
result = [ @builder.match_nil_pattern(val[0], val[1]) ]
|
2040
|
+
}
|
2041
|
+
|
2042
|
+
p_value: p_primitive
|
2043
|
+
| p_primitive tDOT2 p_primitive
|
2044
|
+
{
|
2045
|
+
result = @builder.range_inclusive(val[0], val[1], val[2])
|
2046
|
+
}
|
2047
|
+
| p_primitive tDOT3 p_primitive
|
2048
|
+
{
|
2049
|
+
result = @builder.range_exclusive(val[0], val[1], val[2])
|
2050
|
+
}
|
2051
|
+
| p_primitive tDOT2
|
2052
|
+
{
|
2053
|
+
result = @builder.range_inclusive(val[0], val[1], nil)
|
2054
|
+
}
|
2055
|
+
| p_primitive tDOT3
|
2056
|
+
{
|
2057
|
+
result = @builder.range_exclusive(val[0], val[1], nil)
|
2058
|
+
}
|
2059
|
+
| p_variable
|
2060
|
+
| p_var_ref
|
2061
|
+
| p_const
|
2062
|
+
| tBDOT2 p_primitive
|
2063
|
+
{
|
2064
|
+
result = @builder.range_inclusive(nil, val[0], val[1])
|
2065
|
+
}
|
2066
|
+
| tBDOT3 p_primitive
|
2067
|
+
{
|
2068
|
+
result = @builder.range_exclusive(nil, val[0], val[1])
|
2069
|
+
}
|
2070
|
+
|
2071
|
+
p_primitive: literal
|
2072
|
+
| strings
|
2073
|
+
| xstring
|
2074
|
+
| regexp
|
2075
|
+
| words
|
2076
|
+
| qwords
|
2077
|
+
| symbols
|
2078
|
+
| qsymbols
|
2079
|
+
| keyword_variable
|
2080
|
+
{
|
2081
|
+
result = @builder.accessible(val[0])
|
2082
|
+
}
|
2083
|
+
| tLAMBDA lambda
|
2084
|
+
{
|
2085
|
+
lambda_call = @builder.call_lambda(val[0])
|
2086
|
+
|
2087
|
+
args, (begin_t, body, end_t) = val[1]
|
2088
|
+
result = @builder.block(lambda_call,
|
2089
|
+
begin_t, args, body, end_t)
|
2090
|
+
}
|
2091
|
+
|
2092
|
+
p_variable: tIDENTIFIER
|
2093
|
+
{
|
2094
|
+
result = @builder.match_var(val[0])
|
2095
|
+
}
|
2096
|
+
|
2097
|
+
p_var_ref: tCARET tIDENTIFIER
|
2098
|
+
{
|
2099
|
+
lvar = @builder.accessible(@builder.ident(val[1]))
|
2100
|
+
result = @builder.pin(val[0], lvar)
|
2101
|
+
}
|
2102
|
+
|
2103
|
+
p_const: tCOLON3 cname
|
2104
|
+
{
|
2105
|
+
result = @builder.const_global(val[0], val[1])
|
2106
|
+
}
|
2107
|
+
| p_const tCOLON2 cname
|
2108
|
+
{
|
2109
|
+
result = @builder.const_fetch(val[0], val[1], val[2])
|
2110
|
+
}
|
2111
|
+
| tCONSTANT
|
2112
|
+
{
|
2113
|
+
result = @builder.const(val[0])
|
2114
|
+
}
|
2115
|
+
|
1715
2116
|
opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
|
1716
2117
|
{
|
1717
2118
|
assoc_t, exc_var = val[2]
|
@@ -1918,10 +2319,6 @@ regexp_contents: # nothing
|
|
1918
2319
|
{
|
1919
2320
|
result = @builder.cvar(val[0])
|
1920
2321
|
}
|
1921
|
-
| tNUMPARAM
|
1922
|
-
{
|
1923
|
-
result = @builder.numparam(val[0])
|
1924
|
-
}
|
1925
2322
|
| backref
|
1926
2323
|
|
1927
2324
|
symbol: ssym
|
@@ -1994,10 +2391,6 @@ regexp_contents: # nothing
|
|
1994
2391
|
{
|
1995
2392
|
result = @builder.cvar(val[0])
|
1996
2393
|
}
|
1997
|
-
| tNUMPARAM
|
1998
|
-
{
|
1999
|
-
result = @builder.numparam(val[0])
|
2000
|
-
}
|
2001
2394
|
|
2002
2395
|
keyword_variable: kNIL
|
2003
2396
|
{
|
@@ -2030,6 +2423,46 @@ keyword_variable: kNIL
|
|
2030
2423
|
|
2031
2424
|
var_ref: user_variable
|
2032
2425
|
{
|
2426
|
+
if (node = val[0]) && node.type == :ident
|
2427
|
+
name = node.children[0]
|
2428
|
+
|
2429
|
+
if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && context.in_dynamic_block?
|
2430
|
+
# definitely an implicit param
|
2431
|
+
location = node.loc.expression
|
2432
|
+
|
2433
|
+
if max_numparam_stack.has_ordinary_params?
|
2434
|
+
diagnostic :error, :ordinary_param_defined, nil, [nil, location]
|
2435
|
+
end
|
2436
|
+
|
2437
|
+
raw_context = context.stack.dup
|
2438
|
+
raw_max_numparam_stack = max_numparam_stack.stack.dup
|
2439
|
+
|
2440
|
+
# ignore current block scope
|
2441
|
+
raw_context.pop
|
2442
|
+
raw_max_numparam_stack.pop
|
2443
|
+
|
2444
|
+
raw_context.reverse_each do |outer_scope|
|
2445
|
+
if outer_scope == :block || outer_scope == :lambda
|
2446
|
+
outer_scope_has_numparams = raw_max_numparam_stack.pop > 0
|
2447
|
+
|
2448
|
+
if outer_scope_has_numparams
|
2449
|
+
diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location]
|
2450
|
+
else
|
2451
|
+
# for now it's ok, but an outer scope can also be a block
|
2452
|
+
# with numparams, so we need to continue
|
2453
|
+
end
|
2454
|
+
else
|
2455
|
+
# found an outer scope that can't have numparams
|
2456
|
+
# like def/class/etc
|
2457
|
+
break
|
2458
|
+
end
|
2459
|
+
end
|
2460
|
+
|
2461
|
+
static_env.declare(name)
|
2462
|
+
max_numparam_stack.register(name[1].to_i)
|
2463
|
+
end
|
2464
|
+
end
|
2465
|
+
|
2033
2466
|
result = @builder.accessible(val[0])
|
2034
2467
|
}
|
2035
2468
|
| keyword_variable
|
@@ -2072,6 +2505,13 @@ keyword_variable: kNIL
|
|
2072
2505
|
{
|
2073
2506
|
result = @builder.args(val[0], val[1], val[2])
|
2074
2507
|
|
2508
|
+
@lexer.state = :expr_value
|
2509
|
+
}
|
2510
|
+
| tLPAREN2 args_forward rparen
|
2511
|
+
{
|
2512
|
+
result = @builder.forward_args(val[0], val[1], val[2])
|
2513
|
+
@static_env.declare_forward_args
|
2514
|
+
|
2075
2515
|
@lexer.state = :expr_value
|
2076
2516
|
}
|
2077
2517
|
| {
|
@@ -2204,6 +2644,11 @@ keyword_variable: kNIL
|
|
2204
2644
|
result = []
|
2205
2645
|
}
|
2206
2646
|
|
2647
|
+
args_forward: tBDOT3
|
2648
|
+
{
|
2649
|
+
result = val[0]
|
2650
|
+
}
|
2651
|
+
|
2207
2652
|
f_bad_arg: tCONSTANT
|
2208
2653
|
{
|
2209
2654
|
diagnostic :error, :argument_const, nil, val[0]
|
@@ -2226,18 +2671,20 @@ keyword_variable: kNIL
|
|
2226
2671
|
{
|
2227
2672
|
@static_env.declare val[0][0]
|
2228
2673
|
|
2229
|
-
@
|
2674
|
+
@max_numparam_stack.has_ordinary_params!
|
2230
2675
|
|
2231
2676
|
result = val[0]
|
2232
2677
|
}
|
2233
2678
|
|
2234
2679
|
f_arg_asgn: f_norm_arg
|
2235
2680
|
{
|
2681
|
+
@current_arg_stack.set(val[0][0])
|
2236
2682
|
result = val[0]
|
2237
2683
|
}
|
2238
2684
|
|
2239
2685
|
f_arg_item: f_arg_asgn
|
2240
2686
|
{
|
2687
|
+
@current_arg_stack.set(0)
|
2241
2688
|
result = @builder.arg(val[0])
|
2242
2689
|
}
|
2243
2690
|
| tLPAREN f_margs rparen
|
@@ -2260,17 +2707,21 @@ keyword_variable: kNIL
|
|
2260
2707
|
|
2261
2708
|
@static_env.declare val[0][0]
|
2262
2709
|
|
2263
|
-
@
|
2710
|
+
@max_numparam_stack.has_ordinary_params!
|
2711
|
+
|
2712
|
+
@current_arg_stack.set(val[0][0])
|
2264
2713
|
|
2265
2714
|
result = val[0]
|
2266
2715
|
}
|
2267
2716
|
|
2268
2717
|
f_kw: f_label arg_value
|
2269
2718
|
{
|
2719
|
+
@current_arg_stack.set(nil)
|
2270
2720
|
result = @builder.kwoptarg(val[0], val[1])
|
2271
2721
|
}
|
2272
2722
|
| f_label
|
2273
2723
|
{
|
2724
|
+
@current_arg_stack.set(nil)
|
2274
2725
|
result = @builder.kwarg(val[0])
|
2275
2726
|
}
|
2276
2727
|
|
@@ -2321,11 +2772,13 @@ keyword_variable: kNIL
|
|
2321
2772
|
|
2322
2773
|
f_opt: f_arg_asgn tEQL arg_value
|
2323
2774
|
{
|
2775
|
+
@current_arg_stack.set(0)
|
2324
2776
|
result = @builder.optarg(val[0], val[1], val[2])
|
2325
2777
|
}
|
2326
2778
|
|
2327
2779
|
f_block_opt: f_arg_asgn tEQL primary_value
|
2328
2780
|
{
|
2781
|
+
@current_arg_stack.set(0)
|
2329
2782
|
result = @builder.optarg(val[0], val[1], val[2])
|
2330
2783
|
}
|
2331
2784
|
|