parser 2.6.5.0 → 2.7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|