rubinius-melbourne 2.1.0.0 → 2.2.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.
@@ -15,6 +15,8 @@
15
15
  #define YYDEBUG 1
16
16
  #define YYERROR_VERBOSE 1
17
17
 
18
+ #include <string.h>
19
+
18
20
  #include "namespace.h"
19
21
  #include "melbourne.hpp"
20
22
  #include "grammar.hpp"
@@ -54,17 +56,17 @@ static int parser_yyerror(rb_parser_state*, const char *);
54
56
 
55
57
  static int yylex(void*, void *);
56
58
 
57
- #define BITSTACK_PUSH(stack, n) (stack = (stack<<1)|((n)&1))
58
- #define BITSTACK_POP(stack) (stack >>= 1)
59
- #define BITSTACK_LEXPOP(stack) (stack = (stack >> 1) | (stack & 1))
60
- #define BITSTACK_SET_P(stack) (stack&1)
59
+ #define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
60
+ #define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
61
+ #define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
62
+ #define BITSTACK_SET_P(stack) ((stack)&1)
61
63
 
62
- #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, n)
64
+ #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, (n))
63
65
  #define COND_POP() BITSTACK_POP(cond_stack)
64
66
  #define COND_LEXPOP() BITSTACK_LEXPOP(cond_stack)
65
67
  #define COND_P() BITSTACK_SET_P(cond_stack)
66
68
 
67
- #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, n)
69
+ #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, (n))
68
70
  #define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
69
71
  #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
70
72
  #define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
@@ -101,7 +103,8 @@ static NODE *parser_new_evstr(rb_parser_state*, NODE*);
101
103
  static NODE *parser_evstr2dstr(rb_parser_state*, NODE*);
102
104
  static NODE *parser_call_bin_op(rb_parser_state*, NODE*, ID, NODE*);
103
105
  static NODE *parser_call_uni_op(rb_parser_state*, NODE*, ID);
104
- static NODE *parser_new_args(rb_parser_state*, NODE*, NODE*, ID, NODE*, ID);
106
+ static NODE *parser_new_args(rb_parser_state*, NODE*, NODE*, ID, NODE*, NODE*);
107
+ static NODE *parser_new_args_tail(rb_parser_state*, NODE*, ID, ID);
105
108
  static NODE *splat_array(NODE*);
106
109
 
107
110
  static NODE *parser_negate_lit(rb_parser_state*, NODE*);
@@ -125,6 +128,9 @@ static NODE *parser_aryset(rb_parser_state*, NODE*, NODE*);
125
128
  static NODE *parser_attrset(rb_parser_state*, NODE*, ID);
126
129
  static void rb_parser_backref_error(rb_parser_state*, NODE*);
127
130
  static NODE *parser_node_assign(rb_parser_state*, NODE*, NODE*);
131
+ static NODE *parser_new_op_assign(rb_parser_state*, NODE*, ID, NODE*);
132
+ static NODE *parser_new_attr_op_assign(rb_parser_state*, NODE*, ID, ID, NODE*);
133
+ static NODE *parser_new_const_op_assign(rb_parser_state*, NODE*, ID, NODE*);
128
134
 
129
135
  static NODE *parser_match_op(rb_parser_state*, NODE*, NODE*);
130
136
  static int parser_arg_var(rb_parser_state*, ID);
@@ -155,6 +161,7 @@ rb_parser_state *parser_alloc_state() {
155
161
  class_nest = 0;
156
162
  in_single = 0;
157
163
  in_def = 0;
164
+ brace_nest = 0;
158
165
  compile_for_eval = 0;
159
166
  cur_mid = 0;
160
167
  tokenbuf = NULL;
@@ -241,6 +248,23 @@ static int rb_compile_error(rb_parser_state* parser_state, const char *fmt, ...)
241
248
  return count;
242
249
  }
243
250
 
251
+ static void
252
+ rb_name_error(ID id, const char *fmt, ...)
253
+ {
254
+ char msg[BUFSIZ];
255
+ VALUE exc, argv[2];
256
+ va_list args;
257
+
258
+ va_start(args, fmt);
259
+ vsnprintf(msg, BUFSIZ, fmt, args);
260
+ argv[0] = rb_str_new2(msg);
261
+ va_end(args);
262
+
263
+ argv[1] = ID2SYM(id);
264
+ exc = rb_class_new_instance(2, argv, rb_eNameError);
265
+ rb_exc_raise(exc);
266
+ }
267
+
244
268
  static int _debug_print(const char *fmt, ...) {
245
269
  #if SHOW_PARSER_WARNS
246
270
  va_list ar;
@@ -285,9 +309,13 @@ static int scan_hex(const char *start, size_t len, size_t *retlen);
285
309
  #define arg_concat(a, b) parser_arg_concat(parser_state, a, b)
286
310
  #define list_append(l, i) parser_list_append(parser_state, l, i)
287
311
  #define node_assign(a, b) parser_node_assign(parser_state, a, b)
312
+ #define new_op_assign(l, o, r) parser_new_op_assign(parser_state, l, o, r)
313
+ #define new_attr_op_assign(l,a,o,r) parser_new_attr_op_assign(parser_state, l, a, o, r)
314
+ #define new_const_op_assign(l,o,r) parser_new_const_op_assign(parser_state, l, o, r)
288
315
  #define call_bin_op(a, s, b) parser_call_bin_op(parser_state, a, s, b)
289
316
  #define call_uni_op(n, s) parser_call_uni_op(parser_state, n, s)
290
- #define new_args(f,o,r,p,b) parser_new_args(parser_state, f, o, r, p, b)
317
+ #define new_args(f,o,r,p,t) parser_new_args(parser_state, f, o, r, p, t)
318
+ #define new_args_tail(k,kr,b) parser_new_args_tail(parser_state, k, kr, b)
291
319
  #define negate_lit(n) parser_negate_lit(parser_state, n)
292
320
  #define ret_args(n) parser_ret_args(parser_state, n)
293
321
  #define assignable(a, b) parser_assignable(parser_state, a, b)
@@ -378,7 +406,8 @@ static int scan_hex(const char *start, size_t len, size_t *retlen);
378
406
  #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
379
407
  #define TOK_INTERN(mb) parser_intern3(tok(), toklen(), parser_state->enc)
380
408
 
381
- #define NEW_BLOCK_VAR(b, v) NEW_NODE(NODE_BLOCK_PASS, 0, b, v)
409
+ #define NEW_BLOCK_VAR(b, v) NEW_NODE(NODE_BLOCK_PASS, 0, b, v)
410
+ #define NEW_REQ_KW NEW_LIT(ID2SYM(parser_intern("*")))
382
411
 
383
412
  /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
384
413
  for instance). This is too low for Ruby to parse some files, such as
@@ -455,32 +484,34 @@ static int scan_hex(const char *start, size_t len, size_t *retlen);
455
484
  keyword__ENCODING__
456
485
 
457
486
  %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
458
- %token <node> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
487
+ %token <node> tINTEGER tFLOAT tRATIONAL tIMAGINARY tSTRING_CONTENT tCHAR
459
488
  %token <node> tNTH_REF tBACK_REF
460
489
  %token <num> tREGEXP_END
461
490
 
462
491
  %type <node> singleton strings string string1 xstring regexp
463
492
  %type <node> string_contents xstring_contents regexp_contents string_content
464
- %type <node> words qwords word_list qword_list word
465
- %type <node> literal numeric dsym cpath
493
+ %type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
494
+ %type <node> literal numeric simple_numeric dsym cpath
466
495
  %type <node> top_compstmt top_stmts top_stmt
467
- %type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
468
- %type <node> expr_value arg_value primary_value
496
+ %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
497
+ %type <node> expr_value arg_value primary_value fcall
469
498
  %type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
470
499
  %type <node> args call_args opt_call_args
471
- %type <node> paren_args opt_paren_args
500
+ %type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
472
501
  %type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
473
- %type <node> command_asgn mrhs superclass block_call block_command
502
+ %type <node> command_asgn mrhs mrhs_arg superclass block_call block_command
474
503
  %type <node> f_block_optarg f_block_opt
475
504
  %type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
476
505
  %type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
477
506
  %type <node> block_param opt_block_param block_param_def f_opt
507
+ %type <node> f_kwarg f_kw f_block_kwarg f_block_kw
478
508
  %type <node> bv_decls opt_bv_decl bvar
479
509
  %type <node> lambda f_larglist lambda_body
480
510
  %type <node> brace_block cmd_brace_block do_block lhs none fitem
481
511
  %type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
482
512
  %type <id> fsym keyword_variable user_variable sym symbol operation operation2 operation3
483
513
  %type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
514
+ %type <id> f_kwrest f_label
484
515
 
485
516
  %token tUPLUS /* unary+ */
486
517
  %token tUMINUS /* unary- */
@@ -507,10 +538,11 @@ static int scan_hex(const char *start, size_t len, size_t *retlen);
507
538
  %token tLBRACE /* { */
508
539
  %token tLBRACE_ARG /* { */
509
540
  %token tSTAR /* * */
541
+ %token tDSTAR /* ** */
510
542
  %token tAMPER /* & */
511
543
  %token tLAMBDA /* -> */
512
- %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
513
- %token tSTRING_DBEG tSTRING_DVAR tSTRING_END tLAMBEG
544
+ %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
545
+ %token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
514
546
 
515
547
  /*
516
548
  * precedence table
@@ -640,11 +672,11 @@ stmts : none
640
672
  {
641
673
  $$ = NEW_BEGIN(0);
642
674
  }
643
- | stmt
675
+ | stmt_or_begin
644
676
  {
645
677
  $$ = newline_node($1);
646
678
  }
647
- | stmts terms stmt
679
+ | stmts terms stmt_or_begin
648
680
  {
649
681
  $$ = block_append($1, newline_node($3));
650
682
  }
@@ -654,6 +686,20 @@ stmts : none
654
686
  }
655
687
  ;
656
688
 
689
+ stmt_or_begin : stmt
690
+ {
691
+ $$ = $1;
692
+ }
693
+ | keyword_BEGIN
694
+ {
695
+ yy_error("BEGIN is permitted only at toplevel");
696
+ }
697
+ '{' top_compstmt '}'
698
+ {
699
+ $$ = NEW_BEGIN(0);
700
+ }
701
+ ;
702
+
657
703
  stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
658
704
  {
659
705
  $$ = NEW_ALIAS($2, $4);
@@ -722,30 +768,13 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
722
768
  | mlhs '=' command_call
723
769
  {
724
770
  value_expr($3);
725
- $1->nd_value = ($1->nd_head) ? NEW_TO_ARY($3) : NEW_ARRAY($3);
771
+ $1->nd_value = $3;
726
772
  $$ = $1;
727
773
  }
728
774
  | var_lhs tOP_ASGN command_call
729
775
  {
730
776
  value_expr($3);
731
- if($1) {
732
- ID vid = $1->nd_vid;
733
- if($2 == tOROP) {
734
- $1->nd_value = $3;
735
- $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
736
- if(is_asgn_or_id(vid)) {
737
- $$->nd_aid = vid;
738
- }
739
- } else if($2 == tANDOP) {
740
- $1->nd_value = $3;
741
- $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
742
- } else {
743
- $$ = $1;
744
- $$->nd_value = call_bin_op(gettable(vid), $2, $3);
745
- }
746
- } else {
747
- $$ = NEW_BEGIN(0);
748
- }
777
+ $$ = new_op_assign($1, $2, $3);
749
778
  }
750
779
  | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
751
780
  {
@@ -767,69 +796,41 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
767
796
  | primary_value '.' tIDENTIFIER tOP_ASGN command_call
768
797
  {
769
798
  value_expr($5);
770
- if($4 == tOROP) {
771
- $4 = 0;
772
- } else if($4 == tANDOP) {
773
- $4 = 1;
774
- } else {
775
- $4 = convert_op($4);
776
- }
777
- $$ = NEW_OP_ASGN2($1, $3, $4, $5);
778
- fixpos($$, $1);
799
+ $$ = new_attr_op_assign($1, $3, $4, $5);
779
800
  }
780
801
  | primary_value '.' tCONSTANT tOP_ASGN command_call
781
802
  {
782
803
  value_expr($5);
783
- if($4 == tOROP) {
784
- $4 = 0;
785
- } else if($4 == tANDOP) {
786
- $4 = 1;
787
- } else {
788
- $4 = convert_op($4);
789
- }
790
- $$ = NEW_OP_ASGN2($1, $3, $4, $5);
791
- fixpos($$, $1);
804
+ $$ = new_attr_op_assign($1, $3, $4, $5);
792
805
  }
793
806
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
794
807
  {
795
- yy_error("constant re-assignment");
796
- $$ = 0;
808
+ $$ = NEW_COLON2($1, $3);
809
+ $$ = new_const_op_assign($$, $4, $5);
797
810
  }
798
811
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
799
812
  {
800
813
  value_expr($5);
801
- if($4 == tOROP) {
802
- $4 = 0;
803
- } else if($4 == tANDOP) {
804
- $4 = 1;
805
- } else {
806
- $4 = convert_op($4);
807
- }
808
- $$ = NEW_OP_ASGN2($1, $3, $4, $5);
809
- fixpos($$, $1);
814
+ $$ = new_attr_op_assign($1, $3, $4, $5);
810
815
  }
811
816
  | backref tOP_ASGN command_call
812
817
  {
813
818
  rb_backref_error($1);
814
- $$ = 0;
819
+ $$ = NEW_BEGIN(0);
815
820
  }
816
821
  | lhs '=' mrhs
817
822
  {
818
823
  value_expr($3);
819
824
  $$ = node_assign($1, $3);
820
825
  }
821
- | mlhs '=' arg_value
822
- {
823
- $1->nd_value = ($1->nd_head) ? NEW_TO_ARY($3) : NEW_ARRAY($3);
824
- $$ = $1;
825
- }
826
- | mlhs '=' mrhs
826
+ | mlhs '=' mrhs_arg
827
827
  {
828
828
  $1->nd_value = $3;
829
829
  $$ = $1;
830
830
  }
831
831
  | expr
832
832
  ;
833
+
833
834
  command_asgn : lhs '=' command_call
834
835
  {
835
836
  value_expr($3);
@@ -841,6 +842,7 @@ command_asgn : lhs '=' command_call
841
842
  $$ = node_assign($1, $3);
842
843
  }
843
844
  ;
845
+
844
846
  expr : command_call
845
847
  | expr keyword_and expr
846
848
  {
@@ -874,11 +876,7 @@ command_call : command
874
876
  ;
875
877
 
876
878
  block_command : block_call
877
- | block_call '.' operation2 command_args
878
- {
879
- $$ = NEW_CALL($1, $3, $4);
880
- }
881
- | block_call tCOLON2 operation2 command_args
879
+ | block_call dot_or_colon operation2 command_args
882
880
  {
883
881
  $$ = NEW_CALL($1, $3, $4);
884
882
  }
@@ -899,17 +897,25 @@ cmd_brace_block : tLBRACE_ARG
899
897
  }
900
898
  ;
901
899
 
902
- command : operation command_args %prec tLOWEST
900
+ fcall : operation
903
901
  {
904
- $$ = NEW_FCALL($1, $2);
905
- fixpos($$, $2);
902
+ $$ = NEW_FCALL($1, 0);
903
+ nd_set_line($$, tokline);
904
+ }
905
+ ;
906
+
907
+ command : fcall command_args %prec tLOWEST
908
+ {
909
+ $$ = $1;
910
+ $$->nd_args = $2;
906
911
  }
907
- | operation command_args cmd_brace_block
912
+ | fcall command_args cmd_brace_block
908
913
  {
909
914
  block_dup_check($2, $3);
910
- $3->nd_iter = NEW_FCALL($1, $2);
915
+ $1->nd_args = $2;
916
+ $3->nd_iter = $1;
911
917
  $$ = $3;
912
- fixpos($$, $2);
918
+ fixpos($$, $1);
913
919
  }
914
920
  | primary_value '.' operation2 command_args %prec tLOWEST
915
921
  {
@@ -1209,6 +1215,7 @@ op : '|' { $$ = '|'; }
1209
1215
  | '/' { $$ = '/'; }
1210
1216
  | '%' { $$ = '%'; }
1211
1217
  | tPOW { $$ = tPOW; }
1218
+ | tDSTAR { $$ = tDSTAR; }
1212
1219
  | '!' { $$ = '!'; }
1213
1220
  | '~' { $$ = '~'; }
1214
1221
  | tUPLUS { $$ = tUPLUS; }
@@ -1246,47 +1253,13 @@ arg : lhs '=' arg
1246
1253
  | var_lhs tOP_ASGN arg
1247
1254
  {
1248
1255
  value_expr($3);
1249
- if($1) {
1250
- ID vid = $1->nd_vid;
1251
- if($2 == tOROP) {
1252
- $1->nd_value = $3;
1253
- $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
1254
- if(is_asgn_or_id(vid)) {
1255
- $$->nd_aid = vid;
1256
- }
1257
- } else if($2 == tANDOP) {
1258
- $1->nd_value = $3;
1259
- $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
1260
- } else {
1261
- $$ = $1;
1262
- $$->nd_value = NEW_CALL(gettable(vid), $2, NEW_LIST($3));
1263
- }
1264
- } else {
1265
- $$ = NEW_BEGIN(0);
1266
- }
1256
+ $$ = new_op_assign($1, $2, $3);
1267
1257
  }
1268
1258
  | var_lhs tOP_ASGN arg modifier_rescue arg
1269
1259
  {
1270
1260
  value_expr($3);
1271
1261
  $3 = NEW_RESCUE($3, NEW_RESBODY(0, $5, 0), 0);
1272
- if($1) {
1273
- ID vid = $1->nd_vid;
1274
- if($2 == tOROP) {
1275
- $1->nd_value = $3;
1276
- $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
1277
- if(is_asgn_or_id(vid)) {
1278
- $$->nd_aid = vid;
1279
- }
1280
- } else if($2 == tANDOP) {
1281
- $1->nd_value = $3;
1282
- $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
1283
- } else {
1284
- $$ = $1;
1285
- $$->nd_value = NEW_CALL(gettable(vid), $2, NEW_LIST($3));
1286
- }
1287
- } else {
1288
- $$ = NEW_BEGIN(0);
1289
- }
1262
+ new_op_assign($1, $2, $3);
1290
1263
  }
1291
1264
  | primary_value '[' opt_call_args rbracket tOP_ASGN arg
1292
1265
  {
@@ -1312,51 +1285,27 @@ arg : lhs '=' arg
1312
1285
  | primary_value '.' tIDENTIFIER tOP_ASGN arg
1313
1286
  {
1314
1287
  value_expr($5);
1315
- if($4 == tOROP) {
1316
- $4 = 0;
1317
- } else if($4 == tANDOP) {
1318
- $4 = 1;
1319
- } else {
1320
- $4 = convert_op($4);
1321
- }
1322
- $$ = NEW_OP_ASGN2($1, $3, $4, $5);
1323
- fixpos($$, $1);
1288
+ $$ = new_attr_op_assign($1, $3, $4, $5);
1324
1289
  }
1325
1290
  | primary_value '.' tCONSTANT tOP_ASGN arg
1326
1291
  {
1327
1292
  value_expr($5);
1328
- if($4 == tOROP) {
1329
- $4 = 0;
1330
- } else if($4 == tANDOP) {
1331
- $4 = 1;
1332
- } else {
1333
- $4 = convert_op($4);
1334
- }
1335
- $$ = NEW_OP_ASGN2($1, $3, $4, $5);
1336
- fixpos($$, $1);
1293
+ $$ = new_attr_op_assign($1, $3, $4, $5);
1337
1294
  }
1338
1295
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
1339
1296
  {
1340
1297
  value_expr($5);
1341
- if($4 == tOROP) {
1342
- $4 = 0;
1343
- } else if($4 == tANDOP) {
1344
- $4 = 1;
1345
- } else {
1346
- $4 = convert_op($4);
1347
- }
1348
- $$ = NEW_OP_ASGN2($1, $3, $4, $5);
1349
- fixpos($$, $1);
1298
+ $$ = new_attr_op_assign($1, $3, $4, $5);
1350
1299
  }
1351
1300
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
1352
1301
  {
1353
- yy_error("constant re-assignment");
1354
- $$ = NEW_BEGIN(0);
1302
+ $$ = NEW_COLON2($1, $3);
1303
+ $$ = new_const_op_assign($$, $4, $5);
1355
1304
  }
1356
1305
  | tCOLON3 tCONSTANT tOP_ASGN arg
1357
1306
  {
1358
- yy_error("constant re-assignment");
1359
- $$ = NEW_BEGIN(0);
1307
+ $$ = NEW_COLON3($2);
1308
+ $$ = new_const_op_assign($$, $3, $4);
1360
1309
  }
1361
1310
  | backref tOP_ASGN arg
1362
1311
  {
@@ -1399,11 +1348,7 @@ arg : lhs '=' arg
1399
1348
  {
1400
1349
  $$ = call_bin_op($1, tPOW, $3);
1401
1350
  }
1402
- | tUMINUS_NUM tINTEGER tPOW arg
1403
- {
1404
- $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
1405
- }
1406
- | tUMINUS_NUM tFLOAT tPOW arg
1351
+ | tUMINUS_NUM simple_numeric tPOW arg
1407
1352
  {
1408
1353
  $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
1409
1354
  }
@@ -1549,6 +1494,18 @@ opt_paren_args : none
1549
1494
 
1550
1495
  opt_call_args : none
1551
1496
  | call_args
1497
+ | args ','
1498
+ {
1499
+ $$ = $1;
1500
+ }
1501
+ | args ',' assocs ','
1502
+ {
1503
+ $$ = arg_append($1, NEW_HASH($3));
1504
+ }
1505
+ | assocs ','
1506
+ {
1507
+ $$ = NEW_LIST(NEW_HASH($1));
1508
+ }
1552
1509
  ;
1553
1510
 
1554
1511
  call_args : command
@@ -1595,10 +1552,6 @@ opt_block_arg : ',' block_arg
1595
1552
  {
1596
1553
  $$ = $2;
1597
1554
  }
1598
- | ','
1599
- {
1600
- $$ = 0;
1601
- }
1602
1555
  | none
1603
1556
  {
1604
1557
  $$ = 0;
@@ -1633,6 +1586,10 @@ args : arg_value
1633
1586
  }
1634
1587
  ;
1635
1588
 
1589
+ mrhs_arg : mrhs
1590
+ | arg_value
1591
+ ;
1592
+
1636
1593
  mrhs : args ',' arg_value
1637
1594
  {
1638
1595
  NODE *n1;
@@ -1663,6 +1620,8 @@ primary : literal
1663
1620
  | regexp
1664
1621
  | words
1665
1622
  | qwords
1623
+ | symbols
1624
+ | qsymbols
1666
1625
  | var_ref
1667
1626
  | backref
1668
1627
  | tFID
@@ -1671,11 +1630,14 @@ primary : literal
1671
1630
  }
1672
1631
  | k_begin
1673
1632
  {
1633
+ $<val>1 = cmdarg_stack;
1634
+ cmdarg_stack = 0;
1674
1635
  $<num>$ = sourceline;
1675
1636
  }
1676
1637
  bodystmt
1677
1638
  k_end
1678
1639
  {
1640
+ cmdarg_stack = $<val>1;
1679
1641
  if($3 == NULL) {
1680
1642
  $$ = NEW_NIL();
1681
1643
  } else {
@@ -1686,9 +1648,12 @@ primary : literal
1686
1648
  }
1687
1649
  nd_set_line($$, $<num>2);
1688
1650
  }
1651
+ | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen
1652
+ {
1653
+ $$ = 0;
1654
+ }
1689
1655
  | tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} rparen
1690
1656
  {
1691
- rb_warning("(...) interpreted as grouped expression");
1692
1657
  $$ = $2;
1693
1658
  }
1694
1659
  | tLPAREN compstmt ')'
@@ -1744,9 +1709,9 @@ primary : literal
1744
1709
  {
1745
1710
  $$ = call_uni_op(cond(NEW_NIL()), '!');
1746
1711
  }
1747
- | operation brace_block
1712
+ | fcall brace_block
1748
1713
  {
1749
- $2->nd_iter = NEW_FCALL($1, 0);
1714
+ $2->nd_iter = $1;
1750
1715
  $$ = $2;
1751
1716
  fixpos($2->nd_iter, $2);
1752
1717
  }
@@ -2095,63 +2060,91 @@ f_margs : f_marg_list
2095
2060
  }
2096
2061
  ;
2097
2062
 
2098
- block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
2063
+ block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
2064
+ {
2065
+ $$ = new_args_tail($1, $3, $4);
2066
+ }
2067
+ | f_block_kwarg opt_f_block_arg
2068
+ {
2069
+ $$ = new_args_tail($1, 0, $2);
2070
+ }
2071
+ | f_kwrest opt_f_block_arg
2072
+ {
2073
+ $$ = new_args_tail(0, $1, $2);
2074
+ }
2075
+ | f_block_arg
2076
+ {
2077
+ $$ = new_args_tail(0, 0, $1);
2078
+ }
2079
+ ;
2080
+
2081
+ opt_block_args_tail : ',' block_args_tail
2082
+ {
2083
+ $$ = $2;
2084
+ }
2085
+ | /* none */
2086
+ {
2087
+ $$ = new_args_tail(0, 0, 0);
2088
+ }
2089
+ ;
2090
+
2091
+ block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
2099
2092
  {
2100
2093
  $$ = new_args($1, $3, $5, 0, $6);
2101
2094
  }
2102
- | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
2095
+ | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
2103
2096
  {
2104
2097
  $$ = new_args($1, $3, $5, $7, $8);
2105
2098
  }
2106
- | f_arg ',' f_block_optarg opt_f_block_arg
2099
+ | f_arg ',' f_block_optarg opt_block_args_tail
2107
2100
  {
2108
2101
  $$ = new_args($1, $3, 0, 0, $4);
2109
2102
  }
2110
- | f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg
2103
+ | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
2111
2104
  {
2112
2105
  $$ = new_args($1, $3, 0, $5, $6);
2113
2106
  }
2114
- | f_arg ',' f_rest_arg opt_f_block_arg
2107
+ | f_arg ',' f_rest_arg opt_block_args_tail
2115
2108
  {
2116
2109
  $$ = new_args($1, 0, $3, 0, $4);
2117
2110
  }
2118
2111
  | f_arg ','
2119
2112
  {
2120
- $$ = new_args($1, 0, 1, 0, 0);
2113
+ $$ = new_args($1, 0, 1, 0, new_args_tail(0, 0, 0));
2121
2114
  }
2122
- | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
2115
+ | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
2123
2116
  {
2124
2117
  $$ = new_args($1, 0, $3, $5, $6);
2125
2118
  }
2126
- | f_arg opt_f_block_arg
2119
+ | f_arg opt_block_args_tail
2127
2120
  {
2128
2121
  $$ = new_args($1, 0, 0, 0, $2);
2129
2122
  }
2130
- | f_block_optarg ',' f_rest_arg opt_f_block_arg
2123
+ | f_block_optarg ',' f_rest_arg opt_block_args_tail
2131
2124
  {
2132
2125
  $$ = new_args(0, $1, $3, 0, $4);
2133
2126
  }
2134
- | f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
2127
+ | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
2135
2128
  {
2136
2129
  $$ = new_args(0, $1, $3, $5, $6);
2137
2130
  }
2138
- | f_block_optarg opt_f_block_arg
2131
+ | f_block_optarg opt_block_args_tail
2139
2132
  {
2140
2133
  $$ = new_args(0, $1, 0, 0, $2);
2141
2134
  }
2142
- | f_block_optarg ',' f_arg opt_f_block_arg
2135
+ | f_block_optarg ',' f_arg opt_block_args_tail
2143
2136
  {
2144
2137
  $$ = new_args(0, $1, 0, $3, $4);
2145
2138
  }
2146
- | f_rest_arg opt_f_block_arg
2139
+ | f_rest_arg opt_block_args_tail
2147
2140
  {
2148
2141
  $$ = new_args(0, 0, $1, 0, $2);
2149
2142
  }
2150
- | f_rest_arg ',' f_arg opt_f_block_arg
2143
+ | f_rest_arg ',' f_arg opt_block_args_tail
2151
2144
  {
2152
2145
  $$ = new_args(0, 0, $1, $3, $4);
2153
2146
  }
2154
- | f_block_arg
2147
+ | block_args_tail
2155
2148
  {
2156
2149
  $$ = new_args(0, 0, 0, 0, $1);
2157
2150
  }
@@ -2166,7 +2159,8 @@ opt_block_param : none
2166
2159
 
2167
2160
  block_param_def : '|' opt_bv_decl '|'
2168
2161
  {
2169
- $$ = $2 ? NEW_ARGS_AUX(0,$2) : 0;
2162
+ // This is deliberately different than MRI.
2163
+ $$ = $2 ? NEW_ARGS_AUX(0, $2) : 0;
2170
2164
  }
2171
2165
  | tOROP
2172
2166
  {
@@ -2174,30 +2168,30 @@ block_param_def : '|' opt_bv_decl '|'
2174
2168
  }
2175
2169
  | '|' block_param opt_bv_decl '|'
2176
2170
  {
2177
- if($3) {
2178
- $$ = NEW_ARGS_AUX($2, $3);
2179
- } else {
2180
- $$ = $2;
2181
- }
2171
+ // This is deliberately different than MRI.
2172
+ $$ = $3 ? NEW_ARGS_AUX($2, $3) : $2;
2182
2173
  }
2183
2174
  ;
2184
2175
 
2185
- opt_bv_decl : none
2176
+ opt_bv_decl : opt_nl
2186
2177
  {
2187
2178
  $$ = 0;
2188
2179
  }
2189
- | ';' bv_decls
2180
+ | opt_nl ';' bv_decls
2190
2181
  {
2191
- $$ = $2;
2182
+ // This is deliberately different than MRI.
2183
+ $$ = $3;
2192
2184
  }
2193
2185
  ;
2194
2186
 
2195
2187
  bv_decls : bvar
2196
2188
  {
2189
+ // This is deliberately different than MRI.
2197
2190
  $$ = NEW_LIST($1);
2198
2191
  }
2199
2192
  | bv_decls ',' bvar
2200
2193
  {
2194
+ // This is deliberately different than MRI.
2201
2195
  $$ = list_append($1, $3);
2202
2196
  }
2203
2197
  ;
@@ -2205,6 +2199,7 @@ bv_decls : bvar
2205
2199
  bvar : tIDENTIFIER
2206
2200
  {
2207
2201
  new_bv(get_id($1));
2202
+ // This is deliberately different than MRI.
2208
2203
  $$ = NEW_LIT(ID2SYM(get_id($1)));
2209
2204
  }
2210
2205
  | f_bad_arg
@@ -2221,22 +2216,25 @@ lambda : {
2221
2216
  lpar_beg = ++paren_nest;
2222
2217
  }
2223
2218
  f_larglist
2219
+ {
2220
+ $<num>$ = sourceline;
2221
+ }
2224
2222
  lambda_body
2225
2223
  {
2226
2224
  lpar_beg = $<num>2;
2227
- $$ = $3;
2228
- $$->nd_body = NEW_SCOPE($3->nd_head, $4);
2225
+ $$ = NEW_LAMBDA($3, $5);
2226
+ nd_set_line($$, $<num>4);
2229
2227
  bv_pop($<vars>1);
2230
2228
  }
2231
2229
  ;
2232
2230
 
2233
- f_larglist : '(' f_args opt_bv_decl rparen
2231
+ f_larglist : '(' f_args opt_bv_decl ')'
2234
2232
  {
2235
- $$ = NEW_LAMBDA($2);
2233
+ $$ = $2;
2236
2234
  }
2237
2235
  | f_args
2238
2236
  {
2239
- $$ = NEW_LAMBDA($1);
2237
+ $$ = $1;
2240
2238
  }
2241
2239
  ;
2242
2240
 
@@ -2276,44 +2274,71 @@ block_call : command do_block
2276
2274
  $$ = $2;
2277
2275
  fixpos($$, $1);
2278
2276
  }
2279
- | block_call '.' operation2 opt_paren_args
2277
+ | block_call dot_or_colon operation2 opt_paren_args
2280
2278
  {
2281
2279
  $$ = NEW_CALL($1, $3, $4);
2282
2280
  }
2283
- | block_call tCOLON2 operation2 opt_paren_args
2281
+ | block_call dot_or_colon operation2 opt_paren_args brace_block
2284
2282
  {
2285
- $$ = NEW_CALL($1, $3, $4);
2283
+ block_dup_check($4, $5);
2284
+ $5->nd_iter = NEW_CALL($1, $3, $4);
2285
+ $$ = $5;
2286
+ fixpos($$, $1);
2287
+ }
2288
+ | block_call dot_or_colon operation2 command_args do_block
2289
+ {
2290
+ block_dup_check($4, $5);
2291
+ $5->nd_iter = NEW_CALL($1, $3, $4);
2292
+ $$ = $5;
2293
+ fixpos($$, $1);
2286
2294
  }
2287
2295
  ;
2288
2296
 
2289
- method_call : operation paren_args
2297
+ method_call : fcall paren_args
2290
2298
  {
2291
- $$ = NEW_FCALL($1, $2);
2299
+ $$ = $1;
2300
+ $$->nd_args = $2;
2292
2301
  fixpos($$, $2);
2293
2302
  }
2294
- | primary_value '.' operation2 opt_paren_args
2303
+ | primary_value '.' operation2
2295
2304
  {
2296
- $$ = NEW_CALL($1, $3, $4);
2297
- fixpos($$, $1);
2305
+ $<num>$ = sourceline;
2298
2306
  }
2299
- | primary_value tCOLON2 operation2 paren_args
2307
+ opt_paren_args
2300
2308
  {
2301
- $$ = NEW_CALL($1, $3, $4);
2302
- fixpos($$, $1);
2309
+ $$ = NEW_CALL($1, $3, $5);
2310
+ nd_set_line($$, $<num>4);
2311
+ }
2312
+ | primary_value tCOLON2 operation2
2313
+ {
2314
+ $<num>$ = sourceline;
2315
+ }
2316
+ paren_args
2317
+ {
2318
+ $$ = NEW_CALL($1, $3, $5);
2319
+ nd_set_line($$, $<num>4);
2303
2320
  }
2304
2321
  | primary_value tCOLON2 operation3
2305
2322
  {
2306
2323
  $$ = NEW_CALL($1, $3, 0);
2307
2324
  }
2308
- | primary_value '.' paren_args
2325
+ | primary_value '.'
2309
2326
  {
2310
- $$ = NEW_CALL($1, parser_intern("call"), $3);
2311
- fixpos($$, $1);
2327
+ $<num>$ = sourceline;
2312
2328
  }
2313
- | primary_value tCOLON2 paren_args
2329
+ paren_args
2314
2330
  {
2315
- $$ = NEW_CALL($1, parser_intern("call"), $3);
2316
- fixpos($$, $1);
2331
+ $$ = NEW_CALL($1, parser_intern("call"), $4);
2332
+ nd_set_line($$, $<num>3);
2333
+ }
2334
+ | primary_value tCOLON2
2335
+ {
2336
+ $<num>$ = sourceline;
2337
+ }
2338
+ paren_args
2339
+ {
2340
+ $$ = NEW_CALL($1, parser_intern("call"), $4);
2341
+ nd_set_line($$, $<num>3);
2317
2342
  }
2318
2343
  | keyword_super paren_args
2319
2344
  {
@@ -2555,6 +2580,28 @@ word : string_content
2555
2580
  }
2556
2581
  ;
2557
2582
 
2583
+ symbols : tSYMBOLS_BEG ' ' tSTRING_END
2584
+ {
2585
+ $$ = NEW_ZARRAY();
2586
+ }
2587
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2588
+ {
2589
+ $$ = $2;
2590
+ }
2591
+ ;
2592
+
2593
+ symbol_list : /* none */
2594
+ {
2595
+ $$ = 0;
2596
+ }
2597
+ | symbol_list word ' '
2598
+ {
2599
+ $2 = evstr2dstr($2);
2600
+ nd_set_type($2, NODE_DSYM);
2601
+ $$ = list_append($1, $2);
2602
+ }
2603
+ ;
2604
+
2558
2605
  qwords : tQWORDS_BEG ' ' tSTRING_END
2559
2606
  {
2560
2607
  $$ = NEW_ZARRAY();
@@ -2565,6 +2612,16 @@ qwords : tQWORDS_BEG ' ' tSTRING_END
2565
2612
  }
2566
2613
  ;
2567
2614
 
2615
+ qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END
2616
+ {
2617
+ $$ = NEW_ZARRAY();
2618
+ }
2619
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2620
+ {
2621
+ $$ = $2;
2622
+ }
2623
+ ;
2624
+
2568
2625
  qword_list : /* none */
2569
2626
  {
2570
2627
  $$ = 0;
@@ -2575,6 +2632,20 @@ qword_list : /* none */
2575
2632
  }
2576
2633
  ;
2577
2634
 
2635
+ qsym_list : /* none */
2636
+ {
2637
+ $$ = 0;
2638
+ }
2639
+ | qsym_list tSTRING_CONTENT ' '
2640
+ {
2641
+ VALUE lit;
2642
+ lit = $2->nd_lit;
2643
+ $2->nd_lit = ID2SYM(parser_intern_str(lit));
2644
+ nd_set_type($2, NODE_LIT);
2645
+ $$ = list_append($1, $2);
2646
+ }
2647
+ ;
2648
+
2578
2649
  string_contents : /* none */
2579
2650
  {
2580
2651
  $$ = 0;
@@ -2646,14 +2717,19 @@ string_content : tSTRING_CONTENT
2646
2717
  lex_strterm = 0;
2647
2718
  lex_state = EXPR_BEG;
2648
2719
  }
2649
- compstmt '}'
2720
+ {
2721
+ $<num>$ = brace_nest;
2722
+ brace_nest = 0;
2723
+ }
2724
+ compstmt tSTRING_DEND
2650
2725
  {
2651
2726
  cond_stack = $<val>1;
2652
2727
  cmdarg_stack = $<val>2;
2653
2728
  lex_strterm = $<node>3;
2729
+ brace_nest = $<num>4;
2654
2730
 
2655
- if($4) $4->flags &= ~NODE_FL_NEWLINE;
2656
- $$ = new_evstr($4);
2731
+ if($5) $5->flags &= ~NODE_FL_NEWLINE;
2732
+ $$ = new_evstr($5);
2657
2733
  }
2658
2734
  ;
2659
2735
 
@@ -2679,6 +2755,7 @@ sym : fname
2679
2755
  dsym : tSYMBEG xstring_contents tSTRING_END
2680
2756
  {
2681
2757
  lex_state = EXPR_END;
2758
+ // TODO dsym_node($2);
2682
2759
  if(!($$ = $2)) {
2683
2760
  $$ = NEW_LIT(ID2SYM(parser_intern("")));
2684
2761
  } else {
@@ -2701,18 +2778,19 @@ dsym : tSYMBEG xstring_contents tSTRING_END
2701
2778
  }
2702
2779
  ;
2703
2780
 
2704
- numeric : tINTEGER
2705
- | tFLOAT
2706
- | tUMINUS_NUM tINTEGER %prec tLOWEST
2707
- {
2708
- $$ = negate_lit($2);
2709
- }
2710
- | tUMINUS_NUM tFLOAT %prec tLOWEST
2781
+ numeric : simple_numeric
2782
+ | tUMINUS_NUM simple_numeric %prec tLOWEST
2711
2783
  {
2712
2784
  $$ = negate_lit($2);
2713
2785
  }
2714
2786
  ;
2715
2787
 
2788
+ simple_numeric : tINTEGER
2789
+ | tFLOAT
2790
+ | tRATIONAL
2791
+ | tIMAGINARY
2792
+ ;
2793
+
2716
2794
  user_variable : tIDENTIFIER
2717
2795
  | tIVAR
2718
2796
  | tGVAR
@@ -2764,6 +2842,7 @@ superclass : term
2764
2842
  | '<'
2765
2843
  {
2766
2844
  lex_state = EXPR_BEG;
2845
+ command_start = TRUE;
2767
2846
  }
2768
2847
  expr_value term
2769
2848
  {
@@ -2790,65 +2869,94 @@ f_arglist : '(' f_args rparen
2790
2869
  }
2791
2870
  ;
2792
2871
 
2793
- f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
2872
+ args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
2873
+ {
2874
+ $$ = new_args_tail($1, $3, $4);
2875
+ }
2876
+ | f_kwarg opt_f_block_arg
2877
+ {
2878
+ $$ = new_args_tail($1, 0, $2);
2879
+ }
2880
+ | f_kwrest opt_f_block_arg
2881
+ {
2882
+ $$ = new_args_tail(0, $1, $2);
2883
+ }
2884
+ | f_block_arg
2885
+ {
2886
+ $$ = new_args_tail(0, 0, $1);
2887
+ }
2888
+ ;
2889
+
2890
+ opt_args_tail : ',' args_tail
2891
+ {
2892
+ $$ = $2;
2893
+ }
2894
+ | /* none */
2895
+ {
2896
+ $$ = new_args_tail(0, 0, 0);
2897
+ }
2898
+ ;
2899
+
2900
+ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
2794
2901
  {
2795
2902
  $$ = new_args($1, $3, $5, 0, $6);
2796
2903
  }
2797
- | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
2904
+ | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
2798
2905
  {
2799
2906
  $$ = new_args($1, $3, $5, $7, $8);
2800
2907
  }
2801
- | f_arg ',' f_optarg opt_f_block_arg
2908
+ | f_arg ',' f_optarg opt_args_tail
2802
2909
  {
2803
2910
  $$ = new_args($1, $3, 0, 0, $4);
2804
2911
  }
2805
- | f_arg ',' f_optarg ',' f_arg opt_f_block_arg
2912
+ | f_arg ',' f_optarg ',' f_arg opt_args_tail
2806
2913
  {
2807
2914
  $$ = new_args($1, $3, 0, $5, $6);
2808
2915
  }
2809
- | f_arg ',' f_rest_arg opt_f_block_arg
2916
+ | f_arg ',' f_rest_arg opt_args_tail
2810
2917
  {
2811
2918
  $$ = new_args($1, 0, $3, 0, $4);
2812
2919
  }
2813
- | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
2920
+ | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
2814
2921
  {
2815
2922
  $$ = new_args($1, 0, $3, $5, $6);
2816
2923
  }
2817
- | f_arg opt_f_block_arg
2924
+ | f_arg opt_args_tail
2818
2925
  {
2819
2926
  $$ = new_args($1, 0, 0, 0, $2);
2820
2927
  }
2821
- | f_optarg ',' f_rest_arg opt_f_block_arg
2928
+ | f_optarg ',' f_rest_arg opt_args_tail
2822
2929
  {
2823
2930
  $$ = new_args(0, $1, $3, 0, $4);
2824
2931
  }
2825
- | f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
2932
+ | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
2826
2933
  {
2827
2934
  $$ = new_args(0, $1, $3, $5, $6);
2828
2935
  }
2829
- | f_optarg opt_f_block_arg
2936
+ | f_optarg opt_args_tail
2830
2937
  {
2831
2938
  $$ = new_args(0, $1, 0, 0, $2);
2832
2939
  }
2833
- | f_optarg ',' f_arg opt_f_block_arg
2940
+ | f_optarg ',' f_arg opt_args_tail
2834
2941
  {
2835
2942
  $$ = new_args(0, $1, 0, $3, $4);
2836
2943
  }
2837
- | f_rest_arg opt_f_block_arg
2944
+ | f_rest_arg opt_args_tail
2838
2945
  {
2839
2946
  $$ = new_args(0, 0, $1, 0, $2);
2840
2947
  }
2841
- | f_rest_arg ',' f_arg opt_f_block_arg
2948
+ | f_rest_arg ',' f_arg opt_args_tail
2842
2949
  {
2843
2950
  $$ = new_args(0, 0, $1, $3, $4);
2844
2951
  }
2845
- | f_block_arg
2952
+ | args_tail
2846
2953
  {
2847
2954
  $$ = new_args(0, 0, 0, 0, $1);
2848
2955
  }
2849
2956
  | /* none */
2850
2957
  {
2851
- $$ = new_args(0, 0, 0, 0, 0);
2958
+ $$ = new_args_tail(0, 0, 0);
2959
+ $$ = new_args(0, 0, 0, 0, $$);
2852
2960
  }
2853
2961
  ;
2854
2962
 
@@ -2887,36 +2995,112 @@ f_arg_item : f_norm_arg
2887
2995
  arg_var(get_id($1));
2888
2996
  $$ = NEW_ARGS_AUX($1, 1);
2889
2997
  }
2890
- | tLPAREN f_margs rparen
2998
+ | tLPAREN f_margs rparen
2999
+ {
3000
+ ID tid = internal_id();
3001
+ arg_var(tid);
3002
+ $2->nd_value = NEW_LVAR(tid);
3003
+ $$ = NEW_ARGS_AUX(tid, 1);
3004
+ $$->nd_next = $2;
3005
+ }
3006
+ ;
3007
+
3008
+ f_arg : f_arg_item
3009
+ | f_arg ',' f_arg_item
3010
+ {
3011
+ $$ = $1;
3012
+ $$->nd_plen++;
3013
+ $$->nd_next = block_append($$->nd_next, $3->nd_next);
3014
+ }
3015
+ ;
3016
+
3017
+ f_label : tLABEL
3018
+ {
3019
+ arg_var(formal_argument(get_id($1)));
3020
+ $$ = $1;
3021
+ }
3022
+ ;
3023
+
3024
+ f_kw : f_label arg_value
3025
+ {
3026
+ $$ = assignable($1, $2);
3027
+ $$ = NEW_KW_ARG(0, $$);
3028
+ }
3029
+ | f_label
3030
+ {
3031
+ $$ = assignable($1, NEW_REQ_KW);
3032
+ $$ = NEW_KW_ARG(0, $$);
3033
+ }
3034
+ ;
3035
+
3036
+ f_block_kw : f_label primary_value
3037
+ {
3038
+ $$ = assignable($1, $2);
3039
+ $$ = NEW_KW_ARG(0, $$);
3040
+ }
3041
+ | f_label
3042
+ {
3043
+ $$ = assignable($1, NEW_REQ_KW);
3044
+ $$ = NEW_KW_ARG(0, $$);
3045
+ }
3046
+ ;
3047
+
3048
+ f_block_kwarg : f_block_kw
3049
+ {
3050
+ $$ = $1;
3051
+ }
3052
+ | f_block_kwarg ',' f_block_kw
3053
+ {
3054
+ NODE *kws = $1;
3055
+ while (kws->nd_next) {
3056
+ kws = kws->nd_next;
3057
+ }
3058
+ kws->nd_next = $3;
3059
+ $$ = $1;
3060
+ }
3061
+ ;
3062
+
3063
+ f_kwarg : f_kw
3064
+ {
3065
+ $$ = $1;
3066
+ }
3067
+ | f_kwarg ',' f_kw
2891
3068
  {
2892
- ID tid = internal_id();
2893
- arg_var(tid);
2894
- $2->nd_value = NEW_LVAR(tid);
2895
- $$ = NEW_ARGS_AUX(tid, 1);
2896
- $$->nd_next = $2;
3069
+ NODE *kws = $1;
3070
+ while (kws->nd_next) {
3071
+ kws = kws->nd_next;
3072
+ }
3073
+ kws->nd_next = $3;
3074
+ $$ = $1;
2897
3075
  }
2898
3076
  ;
2899
3077
 
2900
- f_arg : f_arg_item
2901
- | f_arg ',' f_arg_item
3078
+ kwrest_mark : tPOW
3079
+ | tDSTAR
3080
+ ;
3081
+
3082
+ f_kwrest : kwrest_mark tIDENTIFIER
2902
3083
  {
2903
- $$ = $1;
2904
- $$->nd_plen++;
2905
- $$->nd_next = block_append($$->nd_next, $3->nd_next);
3084
+ shadowing_lvar(get_id($2));
3085
+ $$ = $2;
3086
+ }
3087
+ | kwrest_mark
3088
+ {
3089
+ $$ = internal_id();
2906
3090
  }
2907
3091
  ;
2908
3092
 
2909
- f_opt : tIDENTIFIER '=' arg_value
3093
+ f_opt : f_norm_arg '=' arg_value
2910
3094
  {
2911
- arg_var(formal_argument(get_id($1)));
3095
+ arg_var(get_id($1));
2912
3096
  $$ = assignable($1, $3);
2913
3097
  $$ = NEW_OPT_ARG(0, $$);
2914
3098
  }
2915
3099
  ;
2916
3100
 
2917
- f_block_opt : tIDENTIFIER '=' primary_value
3101
+ f_block_opt : f_norm_arg '=' primary_value
2918
3102
  {
2919
- arg_var(formal_argument(get_id($1)));
3103
+ arg_var(get_id($1));
2920
3104
  $$ = assignable($1, $3);
2921
3105
  $$ = NEW_OPT_ARG(0, $$);
2922
3106
  }
@@ -3048,6 +3232,10 @@ assoc : arg_value tASSOC arg_value
3048
3232
  {
3049
3233
  $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
3050
3234
  }
3235
+ | tDSTAR arg_value
3236
+ {
3237
+ $$ = list_append(NEW_LIST(0), $2);
3238
+ }
3051
3239
  ;
3052
3240
 
3053
3241
  operation : tIDENTIFIER
@@ -3114,21 +3302,24 @@ static int parser_here_document(rb_parser_state*, NODE*);
3114
3302
 
3115
3303
 
3116
3304
  #define nextc() parser_nextc(parser_state)
3117
- #define pushback(c) parser_pushback(parser_state, c)
3305
+ #define pushback(c) parser_pushback(parser_state, (c))
3118
3306
  #define newtok() parser_newtok(parser_state)
3119
- #define tokspace(n) parser_tokspace(parser_state, n)
3120
- #define tokadd(c) parser_tokadd(parser_state, c)
3121
- #define tok_hex(numlen) parser_tok_hex(parser_state, numlen)
3122
- #define read_escape(flags,e) parser_read_escape(parser_state, flags, e)
3123
- #define tokadd_escape(e) parser_tokadd_escape(parser_state, e)
3307
+ #define tokspace(n) parser_tokspace(parser_state, (n))
3308
+ #define tokadd(c) parser_tokadd(parser_state, (c))
3309
+ #define tok_hex(numlen) parser_tok_hex(parser_state, (numlen))
3310
+ #define read_escape(flags,e) parser_read_escape(parser_state, (flags), (e))
3311
+ #define tokadd_escape(e) parser_tokadd_escape(parser_state, (e))
3124
3312
  #define regx_options() parser_regx_options(parser_state)
3125
- #define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser_state,f,t,p,n,e)
3126
- #define parse_string(n) parser_parse_string(parser_state,n)
3127
- #define tokaddmbc(c, enc) parser_tokaddmbc(parser_state, c, enc)
3128
- #define here_document(n) parser_here_document(parser_state,n)
3313
+ #define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser_state, (f), (t), (p), (n), (e))
3314
+ #define parse_string(n) parser_parse_string(parser_state, (n))
3315
+ #define tokaddmbc(c, enc) parser_tokaddmbc(parser_state, (c), (enc))
3316
+ #define here_document(n) parser_here_document(parser_state, (n))
3129
3317
  #define heredoc_identifier() parser_heredoc_identifier(parser_state)
3130
- #define heredoc_restore(n) parser_heredoc_restore(parser_state,n)
3131
- #define whole_match_p(e,l,i) parser_whole_match_p(parser_state,e,l,i)
3318
+ #define heredoc_restore(n) parser_heredoc_restore(parser_state, (n))
3319
+ #define whole_match_p(e,l,i) parser_whole_match_p(parser_state, (e), (l), (i))
3320
+ #define number_literal_suffix(f) parser_number_literal_suffix(parser_state, (f))
3321
+ #define set_number_literal(v,t,f) parser_set_number_literal(parser_state, (v), (t), (f))
3322
+ #define set_integer_literal(v,f) parser_set_integer_literal(parser_state, (v), (f))
3132
3323
 
3133
3324
  #define set_yylval_str(x) yylval.node = NEW_STR(x)
3134
3325
  #define set_yylval_num(x) yylval.num = x
@@ -3137,6 +3328,8 @@ static int parser_here_document(rb_parser_state*, NODE*);
3137
3328
  #define set_yylval_literal(x) yylval.node = NEW_LIT(x)
3138
3329
  #define set_yylval_number(x) yylval.node = NEW_NUMBER(x)
3139
3330
  #define set_yylval_float(x) yylval.node = NEW_FLOAT(x)
3331
+ #define set_yylval_rational(x) yylval.node = NEW_RATIONAL(x)
3332
+ #define set_yylval_imaginary(x) yylval.node = NEW_IMAGINARY(x)
3140
3333
  #define set_yylval_node(x) yylval.node = x
3141
3334
  #define yylval_id() yylval.id
3142
3335
 
@@ -3193,7 +3386,6 @@ yycompile(rb_parser_state* parser_state, char *f, int line)
3193
3386
  compile_for_eval = 0;
3194
3387
  cond_stack = 0;
3195
3388
  cmdarg_stack = 0;
3196
- command_start = TRUE;
3197
3389
  class_nest = 0;
3198
3390
  in_single = 0;
3199
3391
  in_def = 0;
@@ -3440,8 +3632,6 @@ parser_pushback(rb_parser_state* parser_state, int c)
3440
3632
  lex_p--;
3441
3633
  }
3442
3634
 
3443
- #define pushback(c) parser_pushback(parser_state, c)
3444
-
3445
3635
  /* Indicates if we're currently at the beginning of a line. */
3446
3636
  #define was_bol() (lex_p == lex_pbeg + 1)
3447
3637
 
@@ -3457,6 +3647,7 @@ static char*
3457
3647
  parser_newtok(rb_parser_state* parser_state)
3458
3648
  {
3459
3649
  tokidx = 0;
3650
+ tokline = sourceline;
3460
3651
  if(!tokenbuf) {
3461
3652
  toksiz = 60;
3462
3653
  tokenbuf = ALLOC_N(char, 60);
@@ -3849,7 +4040,7 @@ parser_tokadd_string(rb_parser_state *parser_state,
3849
4040
  }
3850
4041
 
3851
4042
  #define mixed_escape(beg, enc1, enc2) do { \
3852
- char *pos = lex_p; \
4043
+ const char *pos = lex_p; \
3853
4044
  lex_p = beg; \
3854
4045
  mixed_error(enc1, enc2); \
3855
4046
  lex_p = pos; \
@@ -3871,7 +4062,7 @@ parser_tokadd_string(rb_parser_state *parser_state,
3871
4062
  break;
3872
4063
  }
3873
4064
  } else if(c == '\\') {
3874
- char *beg = lex_p - 1;
4065
+ const char *beg = lex_p - 1;
3875
4066
  c = nextc();
3876
4067
  switch(c) {
3877
4068
  case '\n':
@@ -3950,6 +4141,65 @@ parser_tokadd_string(rb_parser_state *parser_state,
3950
4141
  node_newnode(NODE_STRTERM, (VALUE)(func), \
3951
4142
  (VALUE)((term) | ((paren) << (CHAR_BIT * 2))), 0)
3952
4143
  #define pslval ((YYSTYPE *)lval)
4144
+
4145
+ #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
4146
+ #define SPECIAL_PUNCT(idx) ( \
4147
+ BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
4148
+ BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
4149
+ BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
4150
+ BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
4151
+ BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
4152
+ BIT('0', idx))
4153
+ const unsigned int ruby_global_name_punct_bits[] = {
4154
+ SPECIAL_PUNCT(0),
4155
+ SPECIAL_PUNCT(1),
4156
+ SPECIAL_PUNCT(2),
4157
+ };
4158
+ #undef BIT
4159
+ #undef SPECIAL_PUNCT
4160
+
4161
+ static inline int
4162
+ is_global_name_punct(const int c)
4163
+ {
4164
+ if(c <= 0x20 || 0x7e < c) return 0;
4165
+ return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
4166
+ }
4167
+
4168
+ static int
4169
+ parser_peek_variable_name(rb_parser_state* parser_state)
4170
+ {
4171
+ int c;
4172
+ const char *p = lex_p;
4173
+
4174
+ if(p + 1 >= lex_pend) return 0;
4175
+ c = *p++;
4176
+ switch(c) {
4177
+ case '$':
4178
+ if((c = *p) == '-') {
4179
+ if (++p >= lex_pend) return 0;
4180
+ c = *p;
4181
+ } else if(is_global_name_punct(c) || ISDIGIT(c)) {
4182
+ return tSTRING_DVAR;
4183
+ }
4184
+ break;
4185
+ case '@':
4186
+ if((c = *p) == '@') {
4187
+ if(++p >= lex_pend) return 0;
4188
+ c = *p;
4189
+ }
4190
+ break;
4191
+ case '{':
4192
+ lex_p = p;
4193
+ command_start = TRUE;
4194
+ return tSTRING_DBEG;
4195
+ default:
4196
+ return 0;
4197
+ }
4198
+ if(!ISASCII(c) || c == '_' || ISALPHA(c)) return tSTRING_DVAR;
4199
+
4200
+ return 0;
4201
+ }
4202
+
3953
4203
  static int
3954
4204
  parser_parse_string(rb_parser_state* parser_state, NODE *quote)
3955
4205
  {
@@ -3982,15 +4232,10 @@ parser_parse_string(rb_parser_state* parser_state, NODE *quote)
3982
4232
  }
3983
4233
  newtok();
3984
4234
  if((func & STR_FUNC_EXPAND) && c == '#') {
3985
- switch(c = nextc()) {
3986
- case '$':
3987
- case '@':
3988
- pushback(c);
3989
- return tSTRING_DVAR;
3990
- case '{':
3991
- return tSTRING_DBEG;
3992
- }
4235
+ int t = parser_peek_variable_name(parser_state);
4236
+ if(t) return t;
3993
4237
  tokadd('#');
4238
+ c = nextc();
3994
4239
  }
3995
4240
  pushback(c);
3996
4241
  if(tokadd_string(func, term, paren, &quote->nd_nest, &enc) == -1) {
@@ -4103,6 +4348,7 @@ parser_heredoc_restore(rb_parser_state* parser_state, NODE *here)
4103
4348
  {
4104
4349
  VALUE line;
4105
4350
 
4351
+ lex_strterm = 0;
4106
4352
  line = here->nd_orig;
4107
4353
  lex_lastline = line;
4108
4354
  lex_pbeg = RSTRING_PTR(line);
@@ -4115,16 +4361,93 @@ parser_heredoc_restore(rb_parser_state* parser_state, NODE *here)
4115
4361
  static int
4116
4362
  parser_whole_match_p(rb_parser_state* parser_state, const char *eos, ssize_t len, int indent)
4117
4363
  {
4118
- char *p = lex_pbeg;
4364
+ const char *p = lex_pbeg;
4119
4365
  ssize_t n;
4120
4366
 
4121
4367
  if(indent) {
4122
4368
  while(*p && ISSPACE(*p)) p++;
4123
4369
  }
4124
4370
  n = lex_pend - (p + len);
4125
- if(n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
4126
- if(strncmp(eos, p, len) == 0) return TRUE;
4127
- return FALSE;
4371
+ if(n < 0) return FALSE;
4372
+ if(n > 0 && p[len] != '\n') {
4373
+ if(p[len] != '\r') return FALSE;
4374
+ if(n <= 1 || p[len+1] != '\n') return FALSE;
4375
+ }
4376
+ return strncmp(eos, p, len) == 0;
4377
+ }
4378
+
4379
+ #define NUM_SUFFIX_R (1<<0)
4380
+ #define NUM_SUFFIX_I (1<<1)
4381
+ #define NUM_SUFFIX_ALL 3
4382
+
4383
+ static int
4384
+ parser_number_literal_suffix(rb_parser_state* parser_state, int mask)
4385
+ {
4386
+ int c, result = 0;
4387
+ const char *lastp = lex_p;
4388
+
4389
+ while((c = nextc()) != -1) {
4390
+ if((mask & NUM_SUFFIX_I) && c == 'i') {
4391
+ result |= (mask & NUM_SUFFIX_I);
4392
+ mask &= ~NUM_SUFFIX_I;
4393
+ /* r after i, rational of complex is disallowed */
4394
+ mask &= ~NUM_SUFFIX_R;
4395
+ continue;
4396
+ }
4397
+ if((mask & NUM_SUFFIX_R) && c == 'r') {
4398
+ result |= (mask & NUM_SUFFIX_R);
4399
+ mask &= ~NUM_SUFFIX_R;
4400
+ continue;
4401
+ }
4402
+ if(!ISASCII(c) || ISALPHA(c) || c == '_') {
4403
+ lex_p = lastp;
4404
+ return 0;
4405
+ }
4406
+ pushback(c);
4407
+ break;
4408
+ }
4409
+
4410
+ return result;
4411
+ }
4412
+
4413
+ static int
4414
+ parser_set_number_literal(rb_parser_state* parser_state, VALUE v, int type, int suffix)
4415
+ {
4416
+ if(suffix & NUM_SUFFIX_I) {
4417
+ v = rb_funcall(rb_cObject, rb_intern("Complex"), 2, INT2FIX(0), v);
4418
+ type = tIMAGINARY;
4419
+ }
4420
+
4421
+ switch(type) {
4422
+ case tFLOAT:
4423
+ set_yylval_float(v);
4424
+ break;
4425
+ case tINTEGER:
4426
+ set_yylval_number(v);
4427
+ break;
4428
+ case tRATIONAL:
4429
+ set_yylval_rational(v);
4430
+ break;
4431
+ case tIMAGINARY:
4432
+ set_yylval_imaginary(v);
4433
+ break;
4434
+ default:
4435
+ set_yylval_literal(v);
4436
+ break;
4437
+ }
4438
+
4439
+ return type;
4440
+ }
4441
+
4442
+ static int
4443
+ parser_set_integer_literal(rb_parser_state* parser_state, VALUE v, int suffix)
4444
+ {
4445
+ int type = tINTEGER;
4446
+ if (suffix & NUM_SUFFIX_R) {
4447
+ v = rb_funcall(rb_cObject, rb_intern("Rational"), 1, v);
4448
+ type = tRATIONAL;
4449
+ }
4450
+ return set_number_literal(v, type, suffix);
4128
4451
  }
4129
4452
 
4130
4453
  /* Called when the lexer knows it's inside a heredoc. This function
@@ -4135,7 +4458,7 @@ static int
4135
4458
  parser_here_document(rb_parser_state* parser_state, NODE *here)
4136
4459
  {
4137
4460
  int c, func, indent = 0;
4138
- char *eos, *p, *pend;
4461
+ const char *eos, *p, *pend;
4139
4462
  ssize_t len;
4140
4463
  VALUE str = 0;
4141
4464
  rb_encoding* enc = parser_state->enc;
@@ -4153,7 +4476,6 @@ parser_here_document(rb_parser_state* parser_state, NODE *here)
4153
4476
  rb_compile_error(parser_state, "can't find string \"%s\" anywhere before EOF", eos);
4154
4477
  restore:
4155
4478
  heredoc_restore(lex_strterm);
4156
- lex_strterm = 0;
4157
4479
  return 0;
4158
4480
  }
4159
4481
  /* Gr. not yet sure what was_bol() means other than it seems like
@@ -4196,15 +4518,10 @@ parser_here_document(rb_parser_state* parser_state, NODE *here)
4196
4518
  } else {
4197
4519
  newtok();
4198
4520
  if(c == '#') {
4199
- switch(c = nextc()) {
4200
- case '$':
4201
- case '@':
4202
- pushback(c);
4203
- return tSTRING_DVAR;
4204
- case '{':
4205
- return tSTRING_DBEG;
4206
- }
4521
+ int t = parser_peek_variable_name(parser_state);
4522
+ if(t) return t;
4207
4523
  tokadd('#');
4524
+ c = nextc();
4208
4525
  }
4209
4526
 
4210
4527
  /* Loop while we haven't found a the heredoc ident. */
@@ -4245,8 +4562,6 @@ arg_ambiguous()
4245
4562
  return 1;
4246
4563
  }
4247
4564
 
4248
- #define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG)
4249
-
4250
4565
  static ID
4251
4566
  parser_formal_argument(rb_parser_state* parser_state, ID lhs)
4252
4567
  {
@@ -4535,33 +4850,28 @@ parser_prepare(rb_parser_state* parser_state)
4535
4850
  parser_state->enc = parser_enc_get(lex_lastline);
4536
4851
  }
4537
4852
 
4538
- #define IS_ARG() (lex_state == EXPR_ARG \
4539
- || lex_state == EXPR_CMDARG)
4540
- #define IS_END() (lex_state == EXPR_END \
4541
- || lex_state == EXPR_ENDARG \
4542
- || lex_state == EXPR_ENDFN)
4543
- #define IS_BEG() (lex_state == EXPR_BEG \
4544
- || lex_state == EXPR_MID \
4545
- || lex_state == EXPR_VALUE \
4546
- || lex_state == EXPR_CLASS)
4547
- #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
4548
- #define IS_LABEL_POSSIBLE() ((lex_state == EXPR_BEG && !cmd_state) || IS_ARG())
4549
- #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
4853
+ #define IS_ARG() lex_state_p(EXPR_ARG_ANY)
4854
+ #define IS_END() lex_state_p(EXPR_END_ANY)
4855
+ #define IS_BEG() lex_state_p(EXPR_BEG_ANY)
4856
+ #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
4857
+ #define IS_LABEL_POSSIBLE() ((lex_state_p(EXPR_BEG | EXPR_ENDFN) && !cmd_state) \
4858
+ || IS_ARG())
4859
+ #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
4860
+ #define IS_AFTER_OPERATOR() lex_state_p(EXPR_FNAME | EXPR_DOT)
4550
4861
 
4551
4862
  #define ambiguous_operator(op, syn) ( \
4552
- rb_warning0("`"op"' after local variable is interpreted as binary operator"), \
4553
- rb_warning0("even though it seems like "syn""))
4554
- #define warn_balanced(op, syn) \
4555
- (last_state != EXPR_CLASS && last_state != EXPR_DOT && \
4556
- last_state != EXPR_FNAME && last_state != EXPR_ENDFN && \
4557
- last_state != EXPR_ENDARG && \
4558
- space_seen && !ISSPACE(c) && \
4559
- (ambiguous_operator(op, syn), 0))
4863
+ rb_warning0("`" op "' after local variable is interpreted as binary operator"), \
4864
+ rb_warning0("even though it seems like " syn ""))
4865
+ #define warn_balanced(op, syn) ((void) \
4866
+ (!lex_state_of_p(last_state, \
4867
+ EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN|EXPR_ENDARG) && \
4868
+ space_seen && !ISSPACE(c) && \
4869
+ (ambiguous_operator(op, syn), 0)))
4560
4870
 
4561
4871
  static int
4562
4872
  parser_yylex(rb_parser_state *parser_state)
4563
4873
  {
4564
- register int c;
4874
+ int c;
4565
4875
  int space_seen = 0;
4566
4876
  int cmd_state;
4567
4877
  enum lex_state_e last_state;
@@ -4614,15 +4924,8 @@ retry:
4614
4924
  lex_p = lex_pend;
4615
4925
  /* fall through */
4616
4926
  case '\n':
4617
- switch(lex_state) {
4618
- case EXPR_BEG:
4619
- case EXPR_FNAME:
4620
- case EXPR_DOT:
4621
- case EXPR_CLASS:
4622
- case EXPR_VALUE:
4927
+ if(lex_state_p(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
4623
4928
  goto retry;
4624
- default:
4625
- break;
4626
4929
  }
4627
4930
 
4628
4931
  while((c = nextc())) {
@@ -4660,7 +4963,15 @@ retry:
4660
4963
  return tOP_ASGN;
4661
4964
  }
4662
4965
  pushback(c);
4663
- c = tPOW;
4966
+ if (IS_SPCARG(c)) {
4967
+ rb_warning0("`**' interpreted as argument prefix");
4968
+ c = tDSTAR;
4969
+ } else if (IS_BEG()) {
4970
+ c = tDSTAR;
4971
+ } else {
4972
+ warn_balanced("**", "argument prefix");
4973
+ c = tPOW;
4974
+ }
4664
4975
  } else {
4665
4976
  if(c == '=') {
4666
4977
  set_yylval_id('*');
@@ -4678,17 +4989,12 @@ retry:
4678
4989
  c = '*';
4679
4990
  }
4680
4991
  }
4681
- switch(lex_state) {
4682
- case EXPR_FNAME: case EXPR_DOT:
4683
- lex_state = EXPR_ARG; break;
4684
- default:
4685
- lex_state = EXPR_BEG; break;
4686
- }
4992
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
4687
4993
  return c;
4688
4994
 
4689
4995
  case '!':
4690
4996
  c = nextc();
4691
- if(lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
4997
+ if(IS_AFTER_OPERATOR()) {
4692
4998
  lex_state = EXPR_ARG;
4693
4999
  if(c == '@') {
4694
5000
  return '!';
@@ -4727,12 +5033,7 @@ retry:
4727
5033
  }
4728
5034
  }
4729
5035
 
4730
- switch(lex_state) {
4731
- case EXPR_FNAME: case EXPR_DOT:
4732
- lex_state = EXPR_ARG; break;
4733
- default:
4734
- lex_state = EXPR_BEG; break;
4735
- }
5036
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
4736
5037
  if((c = nextc()) == '=') {
4737
5038
  if((c = nextc()) == '=') {
4738
5039
  return tEQQ;
@@ -4752,18 +5053,19 @@ retry:
4752
5053
  last_state = lex_state;
4753
5054
  c = nextc();
4754
5055
  if(c == '<' &&
4755
- lex_state != EXPR_DOT &&
4756
- lex_state != EXPR_CLASS &&
5056
+ !lex_state_p(EXPR_DOT | EXPR_CLASS) &&
4757
5057
  !IS_END() &&
4758
5058
  (!IS_ARG() || space_seen)) {
4759
5059
  int token = heredoc_identifier();
4760
5060
  if(token) return token;
4761
5061
  }
4762
- switch(lex_state) {
4763
- case EXPR_FNAME: case EXPR_DOT:
4764
- lex_state = EXPR_ARG; break;
4765
- default:
4766
- lex_state = EXPR_BEG; break;
5062
+ if(IS_AFTER_OPERATOR()) {
5063
+ lex_state = EXPR_ARG;
5064
+ } else {
5065
+ if(lex_state_p(EXPR_CLASS)) {
5066
+ command_start = TRUE;
5067
+ }
5068
+ lex_state = EXPR_BEG;
4767
5069
  }
4768
5070
  if(c == '=') {
4769
5071
  if((c = nextc()) == '>') {
@@ -4786,12 +5088,7 @@ retry:
4786
5088
  return '<';
4787
5089
 
4788
5090
  case '>':
4789
- switch(lex_state) {
4790
- case EXPR_FNAME: case EXPR_DOT:
4791
- lex_state = EXPR_ARG; break;
4792
- default:
4793
- lex_state = EXPR_BEG; break;
4794
- }
5091
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
4795
5092
  if((c = nextc()) == '=') {
4796
5093
  return tGEQ;
4797
5094
  }
@@ -4812,15 +5109,16 @@ retry:
4812
5109
  return tSTRING_BEG;
4813
5110
 
4814
5111
  case '`':
4815
- if(lex_state == EXPR_FNAME) {
5112
+ if(lex_state_p(EXPR_FNAME)) {
4816
5113
  lex_state = EXPR_ENDFN;
4817
5114
  return c;
4818
5115
  }
4819
- if(lex_state == EXPR_DOT) {
4820
- if(cmd_state)
5116
+ if(lex_state_p(EXPR_DOT)) {
5117
+ if(cmd_state) {
4821
5118
  lex_state = EXPR_CMDARG;
4822
- else
5119
+ } else {
4823
5120
  lex_state = EXPR_ARG;
5121
+ }
4824
5122
  return c;
4825
5123
  }
4826
5124
  lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
@@ -4929,13 +5227,7 @@ retry:
4929
5227
  warn_balanced("&", "argument prefix");
4930
5228
  c = '&';
4931
5229
  }
4932
- switch(lex_state) {
4933
- case EXPR_FNAME: case EXPR_DOT:
4934
- lex_state = EXPR_ARG;
4935
- break;
4936
- default:
4937
- lex_state = EXPR_BEG;
4938
- }
5230
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
4939
5231
  return c;
4940
5232
 
4941
5233
  case '|':
@@ -4954,17 +5246,13 @@ retry:
4954
5246
  lex_state = EXPR_BEG;
4955
5247
  return tOP_ASGN;
4956
5248
  }
4957
- if(lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
4958
- lex_state = EXPR_ARG;
4959
- } else {
4960
- lex_state = EXPR_BEG;
4961
- }
5249
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
4962
5250
  pushback(c);
4963
5251
  return '|';
4964
5252
 
4965
5253
  case '+':
4966
5254
  c = nextc();
4967
- if(lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
5255
+ if(IS_AFTER_OPERATOR()) {
4968
5256
  lex_state = EXPR_ARG;
4969
5257
  if(c == '@') {
4970
5258
  return tUPLUS;
@@ -4993,7 +5281,7 @@ retry:
4993
5281
 
4994
5282
  case '-':
4995
5283
  c = nextc();
4996
- if(lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
5284
+ if(IS_AFTER_OPERATOR()) {
4997
5285
  lex_state = EXPR_ARG;
4998
5286
  if(c == '@') {
4999
5287
  return tUMINUS;
@@ -5007,7 +5295,7 @@ retry:
5007
5295
  return tOP_ASGN;
5008
5296
  }
5009
5297
  if(c == '>') {
5010
- lex_state = EXPR_ARG;
5298
+ lex_state = EXPR_ENDFN;
5011
5299
  return tLAMBDA;
5012
5300
  }
5013
5301
  if(IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
@@ -5043,7 +5331,7 @@ retry:
5043
5331
  case '0': case '1': case '2': case '3': case '4':
5044
5332
  case '5': case '6': case '7': case '8': case '9':
5045
5333
  {
5046
- int is_float, seen_point, seen_e, nondigit;
5334
+ int is_float, seen_point, seen_e, nondigit, suffix;
5047
5335
 
5048
5336
  is_float = seen_point = seen_e = nondigit = 0;
5049
5337
  lex_state = EXPR_END;
@@ -5078,8 +5366,8 @@ retry:
5078
5366
  } else if(nondigit) {
5079
5367
  goto trailing_uc;
5080
5368
  }
5081
- set_yylval_number(rb_cstr_to_inum(tok(), 16, FALSE));
5082
- return tINTEGER;
5369
+ suffix = number_literal_suffix(NUM_SUFFIX_ALL);
5370
+ return set_integer_literal(rb_cstr_to_inum(tok(), 16, FALSE), suffix);
5083
5371
  }
5084
5372
 
5085
5373
  if(c == 'b' || c == 'B') {
@@ -5104,8 +5392,8 @@ retry:
5104
5392
  } else if(nondigit) {
5105
5393
  goto trailing_uc;
5106
5394
  }
5107
- set_yylval_number(rb_cstr_to_inum(tok(), 2, FALSE));
5108
- return tINTEGER;
5395
+ suffix = number_literal_suffix(NUM_SUFFIX_ALL);
5396
+ return set_integer_literal(rb_cstr_to_inum(tok(), 2, FALSE), suffix);
5109
5397
  }
5110
5398
 
5111
5399
  if(c == 'd' || c == 'D') {
@@ -5130,8 +5418,8 @@ retry:
5130
5418
  } else if(nondigit) {
5131
5419
  goto trailing_uc;
5132
5420
  }
5133
- set_yylval_number(rb_cstr_to_inum(tok(), 10, FALSE));
5134
- return tINTEGER;
5421
+ suffix = number_literal_suffix(NUM_SUFFIX_ALL);
5422
+ return set_integer_literal(rb_cstr_to_inum(tok(), 10, FALSE), suffix);
5135
5423
  }
5136
5424
 
5137
5425
  if(c == '_') {
@@ -5166,8 +5454,8 @@ retry:
5166
5454
  pushback(c);
5167
5455
  tokfix();
5168
5456
  if(nondigit) goto trailing_uc;
5169
- set_yylval_number(rb_cstr_to_inum(tok(), 8, FALSE));
5170
- return tINTEGER;
5457
+ suffix = number_literal_suffix(NUM_SUFFIX_ALL);
5458
+ return set_integer_literal(rb_cstr_to_inum(tok(), 8, FALSE), suffix);
5171
5459
  }
5172
5460
  if(nondigit) {
5173
5461
  pushback(c);
@@ -5182,8 +5470,8 @@ retry:
5182
5470
  tokadd('0');
5183
5471
  } else {
5184
5472
  pushback(c);
5185
- set_yylval_number(INT2FIX(0));
5186
- return tINTEGER;
5473
+ suffix = number_literal_suffix(NUM_SUFFIX_ALL);
5474
+ return set_integer_literal(INT2FIX(0), suffix);
5187
5475
  }
5188
5476
  }
5189
5477
 
@@ -5207,10 +5495,10 @@ retry:
5207
5495
  }
5208
5496
  c = c0;
5209
5497
  }
5498
+ seen_point = toklen();
5210
5499
  tokadd('.');
5211
5500
  tokadd(c);
5212
5501
  is_float++;
5213
- seen_point++;
5214
5502
  nondigit = 0;
5215
5503
  break;
5216
5504
 
@@ -5224,14 +5512,18 @@ retry:
5224
5512
  if(seen_e) {
5225
5513
  goto decode_num;
5226
5514
  }
5227
- tokadd(c);
5228
- seen_e++;
5229
- is_float++;
5230
5515
  nondigit = c;
5231
5516
  c = nextc();
5232
- if(c != '-' && c != '+') continue;
5517
+ if(c != '-' && c != '+' && !ISDIGIT(c)) {
5518
+ pushback(c);
5519
+ nondigit = 0;
5520
+ goto decode_num;
5521
+ }
5522
+ tokadd(nondigit);
5523
+ seen_e++;
5524
+ is_float++;
5233
5525
  tokadd(c);
5234
- nondigit = c;
5526
+ nondigit = (c == '-' || c == '+') ? c : 0;
5235
5527
  break;
5236
5528
 
5237
5529
  case '_': /* `_' in number just ignored */
@@ -5255,16 +5547,30 @@ retry:
5255
5547
  }
5256
5548
  tokfix();
5257
5549
  if(is_float) {
5258
- double d = strtod(tok(), 0);
5259
- if(errno == ERANGE) {
5260
- rb_warningS("Float %s out of range", tok());
5261
- errno = 0;
5550
+ int type = tFLOAT;
5551
+ VALUE v;
5552
+
5553
+ suffix = number_literal_suffix(seen_e ? NUM_SUFFIX_I : NUM_SUFFIX_ALL);
5554
+ if(suffix & NUM_SUFFIX_R) {
5555
+ char *point = &tok()[seen_point];
5556
+ size_t fraclen = toklen()-seen_point-1;
5557
+ type = tRATIONAL;
5558
+ memmove(point, point+1, fraclen+1);
5559
+ v = rb_cstr_to_inum(tok(), 10, FALSE);
5560
+ v = rb_rational_new(v,
5561
+ rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2NUM(fraclen)));
5562
+ } else {
5563
+ double d = strtod(tok(), 0);
5564
+ if(errno == ERANGE) {
5565
+ rb_warningS("Float %s out of range", tok());
5566
+ errno = 0;
5567
+ }
5568
+ v = rb_float_new(d);
5262
5569
  }
5263
- set_yylval_float(rb_float_new(d));
5264
- return tFLOAT;
5570
+ return set_number_literal(v, type, suffix);
5265
5571
  }
5266
- set_yylval_number(rb_cstr_to_inum(tok(), 10, FALSE));
5267
- return tINTEGER;
5572
+ suffix = number_literal_suffix(NUM_SUFFIX_ALL);
5573
+ return set_integer_literal(rb_cstr_to_inum(tok(), 10, FALSE), suffix);
5268
5574
  }
5269
5575
 
5270
5576
  case ')':
@@ -5278,12 +5584,15 @@ retry:
5278
5584
  } else {
5279
5585
  lex_state = EXPR_ENDARG;
5280
5586
  }
5587
+ if(c == '}') {
5588
+ if (!brace_nest--) c = tSTRING_DEND;
5589
+ }
5281
5590
  return c;
5282
5591
 
5283
5592
  case ':':
5284
5593
  c = nextc();
5285
5594
  if(c == ':') {
5286
- if(IS_BEG() || lex_state == EXPR_CLASS || IS_SPCARG(-1)) {
5595
+ if(IS_BEG() || lex_state_p(EXPR_CLASS) || IS_SPCARG(-1)) {
5287
5596
  lex_state = EXPR_BEG;
5288
5597
  return tCOLON3;
5289
5598
  }
@@ -5311,7 +5620,7 @@ retry:
5311
5620
  return tSYMBEG;
5312
5621
 
5313
5622
  case '/':
5314
- if(IS_BEG()) {
5623
+ if(lex_state_p(EXPR_BEG_ANY)) {
5315
5624
  lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
5316
5625
  return tREGEXP_BEG;
5317
5626
  }
@@ -5326,14 +5635,7 @@ retry:
5326
5635
  lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
5327
5636
  return tREGEXP_BEG;
5328
5637
  }
5329
- switch(lex_state) {
5330
- case EXPR_FNAME: case EXPR_DOT:
5331
- lex_state = EXPR_ARG;
5332
- break;
5333
- default:
5334
- lex_state = EXPR_BEG;
5335
- break;
5336
- }
5638
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
5337
5639
  warn_balanced("/", "regexp literal");
5338
5640
  return '/';
5339
5641
 
@@ -5343,14 +5645,7 @@ retry:
5343
5645
  lex_state = EXPR_BEG;
5344
5646
  return tOP_ASGN;
5345
5647
  }
5346
- switch(lex_state) {
5347
- case EXPR_FNAME: case EXPR_DOT:
5348
- lex_state = EXPR_ARG;
5349
- break;
5350
- default:
5351
- lex_state = EXPR_BEG;
5352
- break;
5353
- }
5648
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
5354
5649
  pushback(c);
5355
5650
  return '^';
5356
5651
 
@@ -5358,12 +5653,13 @@ retry:
5358
5653
  lex_state = EXPR_BEG;
5359
5654
  command_start = TRUE;
5360
5655
  return ';';
5656
+
5361
5657
  case ',':
5362
5658
  lex_state = EXPR_BEG;
5363
5659
  return ',';
5364
5660
 
5365
5661
  case '~':
5366
- if(lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
5662
+ if(IS_AFTER_OPERATOR()) {
5367
5663
  if((c = nextc()) != '@') {
5368
5664
  pushback(c);
5369
5665
  }
@@ -5387,7 +5683,7 @@ retry:
5387
5683
 
5388
5684
  case '[':
5389
5685
  paren_nest++;
5390
- if(lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
5686
+ if(IS_AFTER_OPERATOR()) {
5391
5687
  lex_state = EXPR_ARG;
5392
5688
  if((c = nextc()) == ']') {
5393
5689
  if((c = nextc()) == '=') {
@@ -5409,6 +5705,7 @@ retry:
5409
5705
  return c;
5410
5706
 
5411
5707
  case '{':
5708
+ ++brace_nest;
5412
5709
  if(lpar_beg && lpar_beg == paren_nest) {
5413
5710
  lex_state = EXPR_BEG;
5414
5711
  lpar_beg = 0;
@@ -5417,12 +5714,13 @@ retry:
5417
5714
  CMDARG_PUSH(0);
5418
5715
  return tLAMBEG;
5419
5716
  }
5420
- if(IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_ENDFN)
5717
+ if(IS_ARG() || lex_state_p(EXPR_END | EXPR_ENDFN)) {
5421
5718
  c = '{'; /* block (primary) */
5422
- else if(lex_state == EXPR_ENDARG)
5719
+ } else if(lex_state_p(EXPR_ENDARG)) {
5423
5720
  c = tLBRACE_ARG; /* block (expr) */
5424
- else
5721
+ } else {
5425
5722
  c = tLBRACE; /* hash */
5723
+ }
5426
5724
  COND_PUSH(0);
5427
5725
  CMDARG_PUSH(0);
5428
5726
  lex_state = EXPR_BEG;
@@ -5439,7 +5737,7 @@ retry:
5439
5737
  return '\\';
5440
5738
 
5441
5739
  case '%':
5442
- if(IS_BEG()) {
5740
+ if(lex_state_p(EXPR_BEG_ANY)) {
5443
5741
  intptr_t term;
5444
5742
  intptr_t paren;
5445
5743
 
@@ -5487,6 +5785,18 @@ retry:
5487
5785
  pushback(c);
5488
5786
  return tQWORDS_BEG;
5489
5787
 
5788
+ case 'I':
5789
+ lex_strterm = NEW_STRTERM(str_dword, term, paren);
5790
+ do {c = nextc();} while (ISSPACE(c));
5791
+ pushback(c);
5792
+ return tSYMBOLS_BEG;
5793
+
5794
+ case 'i':
5795
+ lex_strterm = NEW_STRTERM(str_sword, term, paren);
5796
+ do {c = nextc();} while (ISSPACE(c));
5797
+ pushback(c);
5798
+ return tQSYMBOLS_BEG;
5799
+
5490
5800
  case 'x':
5491
5801
  lex_strterm = NEW_STRTERM(str_xquote, term, paren);
5492
5802
  return tXSTRING_BEG;
@@ -5513,14 +5823,7 @@ retry:
5513
5823
  if(IS_SPCARG(c)) {
5514
5824
  goto quotation;
5515
5825
  }
5516
- switch(lex_state) {
5517
- case EXPR_FNAME: case EXPR_DOT:
5518
- lex_state = EXPR_ARG;
5519
- break;
5520
- default:
5521
- lex_state = EXPR_BEG;
5522
- break;
5523
- }
5826
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
5524
5827
  pushback(c);
5525
5828
  warn_balanced("%%", "string literal");
5526
5829
  return '%';
@@ -5558,9 +5861,7 @@ retry:
5558
5861
  case '\"': /* $": already loaded files */
5559
5862
  tokadd('$');
5560
5863
  tokadd(c);
5561
- tokfix();
5562
- set_yylval_name(parser_intern(tok()));
5563
- return tGVAR;
5864
+ goto gvar;
5564
5865
 
5565
5866
  case '-':
5566
5867
  tokadd('$');
@@ -5570,9 +5871,12 @@ retry:
5570
5871
  if(tokadd_mbchar(c) == -1) return 0;
5571
5872
  } else {
5572
5873
  pushback(c);
5874
+ pushback('-');
5875
+ return '$';
5573
5876
  }
5574
5877
  gvar:
5575
5878
  tokfix();
5879
+ // TODO rb_intern3(tok(), tokidx, current_enc);
5576
5880
  set_yylval_name(parser_intern(tok()));
5577
5881
  return tGVAR;
5578
5882
 
@@ -5580,7 +5884,7 @@ retry:
5580
5884
  case '`': /* $`: string before last match */
5581
5885
  case '\'': /* $': string after last match */
5582
5886
  case '+': /* $+: string matches last paren. */
5583
- if(last_state == EXPR_FNAME) {
5887
+ if(lex_state_of_p(last_state, EXPR_FNAME)) {
5584
5888
  tokadd('$');
5585
5889
  tokadd(c);
5586
5890
  goto gvar;
@@ -5597,7 +5901,7 @@ retry:
5597
5901
  c = nextc();
5598
5902
  } while(c != -1 && ISDIGIT(c));
5599
5903
  pushback(c);
5600
- if(last_state == EXPR_FNAME) goto gvar;
5904
+ if(lex_state_of_p(last_state, EXPR_FNAME)) goto gvar;
5601
5905
  tokfix();
5602
5906
  set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
5603
5907
  return tNTH_REF;
@@ -5605,7 +5909,9 @@ retry:
5605
5909
  default:
5606
5910
  if(!parser_is_identchar()) {
5607
5911
  pushback(c);
5608
- return '$';
5912
+ rb_compile_error(parser_state,
5913
+ "`$%c' is not allowed as a global variable name", c);
5914
+ return 0;
5609
5915
  }
5610
5916
  case '0':
5611
5917
  tokadd('$');
@@ -5620,7 +5926,7 @@ retry:
5620
5926
  tokadd('@');
5621
5927
  c = nextc();
5622
5928
  }
5623
- if(c != -1 && ISDIGIT(c)) {
5929
+ if(c != -1 && (ISDIGIT(c) || !parser_is_identchar())) {
5624
5930
  if(tokidx == 1) {
5625
5931
  rb_compile_error(parser_state,
5626
5932
  "`@%c' is not allowed as an instance variable name", c);
@@ -5630,10 +5936,6 @@ retry:
5630
5936
  }
5631
5937
  return 0;
5632
5938
  }
5633
- if(!parser_is_identchar()) {
5634
- pushback(c);
5635
- return '@';
5636
- }
5637
5939
  break;
5638
5940
 
5639
5941
  case '_':
@@ -5694,7 +5996,7 @@ retry:
5694
5996
  if(toklast() == '!' || toklast() == '?') {
5695
5997
  result = tFID;
5696
5998
  } else {
5697
- if(lex_state == EXPR_FNAME) {
5999
+ if(lex_state_p(EXPR_FNAME)) {
5698
6000
  if((c = nextc()) == '=' && !peek('~') && !peek('>') &&
5699
6001
  (!peek('=') || (peek_n('>', 1)))) {
5700
6002
  result = tIDENTIFIER;
@@ -5727,25 +6029,27 @@ retry:
5727
6029
  if(kw) {
5728
6030
  enum lex_state_e state = lex_state;
5729
6031
  lex_state = kw->state;
5730
- if(state == EXPR_FNAME) {
6032
+ if(lex_state_of_p(state, EXPR_FNAME)) {
5731
6033
  set_yylval_name(parser_intern(kw->name));
5732
6034
  return kw->id[0];
5733
6035
  }
5734
- if(kw->id[0] == keyword_do) {
6036
+ if(lex_state_p(EXPR_BEG)) {
5735
6037
  command_start = TRUE;
6038
+ }
6039
+ if(kw->id[0] == keyword_do) {
5736
6040
  if(lpar_beg && lpar_beg == paren_nest) {
5737
6041
  lpar_beg = 0;
5738
6042
  --paren_nest;
5739
6043
  return keyword_do_LAMBDA;
5740
6044
  }
5741
6045
  if(COND_P()) return keyword_do_cond;
5742
- if(CMDARG_P() && state != EXPR_CMDARG)
6046
+ if(CMDARG_P() && !lex_state_of_p(state, EXPR_CMDARG))
5743
6047
  return keyword_do_block;
5744
- if(state == EXPR_ENDARG || state == EXPR_BEG)
6048
+ if(lex_state_of_p(state, EXPR_BEG | EXPR_ENDARG))
5745
6049
  return keyword_do_block;
5746
6050
  return keyword_do;
5747
6051
  }
5748
- if(state == EXPR_BEG || state == EXPR_VALUE)
6052
+ if(lex_state_of_p(state, EXPR_BEG | EXPR_VALUE))
5749
6053
  return kw->id[0];
5750
6054
  else {
5751
6055
  if(kw->id[0] != kw->id[1])
@@ -5755,9 +6059,7 @@ retry:
5755
6059
  }
5756
6060
  }
5757
6061
 
5758
- if(IS_BEG() ||
5759
- lex_state == EXPR_DOT ||
5760
- IS_ARG()) {
6062
+ if(lex_state_p(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
5761
6063
  if(cmd_state) {
5762
6064
  lex_state = EXPR_CMDARG;
5763
6065
  } else {
@@ -5773,7 +6075,7 @@ retry:
5773
6075
  ID ident = TOK_INTERN(!ENC_SINGLE(mb));
5774
6076
 
5775
6077
  set_yylval_name(ident);
5776
- if(last_state != EXPR_DOT && last_state != EXPR_FNAME &&
6078
+ if(!lex_state_of_p(last_state, EXPR_DOT | EXPR_FNAME) &&
5777
6079
  is_local_id(ident) && lvar_defined(ident)) {
5778
6080
  lex_state = EXPR_END;
5779
6081
  }
@@ -6031,6 +6333,8 @@ static NODE *
6031
6333
  parser_literal_concat(rb_parser_state* parser_state, NODE *head, NODE *tail)
6032
6334
  {
6033
6335
  enum node_type htype;
6336
+ NODE *headlast;
6337
+ VALUE lit;
6034
6338
 
6035
6339
  if(!head) return tail;
6036
6340
  if(!tail) return head;
@@ -6039,11 +6343,20 @@ parser_literal_concat(rb_parser_state* parser_state, NODE *head, NODE *tail)
6039
6343
  if(htype == NODE_EVSTR) {
6040
6344
  NODE *node = NEW_DSTR(STR_NEW0());
6041
6345
  head = list_append(node, head);
6346
+ htype = NODE_DSTR;
6042
6347
  }
6043
6348
  switch(nd_type(tail)) {
6044
6349
  case NODE_STR:
6350
+ if(htype == NODE_DSTR
6351
+ && (headlast = head->nd_next->nd_end->nd_head)
6352
+ && nd_type(headlast) == NODE_STR) {
6353
+ htype = NODE_STR;
6354
+ lit = headlast->nd_lit;
6355
+ } else {
6356
+ lit = head->nd_lit;
6357
+ }
6045
6358
  if(htype == NODE_STR) {
6046
- if(!literal_concat0(head->nd_lit, tail->nd_lit)) {
6359
+ if(!literal_concat0(lit, tail->nd_lit)) {
6047
6360
  error:
6048
6361
  return 0;
6049
6362
  }
@@ -6059,9 +6372,18 @@ parser_literal_concat(rb_parser_state* parser_state, NODE *head, NODE *tail)
6059
6372
  tail->nd_lit = head->nd_lit;
6060
6373
  head = tail;
6061
6374
  } else if(NIL_P(tail->nd_lit)) {
6375
+ append:
6062
6376
  head->nd_alen += tail->nd_alen - 1;
6063
6377
  head->nd_next->nd_end->nd_next = tail->nd_next;
6064
6378
  head->nd_next->nd_end = tail->nd_next->nd_end;
6379
+ } else if(htype == NODE_DSTR
6380
+ && (headlast = head->nd_next->nd_end->nd_head)
6381
+ && nd_type(headlast) == NODE_STR) {
6382
+ lit = headlast->nd_lit;
6383
+ if (!literal_concat0(lit, tail->nd_lit))
6384
+ goto error;
6385
+ tail->nd_lit = Qnil;
6386
+ goto append;
6065
6387
  } else {
6066
6388
  nd_set_type(tail, NODE_ARRAY);
6067
6389
  tail->nd_head = NEW_STR(tail->nd_lit);
@@ -6125,6 +6447,7 @@ static const struct {
6125
6447
  {tDOT2, ".."},
6126
6448
  {tDOT3, "..."},
6127
6449
  {tPOW, "**"},
6450
+ {tDSTAR, "**"},
6128
6451
  {tUPLUS, "+@"},
6129
6452
  {tUMINUS, "-@"},
6130
6453
  {tCMP, "<=>"},
@@ -6379,8 +6702,6 @@ parser_aryset(rb_parser_state* parser_state, NODE *recv, NODE *idx)
6379
6702
  {
6380
6703
  if(recv && nd_type(recv) == NODE_SELF) {
6381
6704
  recv = (NODE *)1;
6382
- } else {
6383
- value_expr(recv);
6384
6705
  }
6385
6706
  return NEW_ATTRASGN(recv, convert_op(tASET), idx);
6386
6707
  }
@@ -6393,9 +6714,44 @@ parser_block_dup_check(rb_parser_state* parser_state, NODE *node1, NODE *node2)
6393
6714
  }
6394
6715
  }
6395
6716
 
6717
+ static const char id_type_names[][9] = {
6718
+ "LOCAL",
6719
+ "INSTANCE",
6720
+ "", /* INSTANCE2 */
6721
+ "GLOBAL",
6722
+ "ATTRSET",
6723
+ "CONST",
6724
+ "CLASS",
6725
+ "JUNK",
6726
+ };
6727
+
6396
6728
  static ID
6397
6729
  rb_id_attrset(ID id)
6398
6730
  {
6731
+ if(!is_notop_id(id)) {
6732
+ switch (id) {
6733
+ case tAREF:
6734
+ case tASET:
6735
+ return tASET; /* only exception */
6736
+ }
6737
+ rb_name_error(id, "cannot make operator ID :%s attrset", rb_id2name(id));
6738
+ } else {
6739
+ int scope = (int)(id & ID_SCOPE_MASK);
6740
+ switch(scope) {
6741
+ case ID_LOCAL:
6742
+ case ID_INSTANCE:
6743
+ case ID_GLOBAL:
6744
+ case ID_CONST:
6745
+ case ID_CLASS:
6746
+ case ID_JUNK:
6747
+ break;
6748
+ case ID_ATTRSET:
6749
+ return id;
6750
+ default:
6751
+ rb_name_error(id, "cannot make %s ID %+ld attrset",
6752
+ id_type_names[scope], ID2SYM(id));
6753
+ }
6754
+ }
6399
6755
  id &= ~ID_SCOPE_MASK;
6400
6756
  id |= ID_ATTRSET;
6401
6757
  return id;
@@ -6448,18 +6804,6 @@ parser_arg_append(rb_parser_state* parser_state, NODE *node1, NODE *node2)
6448
6804
  return NEW_ARGSPUSH(node1, node2);
6449
6805
  }
6450
6806
 
6451
- static NODE *
6452
- arg_add(rb_parser_state* parser_state, NODE *node1, NODE *node2)
6453
- {
6454
- if(!node1) return NEW_LIST(node2);
6455
- if(nd_type(node1) == NODE_ARRAY) {
6456
- return list_append(node1, node2);
6457
- }
6458
- else {
6459
- return NEW_ARGSPUSH(node1, node2);
6460
- }
6461
- }
6462
-
6463
6807
  static NODE *
6464
6808
  splat_array(NODE* node)
6465
6809
  {
@@ -6473,7 +6817,6 @@ parser_node_assign(rb_parser_state* parser_state, NODE *lhs, NODE *rhs)
6473
6817
  {
6474
6818
  if(!lhs) return 0;
6475
6819
 
6476
- value_expr(rhs);
6477
6820
  switch(nd_type(lhs)) {
6478
6821
  case NODE_GASGN:
6479
6822
  case NODE_IASGN:
@@ -6482,14 +6825,13 @@ parser_node_assign(rb_parser_state* parser_state, NODE *lhs, NODE *rhs)
6482
6825
  case NODE_DASGN_CURR:
6483
6826
  case NODE_MASGN:
6484
6827
  case NODE_CDECL:
6485
- case NODE_CVDECL:
6486
6828
  case NODE_CVASGN:
6487
6829
  lhs->nd_value = rhs;
6488
6830
  break;
6489
6831
 
6490
6832
  case NODE_ATTRASGN:
6491
6833
  case NODE_CALL:
6492
- lhs->nd_args = arg_add(parser_state, lhs->nd_args, rhs);
6834
+ lhs->nd_args = arg_append(lhs->nd_args, rhs);
6493
6835
  break;
6494
6836
 
6495
6837
  default:
@@ -6500,6 +6842,76 @@ parser_node_assign(rb_parser_state* parser_state, NODE *lhs, NODE *rhs)
6500
6842
  return lhs;
6501
6843
  }
6502
6844
 
6845
+ static NODE*
6846
+ parser_new_op_assign(rb_parser_state* parser_state, NODE *lhs, ID op, NODE *rhs)
6847
+ {
6848
+ NODE *asgn;
6849
+
6850
+ if(lhs) {
6851
+ ID vid = lhs->nd_vid;
6852
+ if(op == tOROP) {
6853
+ lhs->nd_value = rhs;
6854
+ asgn = NEW_OP_ASGN_OR(gettable(vid), lhs);
6855
+ if(is_asgn_or_id(vid)) {
6856
+ asgn->nd_aid = vid;
6857
+ }
6858
+ } else if(op == tANDOP) {
6859
+ lhs->nd_value = rhs;
6860
+ asgn = NEW_OP_ASGN_AND(gettable(vid), lhs);
6861
+ } else {
6862
+ asgn = lhs;
6863
+ // TODO: is NEW_LIST(rhs) needed?
6864
+ asgn->nd_value = call_bin_op(gettable(vid), op, rhs);
6865
+ }
6866
+ } else {
6867
+ asgn = NEW_BEGIN(0);
6868
+ }
6869
+
6870
+ return asgn;
6871
+ }
6872
+
6873
+ static NODE*
6874
+ parser_new_attr_op_assign(rb_parser_state* parser_state,
6875
+ NODE *lhs, ID attr, ID op, NODE *rhs)
6876
+ {
6877
+ NODE *asgn;
6878
+
6879
+ if(op == tOROP) {
6880
+ op = 0;
6881
+ } else if(op == tANDOP) {
6882
+ op = 1;
6883
+ } else {
6884
+ op = convert_op(op);
6885
+ }
6886
+ asgn = NEW_OP_ASGN2(lhs, attr, op, rhs);
6887
+ fixpos(asgn, lhs);
6888
+
6889
+ return asgn;
6890
+ }
6891
+
6892
+ static NODE*
6893
+ parser_new_const_op_assign(rb_parser_state* parser_state, NODE *lhs, ID op, NODE *rhs)
6894
+ {
6895
+ NODE *asgn;
6896
+
6897
+ if(op == tOROP) {
6898
+ op = 0;
6899
+ } else if(op == tANDOP) {
6900
+ op = 1;
6901
+ } else {
6902
+ op = convert_op(op);
6903
+ }
6904
+
6905
+ if(lhs) {
6906
+ asgn = NEW_OP_CDECL(lhs, op, rhs);
6907
+ } else {
6908
+ asgn = NEW_BEGIN(0);
6909
+ }
6910
+ fixpos(asgn, lhs);
6911
+
6912
+ return asgn;
6913
+ }
6914
+
6503
6915
  static int
6504
6916
  parser_value_expr(rb_parser_state* parser_state, NODE *node)
6505
6917
  {
@@ -6511,11 +6923,6 @@ parser_value_expr(rb_parser_state* parser_state, NODE *node)
6511
6923
 
6512
6924
  while(node) {
6513
6925
  switch(nd_type(node)) {
6514
- case NODE_DEFN:
6515
- case NODE_DEFS:
6516
- parser_warning(node, "void value expression");
6517
- return FALSE;
6518
-
6519
6926
  case NODE_RETURN:
6520
6927
  case NODE_BREAK:
6521
6928
  case NODE_NEXT:
@@ -6899,6 +7306,8 @@ parser_negate_lit(rb_parser_state* parser_state, NODE *node)
6899
7306
  node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));
6900
7307
  break;
6901
7308
  case T_BIGNUM:
7309
+ case T_RATIONAL:
7310
+ case T_COMPLEX:
6902
7311
  node->nd_lit = REF(rb_funcall(node->nd_lit, rb_intern("-@"), 0, 0));
6903
7312
  break;
6904
7313
  case T_FLOAT:
@@ -6921,25 +7330,50 @@ arg_blk_pass(NODE *node1, NODE *node2)
6921
7330
  }
6922
7331
 
6923
7332
  static NODE*
6924
- parser_new_args(rb_parser_state* parser_state, NODE *m, NODE *o, ID r, NODE *p, ID b)
7333
+ parser_new_args(rb_parser_state* parser_state, NODE *m, NODE *o, ID r, NODE *p, NODE *tail)
7334
+ {
7335
+ int saved_line = sourceline;
7336
+ struct rb_args_info *args = tail->nd_ainfo;
7337
+
7338
+ args->pre_args_num = m ? rb_long2int(m->nd_plen) : 0;
7339
+ args->pre_init = m ? m->nd_next : 0;
7340
+
7341
+ args->post_args_num = p ? rb_long2int(p->nd_plen) : 0;
7342
+ args->post_init = p ? p->nd_next : 0;
7343
+ args->first_post_arg = p ? p->nd_pid : 0;
7344
+
7345
+ args->rest_arg = r;
7346
+
7347
+ args->opt_args = o;
7348
+
7349
+ sourceline = saved_line;
7350
+ return tail;
7351
+ }
7352
+
7353
+ static NODE*
7354
+ parser_new_args_tail(rb_parser_state* parser_state, NODE *k, ID kr, ID b)
6925
7355
  {
6926
7356
  int saved_line = sourceline;
7357
+ struct rb_args_info *args;
7358
+ NODE *kw_rest_arg = 0;
6927
7359
  NODE *node;
6928
- NODE *i1, *i2 = 0;
6929
7360
 
6930
- node = NEW_ARGS(m ? m->nd_plen : 0, o);
6931
- i1 = m ? m->nd_next : 0;
6932
- node->nd_next = NEW_ARGS_AUX(r, b);
7361
+ args = ALLOC(struct rb_args_info);
7362
+ MEMZERO(args, struct rb_args_info, 1);
7363
+ node = NEW_NODE(NODE_ARGS, 0, 0, args);
6933
7364
 
6934
- if(p) {
6935
- i2 = p->nd_next;
6936
- node->nd_next->nd_next = NEW_ARGS_AUX(p->nd_pid, p->nd_plen);
6937
- } else if(i1) {
6938
- node->nd_next->nd_next = NEW_ARGS_AUX(0, 0);
6939
- }
6940
- if(i1 || i2) {
6941
- node->nd_next->nd_next->nd_next = NEW_NODE(NODE_AND, i1, i2, 0);
7365
+ args->block_arg = b;
7366
+ args->kw_args = k;
7367
+ if(kr) {
7368
+ if(kr == 1) {
7369
+ kw_rest_arg = (NODE*)kr;
7370
+ } else {
7371
+ arg_var(kr);
7372
+ kw_rest_arg = NEW_DVAR(kr);
7373
+ }
6942
7374
  }
7375
+ args->kw_rest_arg = kw_rest_arg;
7376
+
6943
7377
  sourceline = saved_line;
6944
7378
  return node;
6945
7379
  }
@@ -7109,8 +7543,8 @@ parser_id2name(ID id)
7109
7543
  static int
7110
7544
  scan_oct(const char *start, size_t len, size_t *retlen)
7111
7545
  {
7112
- register const char *s = start;
7113
- register int retval = 0;
7546
+ const char *s = start;
7547
+ int retval = 0;
7114
7548
 
7115
7549
  while(len-- && *s >= '0' && *s <= '7') {
7116
7550
  retval <<= 3;
@@ -7124,8 +7558,8 @@ static int
7124
7558
  scan_hex(const char *start, size_t len, size_t *retlen)
7125
7559
  {
7126
7560
  static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
7127
- register const char *s = start;
7128
- register int retval = 0;
7561
+ const char *s = start;
7562
+ int retval = 0;
7129
7563
  const char *tmp;
7130
7564
 
7131
7565
  while(len-- && *s && (tmp = strchr(hexdigit, *s))) {