rubinius-melbourne 2.1.0.0 → 2.2.0.0

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