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.
@@ -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 => 'cannot define an alias for a back-reference variable',
46
- :begin_in_method => 'BEGIN in method',
47
- :backref_assignment => 'cannot assign to a back-reference variable',
48
- :invalid_assignment => 'cannot assign to a keyword',
49
- :module_name_const => 'class or module name must be a constant literal',
50
- :unexpected_token => 'unexpected token %{token}',
51
- :argument_const => 'formal argument cannot be a constant',
52
- :argument_ivar => 'formal argument cannot be an instance variable',
53
- :argument_gvar => 'formal argument cannot be a global variable',
54
- :argument_cvar => 'formal argument cannot be a class variable',
55
- :duplicate_argument => 'duplicate argument name',
56
- :empty_symbol => 'empty symbol literal',
57
- :odd_hash => 'odd number of entries for a hash',
58
- :singleton_literal => 'cannot define a singleton method for a literal',
59
- :dynamic_const => 'dynamic constant assignment',
60
- :const_reassignment => 'constant re-assignment',
61
- :module_in_def => 'module definition in method body',
62
- :class_in_def => 'class definition in method body',
63
- :unexpected_percent_str => '%{type}: unknown type of percent-literal',
64
- :block_and_blockarg => 'both block argument and literal block are passed',
65
- :masgn_as_condition => 'multiple assignment in conditional context',
66
- :block_given_to_yield => 'block given to yield',
67
- :invalid_regexp => '%{message}',
68
- :invalid_return => 'Invalid return in class/module body',
69
- :csend_in_lhs_of_masgn => '&. inside multiple assignment destination',
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',
@@ -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
- meth_ref restarg_expr blockarg_expr
27
+ restarg_expr blockarg_expr
28
28
  objc_kwarg objc_restarg objc_varargs
29
- numargs numblock numparam
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
@@ -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 tMETHREF tBDOT2 tBDOT3 tNUMPARAM
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
- @lexer.max_numparam_stack.cant_have_numparams!
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
- @lexer.max_numparam_stack.cant_have_numparams!
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
- @lexer.max_numparam_stack.push
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 = @lexer.max_numparam > 0 ? @builder.numargs(@lexer.max_numparam) : val[1]
1550
+ args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1]
1524
1551
  result = [ args, val[3] ]
1525
1552
 
1526
- @lexer.max_numparam_stack.pop
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
- @lexer.max_numparam_stack.cant_have_numparams!
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
- @lexer.max_numparam_stack.cant_have_numparams!
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
- @lexer.max_numparam_stack.push
1702
+ @max_numparam_stack.push
1676
1703
  }
1677
1704
  opt_block_param compstmt
1678
1705
  {
1679
- args = @lexer.max_numparam > 0 ? @builder.numargs(@lexer.max_numparam) : val[1]
1706
+ args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1]
1680
1707
  result = [ args, val[2] ]
1681
1708
 
1682
- @lexer.max_numparam_stack.pop
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
- @lexer.max_numparam_stack.push
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 = @lexer.max_numparam > 0 ? @builder.numargs(@lexer.max_numparam) : val[2]
1722
+ args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2]
1696
1723
  result = [ args, val[3] ]
1697
1724
 
1698
- @lexer.max_numparam_stack.pop
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
- @lexer.max_numparam_stack.cant_have_numparams!
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
- @lexer.max_numparam_stack.cant_have_numparams!
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