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.
@@ -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