parser 2.6.5.0 → 2.7.0.4

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.
@@ -2,17 +2,23 @@
2
2
 
3
3
  module Parser
4
4
 
5
- class Lexer::MaxNumparamStack
5
+ class MaxNumparamStack
6
+ attr_reader :stack
7
+
6
8
  def initialize
7
9
  @stack = []
8
10
  end
9
11
 
10
- def cant_have_numparams!
12
+ def has_ordinary_params!
11
13
  set(-1)
12
14
  end
13
15
 
14
- def can_have_numparams?
15
- top >= 0
16
+ def has_ordinary_params?
17
+ top < 0
18
+ end
19
+
20
+ def has_numparams?
21
+ top > 0
16
22
  end
17
23
 
18
24
  def register(numparam)
@@ -31,42 +31,48 @@ module Parser
31
31
  :heredoc_id_has_newline => 'here document identifier across newlines, never match',
32
32
  :heredoc_id_ends_with_nl => 'here document identifier ends with a newline',
33
33
  :unterminated_heredoc_id => 'unterminated heredoc id',
34
- :leading_zero_in_numparam => 'leading zero is not allowed as a numbered parameter',
35
- :numparam_outside_block => 'numbered parameter outside block',
36
- :too_large_numparam => 'too large numbered parameter',
37
- :ordinary_param_defined => 'ordinary parameter is defined',
38
34
 
39
35
  # Lexer warnings
40
36
  :invalid_escape_use => 'invalid character syntax; use ?%{escape}',
41
37
  :ambiguous_literal => 'ambiguous first argument; put parentheses or a space even after the operator',
42
38
  :ambiguous_prefix => "`%{prefix}' interpreted as argument prefix",
39
+ :triple_dot_at_eol => '... at EOL, should be parenthesized',
43
40
 
44
41
  # Parser errors
45
- :nth_ref_alias => '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
+ :undefined_lvar => "no such local variable: `%{name}'",
74
+ :duplicate_variable_name => 'duplicate variable name %{name}',
75
+ :duplicate_pattern_key => 'duplicate hash pattern key %{name}',
70
76
 
71
77
  # Parser warnings
72
78
  :useless_else => 'else without rescue is useless',
@@ -24,9 +24,14 @@ module Parser
24
24
  kwbegin begin retry preexe postexe iflipflop eflipflop
25
25
  shadowarg complex rational __FILE__ __LINE__ __ENCODING__
26
26
  ident root lambda indexasgn index procarg0
27
- 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
34
+ empty_else
30
35
  ).map(&:to_sym).to_set.freeze
31
36
 
32
37
  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,387 @@ opt_block_args_tail:
1712
1739
  }
1713
1740
  | case_body
1714
1741
 
1742
+ p_case_body: kIN
1743
+ {
1744
+ @lexer.state = :expr_beg
1745
+ @lexer.command_start = false
1746
+ @pattern_variables.push
1747
+ @pattern_hash_keys.push
1748
+
1749
+ result = @lexer.in_kwarg
1750
+ @lexer.in_kwarg = true
1751
+ }
1752
+ p_top_expr then
1753
+ {
1754
+ @lexer.in_kwarg = val[1]
1755
+ }
1756
+ compstmt p_cases
1757
+ {
1758
+ result = [ @builder.in_pattern(val[0], *val[2], val[3], val[5]),
1759
+ *val[6] ]
1760
+ }
1761
+
1762
+ p_cases: opt_else
1763
+ {
1764
+ result = [ val[0] ]
1765
+ }
1766
+ | p_case_body
1767
+
1768
+ p_top_expr: p_top_expr_body
1769
+ {
1770
+ result = [ val[0], nil ]
1771
+ }
1772
+ | p_top_expr_body kIF_MOD expr_value
1773
+ {
1774
+ result = [ val[0], @builder.if_guard(val[1], val[2]) ]
1775
+ }
1776
+ | p_top_expr_body kUNLESS_MOD expr_value
1777
+ {
1778
+ result = [ val[0], @builder.unless_guard(val[1], val[2]) ]
1779
+ }
1780
+
1781
+ p_top_expr_body: p_expr
1782
+ | p_expr tCOMMA
1783
+ {
1784
+ # array patterns that end with comma
1785
+ # like 1, 2,
1786
+ # must be emitted as `array_pattern_with_tail`
1787
+ item = @builder.match_with_trailing_comma(val[0])
1788
+ result = @builder.array_pattern(nil, [ item ], nil)
1789
+ }
1790
+ | p_expr tCOMMA p_args
1791
+ {
1792
+ result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil)
1793
+ }
1794
+ | p_args_tail
1795
+ {
1796
+ result = @builder.array_pattern(nil, val[0], nil)
1797
+ }
1798
+ | p_kwargs
1799
+ {
1800
+ result = @builder.hash_pattern(nil, val[0], nil)
1801
+ }
1802
+
1803
+ p_expr: p_as
1804
+
1805
+ p_as: p_expr tASSOC p_variable
1806
+ {
1807
+ result = @builder.match_as(val[0], val[1], val[2])
1808
+ }
1809
+ | p_alt
1810
+
1811
+ p_alt: p_alt tPIPE p_expr_basic
1812
+ {
1813
+ result = @builder.match_alt(val[0], val[1], val[2])
1814
+ }
1815
+ | p_expr_basic
1816
+
1817
+ p_lparen: tLPAREN2
1818
+ {
1819
+ result = val[0]
1820
+ @pattern_hash_keys.push
1821
+ }
1822
+
1823
+ p_lbracket: tLBRACK2
1824
+ {
1825
+ result = val[0]
1826
+ @pattern_hash_keys.push
1827
+ }
1828
+
1829
+ p_expr_basic: p_value
1830
+ | p_const p_lparen p_args rparen
1831
+ {
1832
+ @pattern_hash_keys.pop
1833
+ pattern = @builder.array_pattern(nil, val[2], nil)
1834
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1835
+ }
1836
+ | p_const p_lparen p_kwargs rparen
1837
+ {
1838
+ @pattern_hash_keys.pop
1839
+ pattern = @builder.hash_pattern(nil, val[2], nil)
1840
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1841
+ }
1842
+ | p_const tLPAREN2 rparen
1843
+ {
1844
+ pattern = @builder.array_pattern(val[1], nil, val[2])
1845
+ result = @builder.const_pattern(val[0], val[1], pattern, val[2])
1846
+ }
1847
+ | p_const p_lbracket p_args rbracket
1848
+ {
1849
+ @pattern_hash_keys.pop
1850
+ pattern = @builder.array_pattern(nil, val[2], nil)
1851
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1852
+ }
1853
+ | p_const p_lbracket p_kwargs rbracket
1854
+ {
1855
+ @pattern_hash_keys.pop
1856
+ pattern = @builder.hash_pattern(nil, val[2], nil)
1857
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1858
+ }
1859
+ | p_const tLBRACK2 rbracket
1860
+ {
1861
+ pattern = @builder.array_pattern(val[1], nil, val[2])
1862
+ result = @builder.const_pattern(val[0], val[1], pattern, val[2])
1863
+ }
1864
+ | tLBRACK
1865
+ {
1866
+ @pattern_hash_keys.push
1867
+ }
1868
+ p_args rbracket
1869
+ {
1870
+ @pattern_hash_keys.pop
1871
+ result = @builder.array_pattern(val[0], val[2], val[3])
1872
+ }
1873
+ | tLBRACK rbracket
1874
+ {
1875
+ result = @builder.array_pattern(val[0], [], val[1])
1876
+ }
1877
+ | tLBRACE
1878
+ {
1879
+ @pattern_hash_keys.push
1880
+ }
1881
+ p_kwargs tRCURLY
1882
+ {
1883
+ @pattern_hash_keys.pop
1884
+ result = @builder.hash_pattern(val[0], val[2], val[3])
1885
+ }
1886
+ | tLBRACE tRCURLY
1887
+ {
1888
+ result = @builder.hash_pattern(val[0], [], val[1])
1889
+ }
1890
+ | tLPAREN
1891
+ {
1892
+ @pattern_hash_keys.push
1893
+ }
1894
+ p_expr rparen
1895
+ {
1896
+ @pattern_hash_keys.pop
1897
+ result = @builder.begin(val[0], val[2], val[3])
1898
+ }
1899
+
1900
+ p_args: p_expr
1901
+ {
1902
+ result = [ val[0] ]
1903
+ }
1904
+ | p_args_head
1905
+ {
1906
+ result = val[0]
1907
+ }
1908
+ | p_args_head p_arg
1909
+ {
1910
+ result = [ *val[0], val[1] ]
1911
+ }
1912
+ | p_args_head tSTAR tIDENTIFIER
1913
+ {
1914
+ match_rest = @builder.match_rest(val[1], val[2])
1915
+ result = [ *val[0], match_rest ]
1916
+ }
1917
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
1918
+ {
1919
+ match_rest = @builder.match_rest(val[1], val[2])
1920
+ result = [ *val[0], match_rest, *val[4] ]
1921
+ }
1922
+ | p_args_head tSTAR
1923
+ {
1924
+ result = [ *val[0], @builder.match_rest(val[1]) ]
1925
+ }
1926
+ | p_args_head tSTAR tCOMMA p_args_post
1927
+ {
1928
+ result = [ *val[0], @builder.match_rest(val[1]), *val[3] ]
1929
+ }
1930
+ | p_args_tail
1931
+
1932
+ p_args_head: p_arg tCOMMA
1933
+ {
1934
+ # array patterns that end with comma
1935
+ # like [1, 2,]
1936
+ # must be emitted as `array_pattern_with_tail`
1937
+ item = @builder.match_with_trailing_comma(val[0])
1938
+ result = [ item ]
1939
+ }
1940
+ | p_args_head p_arg tCOMMA
1941
+ {
1942
+ # array patterns that end with comma
1943
+ # like [1, 2,]
1944
+ # must be emitted as `array_pattern_with_tail`
1945
+ last_item = @builder.match_with_trailing_comma(val[1])
1946
+ result = [ *val[0], last_item ]
1947
+ }
1948
+
1949
+ p_args_tail: tSTAR tIDENTIFIER
1950
+ {
1951
+ match_rest = @builder.match_rest(val[0], val[1])
1952
+ result = [ match_rest ]
1953
+ }
1954
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
1955
+ {
1956
+ match_rest = @builder.match_rest(val[0], val[1])
1957
+ result = [ match_rest, *val[3] ]
1958
+ }
1959
+ | tSTAR
1960
+ {
1961
+ match_rest = @builder.match_rest(val[0])
1962
+ result = [ match_rest ]
1963
+ }
1964
+ | tSTAR tCOMMA p_args_post
1965
+ {
1966
+ match_rest = @builder.match_rest(val[0])
1967
+ result = [ match_rest, *val[2] ]
1968
+ }
1969
+
1970
+ p_args_post: p_arg
1971
+ {
1972
+ result = [ val[0] ]
1973
+ }
1974
+ | p_args_post tCOMMA p_arg
1975
+ {
1976
+ result = [ *val[0], val[2] ]
1977
+ }
1978
+
1979
+ p_arg: p_expr
1980
+
1981
+ p_kwargs: p_kwarg tCOMMA p_kwrest
1982
+ {
1983
+ result = [ *val[0], *val[2] ]
1984
+ }
1985
+ | p_kwarg
1986
+ {
1987
+ result = val[0]
1988
+ }
1989
+ | p_kwrest
1990
+ {
1991
+ result = val[0]
1992
+ }
1993
+ | p_kwarg tCOMMA p_kwnorest
1994
+ {
1995
+ result = [ *val[0], *val[2] ]
1996
+ }
1997
+ | p_kwnorest
1998
+ {
1999
+ result = [ *val[0], *val[2] ]
2000
+ }
2001
+
2002
+ p_kwarg: p_kw
2003
+ {
2004
+ result = [ val[0] ]
2005
+ }
2006
+ | p_kwarg tCOMMA p_kw
2007
+ {
2008
+ result = [ *val[0], val[2] ]
2009
+ }
2010
+
2011
+ p_kw: p_kw_label p_expr
2012
+ {
2013
+ result = @builder.match_pair(*val[0], val[1])
2014
+ }
2015
+ | p_kw_label
2016
+ {
2017
+ result = @builder.match_label(*val[0])
2018
+ }
2019
+
2020
+ p_kw_label: tLABEL
2021
+ {
2022
+ check_kwarg_name(val[0])
2023
+ result = [:label, val[0]]
2024
+ }
2025
+ | tSTRING_BEG string_contents tLABEL_END
2026
+ {
2027
+ result = [:quoted, [val[0], val[1], val[2]]]
2028
+ }
2029
+
2030
+ p_kwrest: kwrest_mark tIDENTIFIER
2031
+ {
2032
+ result = [ @builder.match_rest(val[0], val[1]) ]
2033
+ }
2034
+ | kwrest_mark
2035
+ {
2036
+ result = [ @builder.match_rest(val[0], nil) ]
2037
+ }
2038
+
2039
+ p_kwnorest: kwrest_mark kNIL
2040
+ {
2041
+ result = [ @builder.match_nil_pattern(val[0], val[1]) ]
2042
+ }
2043
+
2044
+ p_value: p_primitive
2045
+ | p_primitive tDOT2 p_primitive
2046
+ {
2047
+ result = @builder.range_inclusive(val[0], val[1], val[2])
2048
+ }
2049
+ | p_primitive tDOT3 p_primitive
2050
+ {
2051
+ result = @builder.range_exclusive(val[0], val[1], val[2])
2052
+ }
2053
+ | p_primitive tDOT2
2054
+ {
2055
+ result = @builder.range_inclusive(val[0], val[1], nil)
2056
+ }
2057
+ | p_primitive tDOT3
2058
+ {
2059
+ result = @builder.range_exclusive(val[0], val[1], nil)
2060
+ }
2061
+ | p_variable
2062
+ | p_var_ref
2063
+ | p_const
2064
+ | tBDOT2 p_primitive
2065
+ {
2066
+ result = @builder.range_inclusive(nil, val[0], val[1])
2067
+ }
2068
+ | tBDOT3 p_primitive
2069
+ {
2070
+ result = @builder.range_exclusive(nil, val[0], val[1])
2071
+ }
2072
+
2073
+ p_primitive: literal
2074
+ | strings
2075
+ | xstring
2076
+ | regexp
2077
+ | words
2078
+ | qwords
2079
+ | symbols
2080
+ | qsymbols
2081
+ | keyword_variable
2082
+ {
2083
+ result = @builder.accessible(val[0])
2084
+ }
2085
+ | tLAMBDA lambda
2086
+ {
2087
+ lambda_call = @builder.call_lambda(val[0])
2088
+
2089
+ args, (begin_t, body, end_t) = val[1]
2090
+ result = @builder.block(lambda_call,
2091
+ begin_t, args, body, end_t)
2092
+ }
2093
+
2094
+ p_variable: tIDENTIFIER
2095
+ {
2096
+ result = @builder.match_var(val[0])
2097
+ }
2098
+
2099
+ p_var_ref: tCARET tIDENTIFIER
2100
+ {
2101
+ name = val[1][0]
2102
+ unless static_env.declared?(name)
2103
+ diagnostic :error, :undefined_lvar, { :name => name }, val[1]
2104
+ end
2105
+
2106
+ lvar = @builder.accessible(@builder.ident(val[1]))
2107
+ result = @builder.pin(val[0], lvar)
2108
+ }
2109
+
2110
+ p_const: tCOLON3 cname
2111
+ {
2112
+ result = @builder.const_global(val[0], val[1])
2113
+ }
2114
+ | p_const tCOLON2 cname
2115
+ {
2116
+ result = @builder.const_fetch(val[0], val[1], val[2])
2117
+ }
2118
+ | tCONSTANT
2119
+ {
2120
+ result = @builder.const(val[0])
2121
+ }
2122
+
1715
2123
  opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1716
2124
  {
1717
2125
  assoc_t, exc_var = val[2]
@@ -1918,10 +2326,6 @@ regexp_contents: # nothing
1918
2326
  {
1919
2327
  result = @builder.cvar(val[0])
1920
2328
  }
1921
- | tNUMPARAM
1922
- {
1923
- result = @builder.numparam(val[0])
1924
- }
1925
2329
  | backref
1926
2330
 
1927
2331
  symbol: ssym
@@ -1994,10 +2398,6 @@ regexp_contents: # nothing
1994
2398
  {
1995
2399
  result = @builder.cvar(val[0])
1996
2400
  }
1997
- | tNUMPARAM
1998
- {
1999
- result = @builder.numparam(val[0])
2000
- }
2001
2401
 
2002
2402
  keyword_variable: kNIL
2003
2403
  {
@@ -2030,6 +2430,46 @@ keyword_variable: kNIL
2030
2430
 
2031
2431
  var_ref: user_variable
2032
2432
  {
2433
+ if (node = val[0]) && node.type == :ident
2434
+ name = node.children[0]
2435
+
2436
+ if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && context.in_dynamic_block?
2437
+ # definitely an implicit param
2438
+ location = node.loc.expression
2439
+
2440
+ if max_numparam_stack.has_ordinary_params?
2441
+ diagnostic :error, :ordinary_param_defined, nil, [nil, location]
2442
+ end
2443
+
2444
+ raw_context = context.stack.dup
2445
+ raw_max_numparam_stack = max_numparam_stack.stack.dup
2446
+
2447
+ # ignore current block scope
2448
+ raw_context.pop
2449
+ raw_max_numparam_stack.pop
2450
+
2451
+ raw_context.reverse_each do |outer_scope|
2452
+ if outer_scope == :block || outer_scope == :lambda
2453
+ outer_scope_has_numparams = raw_max_numparam_stack.pop > 0
2454
+
2455
+ if outer_scope_has_numparams
2456
+ diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location]
2457
+ else
2458
+ # for now it's ok, but an outer scope can also be a block
2459
+ # with numparams, so we need to continue
2460
+ end
2461
+ else
2462
+ # found an outer scope that can't have numparams
2463
+ # like def/class/etc
2464
+ break
2465
+ end
2466
+ end
2467
+
2468
+ static_env.declare(name)
2469
+ max_numparam_stack.register(name[1].to_i)
2470
+ end
2471
+ end
2472
+
2033
2473
  result = @builder.accessible(val[0])
2034
2474
  }
2035
2475
  | keyword_variable
@@ -2072,6 +2512,13 @@ keyword_variable: kNIL
2072
2512
  {
2073
2513
  result = @builder.args(val[0], val[1], val[2])
2074
2514
 
2515
+ @lexer.state = :expr_value
2516
+ }
2517
+ | tLPAREN2 args_forward rparen
2518
+ {
2519
+ result = @builder.forward_args(val[0], val[1], val[2])
2520
+ @static_env.declare_forward_args
2521
+
2075
2522
  @lexer.state = :expr_value
2076
2523
  }
2077
2524
  | {
@@ -2204,6 +2651,11 @@ keyword_variable: kNIL
2204
2651
  result = []
2205
2652
  }
2206
2653
 
2654
+ args_forward: tBDOT3
2655
+ {
2656
+ result = val[0]
2657
+ }
2658
+
2207
2659
  f_bad_arg: tCONSTANT
2208
2660
  {
2209
2661
  diagnostic :error, :argument_const, nil, val[0]
@@ -2226,18 +2678,20 @@ keyword_variable: kNIL
2226
2678
  {
2227
2679
  @static_env.declare val[0][0]
2228
2680
 
2229
- @lexer.max_numparam_stack.cant_have_numparams!
2681
+ @max_numparam_stack.has_ordinary_params!
2230
2682
 
2231
2683
  result = val[0]
2232
2684
  }
2233
2685
 
2234
2686
  f_arg_asgn: f_norm_arg
2235
2687
  {
2688
+ @current_arg_stack.set(val[0][0])
2236
2689
  result = val[0]
2237
2690
  }
2238
2691
 
2239
2692
  f_arg_item: f_arg_asgn
2240
2693
  {
2694
+ @current_arg_stack.set(0)
2241
2695
  result = @builder.arg(val[0])
2242
2696
  }
2243
2697
  | tLPAREN f_margs rparen
@@ -2260,17 +2714,21 @@ keyword_variable: kNIL
2260
2714
 
2261
2715
  @static_env.declare val[0][0]
2262
2716
 
2263
- @lexer.max_numparam_stack.cant_have_numparams!
2717
+ @max_numparam_stack.has_ordinary_params!
2718
+
2719
+ @current_arg_stack.set(val[0][0])
2264
2720
 
2265
2721
  result = val[0]
2266
2722
  }
2267
2723
 
2268
2724
  f_kw: f_label arg_value
2269
2725
  {
2726
+ @current_arg_stack.set(nil)
2270
2727
  result = @builder.kwoptarg(val[0], val[1])
2271
2728
  }
2272
2729
  | f_label
2273
2730
  {
2731
+ @current_arg_stack.set(nil)
2274
2732
  result = @builder.kwarg(val[0])
2275
2733
  }
2276
2734
 
@@ -2321,11 +2779,13 @@ keyword_variable: kNIL
2321
2779
 
2322
2780
  f_opt: f_arg_asgn tEQL arg_value
2323
2781
  {
2782
+ @current_arg_stack.set(0)
2324
2783
  result = @builder.optarg(val[0], val[1], val[2])
2325
2784
  }
2326
2785
 
2327
2786
  f_block_opt: f_arg_asgn tEQL primary_value
2328
2787
  {
2788
+ @current_arg_stack.set(0)
2329
2789
  result = @builder.optarg(val[0], val[1], val[2])
2330
2790
  }
2331
2791