parser 2.6.5.0 → 2.7.0.4

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