yarv-diff:411
From: ko1 atdot.net
Date: 10 Nov 2006 09:18:14 +0900
Subject: [yarv-diff:411] r579 - in trunk: . yarvtest
Author: ko1
Date: 2006-11-10 09:18:12 +0900 (Fri, 10 Nov 2006)
New Revision: 579
Modified:
trunk/ChangeLog
trunk/class.c
trunk/compile.c
trunk/eval_thread.c
trunk/gc.c
trunk/iseq.c
trunk/node.h
trunk/parse.y
trunk/vm_dump.c
trunk/yarvtest/test_block.rb
trunk/yarvtest/test_class.rb
trunk/yarvtest/test_syntax.rb
Log:
* class.c : revert module duplicate inclusion
* parse.y : catch up current Ruby HEAD
* node.h : ditto
* compile.c : ditto
* gc.c : ditto
* iseq.c : ditto
* eval_thread.c : define Continuation (null class)
* vm_dump.c : fix to output backtrae to stderr
* yarvtest/test_block.rb : remove unsupported test
* yarvtest/test_class.rb : add a test about super
* yarvtest/test_syntax.rb : add a test about case/when
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/ChangeLog 2006-11-10 00:18:12 UTC (rev 579)
@@ -4,6 +4,31 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-11-10(Fri) 09:13:46 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * class.c : revert module duplicate inclusion
+
+ * parse.y : catch up current Ruby HEAD
+
+ * node.h : ditto
+
+ * compile.c : ditto
+
+ * gc.c : ditto
+
+ * iseq.c : ditto
+
+ * eval_thread.c : define Continuation (null class)
+
+ * vm_dump.c : fix to output backtrae to stderr
+
+ * yarvtest/test_block.rb : remove unsupported test
+
+ * yarvtest/test_class.rb : add a test about super
+
+ * yarvtest/test_syntax.rb : add a test about case/when
+
+
2006-11-09(Thu) 10:22:59 +0900 Koichi Sasada <ko1 atdot.net>
* call_cfunc.h -> call_cfunc.ci : renamed
Modified: trunk/class.c
===================================================================
--- trunk/class.c 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/class.c 2006-11-10 00:18:12 UTC (rev 579)
@@ -365,7 +365,7 @@
void
rb_include_module(VALUE klass, VALUE module)
{
- VALUE c;
+ VALUE p, c;
int changed = 0;
rb_frozen_class_p(klass);
@@ -380,11 +380,29 @@
OBJ_INFECT(klass, module);
c = klass;
while (module) {
+ int superclass_seen = Qfalse;
+
if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
rb_raise(rb_eArgError, "cyclic include detected");
- RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
- c = RCLASS(c)->super;
+ /* ignore if the module included already in superclasses */
+ for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
+ switch (BUILTIN_TYPE(p)) {
+ case T_ICLASS:
+ if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
+ if (!superclass_seen) {
+ c = p; /* move insertion point */
+ }
+ goto skip;
+ }
+ break;
+ case T_CLASS:
+ superclass_seen = Qtrue;
+ break;
+ }
+ }
+ c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
changed = 1;
+ skip:
module = RCLASS(module)->super;
}
if (changed) rb_clear_cache();
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/compile.c 2006-11-10 00:18:12 UTC (rev 579)
@@ -1967,7 +1967,7 @@
if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
opt_p = Qfalse;
}
- COMPILE(anchor, "element", node->nd_head);
+ COMPILE(anchor, "array element", node->nd_head);
node = node->nd_next;
}
@@ -1992,8 +1992,7 @@
ADD_INSN1(anchor, line, newarray, INT2FIX(len));
APPEND_LIST(ret, anchor);
}
-
- return COMPILE_OK;
+ return len;
}
static VALUE
@@ -2012,6 +2011,33 @@
return Qfalse;
}
+static VALUE
+when_vals(yarv_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, VALUE special_literals)
+{
+ while (vals) {
+ VALUE lit;
+ NODE* val;
+
+ val = vals->nd_head;
+
+ if (special_literals &&
+ (lit = case_when_optimizable_literal(val)) != Qfalse) {
+ rb_ary_push(special_literals, lit);
+ rb_ary_push(special_literals, (VALUE)(l1) | 1);
+ }
+ else {
+ special_literals = Qfalse;
+ }
+
+ COMPILE(cond_seq, "when cond", val);
+ ADD_INSN1(cond_seq, nd_line(val), topn, INT2FIX(1));
+ ADD_SEND(cond_seq, nd_line(val), ID2SYM(idEqq), INT2FIX(1));
+ ADD_INSNL(cond_seq, nd_line(val), branchif, l1);
+ vals = vals->nd_next;
+ }
+ return special_literals;
+}
+
static int
make_masgn_lhs(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node)
{
@@ -2156,7 +2182,10 @@
break;
}
default:
- rb_bug("unknown rhs: %s", node_name(nd_type(rhsn)));
+ COMPILE(ret, "rhs to ary (splat/default)", rhsn);
+ ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen),
+ INT2FIX(lhs_splat));
+ // rb_bug("unknown rhs: %s", node_name(nd_type(rhsn)));
}
}
else {
@@ -2468,6 +2497,49 @@
ADD_SEQ(ret, ensure);
}
+static VALUE
+setup_arg(yarv_iseq_t *iseq, LINK_ANCHOR *args, NODE *node, VALUE *flag)
+{
+ VALUE argc = INT2FIX(0);
+ NODE *argn = node->nd_args;
+ DECL_ANCHOR(arg_block);
+
+ if (argn && nd_type(argn) == NODE_BLOCK_PASS) {
+ COMPILE(arg_block, "block", argn->nd_body);
+ *flag |= VM_CALL_ARGS_BLOCKARG_BIT;
+ argn = argn->nd_head;
+ }
+
+ if (argn) {
+ switch (nd_type(argn)) {
+ case NODE_SPLAT: {
+ COMPILE(args, "args(splat)", argn->nd_head);
+ argc = INT2FIX(1);
+ *flag |= VM_CALL_ARGS_SPLAT_BIT;
+ break;
+ }
+ case NODE_ARGSCAT: {
+ argc = INT2FIX(compile_array(iseq, args, argn->nd_head, Qfalse) + 1);
+ POP_ELEMENT(args);
+ COMPILE(args, "args(cat: splat)", argn->nd_body);
+ *flag |= VM_CALL_ARGS_SPLAT_BIT;
+ break;
+ }
+ default: {
+ argc = INT2FIX(compile_array(iseq, args, argn, Qfalse));
+ POP_ELEMENT(args);
+ break;
+ }
+ }
+ }
+
+ if (*flag & VM_CALL_ARGS_BLOCKARG_BIT) {
+ ADD_SEQ(args, arg_block);
+ }
+ return argc;
+}
+
+
/**
compile each node
@@ -2502,6 +2574,7 @@
case NODE_METHOD:{
/* OK */
+ bp();
COMPILE_ERROR(("BUG: unknown node: NODE_METHOD"));
break;
}
@@ -2569,6 +2642,10 @@
DECL_ANCHOR(cond_seq);
VALUE special_literals = rb_ary_new();
+ if (node->nd_head == 0) {
+ COMPILE_(ret, "when", node->nd_body, poped);
+ break;
+ }
COMPILE(head, "case base", node->nd_head);
node = node->nd_body;
@@ -2593,43 +2670,29 @@
ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
vals = node->nd_head;
- if (vals && nd_type(vals) == NODE_ARRAY) {
- while (vals) {
- VALUE lit;
- val = vals->nd_head;
+ if (vals) {
+ if (nd_type(vals) == NODE_ARRAY) {
+ special_literals = when_vals(iseq, cond_seq, vals, l1, special_literals);
+ }
+ else if (nd_type(vals) == NODE_SPLAT || nd_type(vals) == NODE_ARGSCAT) {
+ NODE *val = vals->nd_head;
+ special_literals = 0;
- if ((lit = case_when_optimizable_literal(val))
- && special_literals) {
- rb_ary_push(special_literals, lit);
- rb_ary_push(special_literals, (VALUE)(l1) | 1);
+ if (nd_type(vals) == NODE_ARGSCAT) {
+ when_vals(iseq, cond_seq, vals->nd_head, l1, 0);
+ val = vals->nd_body;
}
- else {
- special_literals = Qfalse;
- }
- if (nd_type(val) == NODE_WHEN) { // && nd_type(val->nd_head) != NODE_ARRAY){
- COMPILE(cond_seq, "when/cond specail?",
- val->nd_head);
- ADD_INSN1(cond_seq, nd_line(node),
- checkincludearray, Qtrue);
- /* for stack caching */
- ADD_INSN(cond_seq, nd_line(node), putnil);
- ADD_INSN(cond_seq, nd_line(node), pop);
- }
- else {
- COMPILE(cond_seq, "when cond", val);
- ADD_INSN1(cond_seq, nd_line(node), topn,
- INT2FIX(1));
- ADD_SEND(cond_seq, nd_line(node), ID2SYM(idEqq),
- INT2FIX(1));
- }
- ADD_INSNL(cond_seq, nd_line(node), branchif, l1) ;
- vals = vals->nd_next;
+ COMPILE(cond_seq, "when/cond splat", val);
+ ADD_INSN1(cond_seq, nd_line(val), checkincludearray, Qtrue);
+ ADD_INSNL(cond_seq, nd_line(val), branchif, l1);
}
+ else {
+ rb_bug("NODE_CASAE: unknown node (%s)", node_name(nd_type(vals)));
+ }
}
else {
- COMPILE_ERROR(("NODE_CASAE: must be NODE_ARRAY, but %s\n",
- node_name(nd_type(vals))));
+ rb_bug("NODE_CASAE: must be NODE_ARRAY, but 0\n");
}
node = node->nd_next;
@@ -2686,21 +2749,32 @@
if (vals && nd_type(vals) == NODE_ARRAY) {
while (vals) {
val = vals->nd_head;
- if (nd_type(val) == NODE_WHEN) {
- ADD_INSN(ret, nd_line(val), putnil);
- COMPILE(ret, "when2/splat", val->nd_head);
- ADD_INSN1(ret, nd_line(val), checkincludearray,
- Qfalse);
- ADD_INSN(ret, nd_line(val), pop);
- ADD_INSNL(ret, nd_line(val), branchif, l1) ;
- }
- else {
- COMPILE(ret, "when2", val);
- ADD_INSNL(ret, nd_line(val), branchif, l1) ;
- }
+ COMPILE(ret, "when2", val);
+ ADD_INSNL(ret, nd_line(val), branchif, l1) ;
vals = vals->nd_next;
}
}
+ else if (nd_type(vals) == NODE_SPLAT || nd_type(vals) == NODE_ARGSCAT) {
+ NODE *val = vals->nd_head;
+
+ if (nd_type(vals) == NODE_ARGSCAT) {
+ NODE *vs = vals->nd_head;
+ val = vals->nd_body;
+
+ while (vs) {
+ NODE* val = vs->nd_head;
+ COMPILE(ret, "when/argscat", val);
+ ADD_INSNL(ret, nd_line(val), branchif, l1);
+ vs = vs->nd_next;
+ }
+ }
+
+ ADD_INSN(ret, nd_line(val), putnil);
+ COMPILE(ret, "when2/splat", val);
+ ADD_INSN1(ret, nd_line(val), checkincludearray, Qfalse);
+ ADD_INSN(ret, nd_line(val), pop);
+ ADD_INSNL(ret, nd_line(val), branchif, l1);
+ }
else {
rb_bug("err");
}
@@ -3220,15 +3294,20 @@
* send op # a x a[x]+y
* send []= # ret
*/
+
+ /*
+ * nd_recv[nd_args->nd_body] (nd_mid)= nd_args->nd_head;
+ * NODE_OP_ASGN nd_recv
+ * nd_args->nd_head
+ * nd_args->nd_body
+ * nd_mid
+ */
+
COMPILE(ret, "NODE_OP_ASGN1 recv", node->nd_recv);
-
- compile_array(iseq, args, node->nd_args->nd_next, Qfalse);
+ argc = compile_array(iseq, args, node->nd_args->nd_body, Qfalse);
POP_ELEMENT(args);
- POP_ELEMENT(args);
- argc = node->nd_args->nd_alen - 2;
-
ADD_SEQ(ret, args);
- ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(argc + 1));
+ ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(argc+1));
ADD_SEND(ret, nd_line(node), ID2SYM(idAREF), INT2FIX(argc));
if (id == 0 || id == 1) {
@@ -3477,31 +3556,8 @@
}
/* args */
- if (type != NODE_VCALL && node->nd_args) {
- if (nd_type(node->nd_args) == NODE_SPLAT) {
- COMPILE(args, "args(splat)", node->nd_args->nd_head);
- argc = INT2FIX(1);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else if (nd_type(node->nd_args) == NODE_ARGSCAT) {
- NODE *t = node->nd_args->nd_head;
- for (argc = 0; t; argc++, t = t->nd_next) {
- /* */
- }
- argc = INT2FIX(argc + 1);
-
- compile_array(iseq, args, node->nd_args->nd_head, Qfalse);
- POP_ELEMENT(args);
-
- // argc = INT2FIX(LIST_SIZE(args) + 1);
- COMPILE(args, "args(cat: splat)", node->nd_args->nd_body);
-
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else {
- compile_array(iseq, args, node->nd_args, Qfalse);
- argc = OPERAND_AT(POP_ELEMENT(args), 0);
- }
+ if (nd_type(node) != NODE_VCALL) {
+ argc = setup_arg(iseq, args, node, &flag);
}
else {
argc = INT2FIX(0);
@@ -3550,31 +3606,7 @@
iseq->compile_data->current_block = Qfalse;
if (nd_type(node) == NODE_SUPER) {
- /* args */
- if (type != NODE_VCALL && node->nd_args) {
- if (nd_type(node->nd_args) == NODE_SPLAT) {
- COMPILE(args, "args(splat)", node->nd_args->nd_head);
- argc = INT2FIX(1);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else if (nd_type(node->nd_args) == NODE_ARGSCAT) {
- compile_array(iseq, args, node->nd_args->nd_head,
- Qfalse);
- POP_ELEMENT(args);
-
- argc = INT2FIX(LIST_SIZE(args) + 1);
- COMPILE(args, "args(cat: splat)",
- node->nd_args->nd_body);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else {
- compile_array(iseq, args, node->nd_args, Qfalse);
- argc = OPERAND_AT(POP_ELEMENT(args), 0);
- }
- }
- else {
- argc = INT2FIX(0);
- }
+ argc = setup_arg(iseq, args, node, &flag);
}
else {
/* NODE_ZSUPER */
@@ -4025,35 +4057,14 @@
COMPILE_ERROR(("BUG: unknown node: NODE_TO_ARY"));
break;
}
- case NODE_SVALUE:{
- COMPILE(ret, "svalue head", node->nd_head);
- ADD_INSN1(ret, nd_line(node), splatarray, Qtrue);
- break;
- }
case NODE_BLOCK_ARG:{
iseq->arg_block = node->nd_cnt - 2 + 1;
iseq->arg_simple = 0;
-
break;
}
case NODE_BLOCK_PASS:{
- VALUE prevblock = iseq->compile_data->current_block;
- LABEL *retry_label = NEW_LABEL(nd_line(node));
- LABEL *retry_end_l = NEW_LABEL(nd_line(node));
- DECL_ANCHOR(current_block);
-
- COMPILE(current_block, "block pass proc", node->nd_body);
-
- iseq->compile_data->current_block = (VALUE)current_block | 1;
- ADD_LABEL(ret, retry_label);
- COMPILE_(ret, "iter caller (NODE_BLOCK_PASS)", node->nd_iter,
- poped);
- ADD_LABEL(ret, retry_end_l);
-
- iseq->compile_data->current_block = prevblock;
- ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, retry_label, retry_end_l, 0,
- retry_label);
- break;
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_BLOCK_PASS"));
}
case NODE_DEFN:{
VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
@@ -4362,8 +4373,8 @@
break;
}
case NODE_POSTEXE:{
- ADD_INSN1(ret, nd_line(node), postexe,
- iseq->compile_data->current_block);
+ VALUE block = NEW_CHILD_ISEQVAL(node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK);
+ ADD_INSN1(ret, nd_line(node), postexe, block);
if (!poped) {
ADD_INSN(ret, nd_line(node), putnil);
}
Modified: trunk/eval_thread.c
===================================================================
--- trunk/eval_thread.c 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/eval_thread.c 2006-11-10 00:18:12 UTC (rev 579)
@@ -587,6 +587,7 @@
{
recursive_key = rb_intern("__recursive_key__");
rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);
+ rb_cCont = rb_define_class("Continuation", rb_cObject);
}
static VALUE
Modified: trunk/gc.c
===================================================================
--- trunk/gc.c 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/gc.c 2006-11-10 00:18:12 UTC (rev 579)
@@ -847,6 +847,7 @@
case NODE_RESBODY:
case NODE_CLASS:
case NODE_ARGS:
+ case NODE_BLOCK_PASS:
gc_mark((VALUE)obj->as.node.u2.node, lev);
/* fall through */
case NODE_BLOCK: /* 1,3 */
@@ -901,6 +902,7 @@
case NODE_OPT_N:
case NODE_EVSTR:
case NODE_UNDEF:
+ case NODE_POSTEXE:
ptr = (VALUE)obj->as.node.u2.node;
goto again;
@@ -917,12 +919,10 @@
case NODE_COLON2:
case NODE_SPLAT:
case NODE_TO_ARY:
- case NODE_SVALUE:
ptr = (VALUE)obj->as.node.u1.node;
goto again;
case NODE_SCOPE: /* 2,3 */
- case NODE_BLOCK_PASS:
case NODE_CDECL:
gc_mark((VALUE)obj->as.node.u3.node, lev);
ptr = (VALUE)obj->as.node.u2.node;
@@ -948,7 +948,6 @@
case NODE_ERRINFO:
case NODE_ATTRSET:
case NODE_BLOCK_ARG:
- case NODE_POSTEXE:
break;
case NODE_ALLOCA:
mark_locations_array((VALUE*)obj->as.node.u1.value,
Modified: trunk/iseq.c
===================================================================
--- trunk/iseq.c 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/iseq.c 2006-11-10 00:18:12 UTC (rev 579)
@@ -934,6 +934,8 @@
return "NODE_DREGX_ONCE";
case NODE_ARGS:
return "NODE_ARGS";
+ case NODE_POSTARG:
+ return "NODE_POSTARG";
case NODE_ARGSCAT:
return "NODE_ARGSCAT";
case NODE_ARGSPUSH:
@@ -942,8 +944,6 @@
return "NODE_SPLAT";
case NODE_TO_ARY:
return "NODE_TO_ARY";
- case NODE_SVALUE:
- return "NODE_SVALUE";
case NODE_BLOCK_ARG:
return "NODE_BLOCK_ARG";
case NODE_BLOCK_PASS:
Modified: trunk/node.h
===================================================================
--- trunk/node.h 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/node.h 2006-11-10 00:18:12 UTC (rev 579)
@@ -86,11 +86,11 @@
NODE_DREGX,
NODE_DREGX_ONCE,
NODE_ARGS,
+ NODE_POSTARG,
NODE_ARGSCAT,
NODE_ARGSPUSH,
NODE_SPLAT,
NODE_TO_ARY,
- NODE_SVALUE,
NODE_BLOCK_ARG,
NODE_BLOCK_PASS,
NODE_DEFN,
@@ -314,11 +314,11 @@
#define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)
#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)
#define NEW_ARGS(f,o,r) NEW_NODE(NODE_ARGS,o,r,f)
+#define NEW_POSTARG(r,m) NEW_NODE(NODE_POSTARG,m,0,r)
#define NEW_ARGSCAT(a,b) NEW_NODE(NODE_ARGSCAT,a,b,0)
#define NEW_ARGSPUSH(a,b) NEW_NODE(NODE_ARGSPUSH,a,b,0)
#define NEW_SPLAT(a) NEW_NODE(NODE_SPLAT,a,0,0)
#define NEW_TO_ARY(a) NEW_NODE(NODE_TO_ARY,a,0,0)
-#define NEW_SVALUE(a) NEW_NODE(NODE_SVALUE,a,0,0)
#define NEW_BLOCK_ARG(v) NEW_NODE(NODE_BLOCK_ARG,v,0,local_cnt(v))
#define NEW_BLOCK_PASS(b) NEW_NODE(NODE_BLOCK_PASS,0,b,0)
#define NEW_ALIAS(n,o) NEW_NODE(NODE_ALIAS,n,o,0)
@@ -340,7 +340,7 @@
#define NEW_ERRINFO() NEW_NODE(NODE_ERRINFO,0,0,0)
#define NEW_DEFINED(e) NEW_NODE(NODE_DEFINED,e,0,0)
#define NEW_PREEXE(b) NEW_SCOPE(b)
-#define NEW_POSTEXE() NEW_NODE(NODE_POSTEXE,0,0,0)
+#define NEW_POSTEXE(b) NEW_NODE(NODE_POSTEXE,0,b,0)
#define NEW_BMETHOD(b) NEW_NODE(NODE_BMETHOD,0,0,b)
#define NEW_ATTRASGN(r,m,a) NEW_NODE(NODE_ATTRASGN,r,m,a)
#define NEW_PRELUDE(p,b) NEW_NODE(NODE_PRELUDE,p,b,0)
Modified: trunk/parse.y
===================================================================
--- trunk/parse.y 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/parse.y 2006-11-10 00:18:12 UTC (rev 579)
@@ -66,7 +66,6 @@
enum lex_state_e {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is a operator. */
- EXPR_END2, /* newline significant, +/- is a operator. */
EXPR_ARG, /* newline significant, +/- is a operator. */
EXPR_CMDARG, /* newline significant, +/- is a operator. */
EXPR_ENDARG, /* newline significant, +/- is a operator. */
@@ -206,6 +205,8 @@
token
*/
struct parser_params {
+ NODE *heap;
+
union tmpyystype *parser_yylval; /* YYSTYPE not defined yet */
VALUE eofp;
@@ -226,15 +227,18 @@
int parser_toksiz;
VALUE parser_lex_input;
VALUE parser_lex_lastline;
- char *parser_lex_pbeg;
- char *parser_lex_p;
- char *parser_lex_pend;
+ const char *parser_lex_pbeg;
+ const char *parser_lex_p;
+ const char *parser_lex_pend;
int parser_heredoc_end;
int parser_command_start;
int parser_lex_gets_ptr;
VALUE (*parser_lex_gets)(struct parser_params*,VALUE);
struct local_vars *parser_lvtbl;
int parser_ruby__end__seen;
+ int line_count;
+ int has_shebang;
+
#ifndef RIPPER
/* Ruby core only */
NODE *parser_eval_tree_begin;
@@ -244,7 +248,7 @@
/* Ripper only */
int parser_ruby_sourceline;
VALUE parser_ruby_sourcefile;
- char *tokp;
+ const char *tokp;
VALUE delayed;
int delayed_line;
int delayed_col;
@@ -254,12 +258,6 @@
VALUE parsing_thread;
int toplevel_p;
#endif
- int line_count;
- int has_shebang;
-
-#ifdef YYMALLOC
- NODE *heap;
-#endif
};
#ifdef YYMALLOC
@@ -314,7 +312,7 @@
static int yylex(void*, void*);
#ifndef RIPPER
-#define yyparse parser_yyparse
+#define yyparse ruby_yyparse
#define yydebug ruby_yydebug
static NODE *cond_gen(struct parser_params*,NODE*);
@@ -335,11 +333,12 @@
static void void_stmts_gen(struct parser_params*,NODE*);
#define void_stmts(node) void_stmts_gen(parser, node)
static void reduce_nodes(NODE**);
-static void block_dup_check(NODE*);
+static void block_dup_check(NODE*,NODE*);
static NODE *block_append(NODE*,NODE*);
static NODE *list_append(NODE*,NODE*);
static NODE *list_concat(NODE*,NODE*);
+static NODE *arg_append(NODE*,NODE*);
static NODE *arg_concat(NODE*,NODE*);
static NODE *literal_concat(NODE*,NODE*);
static NODE *new_evstr(NODE*);
@@ -348,18 +347,14 @@
static NODE *call_op_gen(struct parser_params*,NODE*,ID,int,NODE*);
#define call_op(recv,id,narg,arg1) call_op_gen(parser, recv,id,narg,arg1)
-static NODE *new_args_gen(struct parser_params*,VALUE,NODE*,NODE*,NODE*);
-#define new_args(f,o,r,b) new_args_gen(parser, f,o,r,b)
+static NODE *new_args_gen(struct parser_params*,VALUE,NODE*,NODE*,NODE*,NODE*);
+#define new_args(f,o,r,p,b) new_args_gen(parser, f,o,r,p,b)
static void shadowing_lvar_gen(struct parser_params*,ID);
#define shadowing_lvar(name) shadowing_lvar_gen(parser, name)
static NODE *negate_lit(NODE*);
static NODE *ret_args(NODE*);
static NODE *arg_blk_pass(NODE*,NODE*);
-static NODE *new_call(NODE*,ID,NODE*);
-static NODE *new_fcall_gen(struct parser_params*,ID,NODE*);
-#define new_fcall(id,args) new_fcall_gen(parser, id, args)
-static NODE *new_super(NODE*);
static NODE *new_yield(NODE*);
static NODE *gettable_gen(struct parser_params*,ID);
@@ -413,6 +408,7 @@
static int dvar_curr_gen(struct parser_params*,ID);
#define dvar_curr(id) dvar_curr_gen(parser, id)
+
static void top_local_init_gen(struct parser_params*);
#define top_local_init() top_local_init_gen(parser)
static void top_local_setup_gen(struct parser_params*);
@@ -620,15 +616,17 @@
%type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
%type <node> expr_value arg_value primary_value
%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
-%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args
+%type <node> args call_args call_args2 opt_call_args
+%type <node> open_args paren_args opt_paren_args
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <node> mrhs superclass block_call block_command
-%type <node> f_arglist f_args f_rest_arg f_optarg f_opt f_block_arg opt_f_block_arg
-%type <node> assoc_list assocs assoc undef_list backref string_dvar
-%type <node> for_var block_param opt_block_param block_param_def block_param0
-%type <node> opt_bv_decl bv_decls bv_decl lambda f_larglist lambda_body
+%type <node> f_arglist f_args f_rest_arg f_post_arg
+%type <node> f_optarg f_opt f_block_arg opt_f_block_arg
+%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
+%type <node> block_param opt_block_param block_param_def bparam_list bparam_item
+%type <node> opt_bv_decl bv_decls bvar lambda f_larglist lambda_body
%type <node> brace_block cmd_brace_block do_block lhs none fitem
-%type <node> mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node
+%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post
%type <id> fsym variable sym symbol operation operation2 operation3
%type <id> cname fname op f_norm_arg
%type <val> f_arg
@@ -663,7 +661,6 @@
%token tSTAR /* * */
%token tAMPER /* & */
%token tLAMBDA /* -> */
-%token tLAMBDA_ARG /* -> */
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
%token tSTRING_DBEG tSTRING_DVAR tSTRING_END tLAMBEG
@@ -942,16 +939,12 @@
}
| keyword_END '{' compstmt '}'
{
- /*%%%*/
if (in_def || in_single) {
- rb_warn("END in method; use at_exit");
- }
-
- $$ = NEW_ITER(0, NEW_POSTEXE(), $3);
- /*%
- if (in_def || in_single) {
rb_warn0("END in method; use at_exit");
}
+ /*%%%*/
+ $$ = NEW_POSTEXE($3);
+ /*%
$$ = dispatch1(END, $3);
%*/
}
@@ -1002,17 +995,13 @@
$$ = dispatch3(opassign, $1, $2, $3);
%*/
}
- | primary_value '[' aref_args ']' tOP_ASGN command_call
+ | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
{
/*%%%*/
- NODE *args;
+ NODE *args = $3;
value_expr($6);
- args = NEW_LIST($6);
- if ($3 && nd_type($3) != NODE_ARRAY)
- $3 = NEW_LIST($3);
- $3 = list_append($3, NEW_NIL());
- list_concat(args, $3);
+ args = arg_concat($6, $3);
if ($5 == tOROP) {
$5 = 0;
}
@@ -1090,7 +1079,7 @@
| lhs '=' mrhs
{
/*%%%*/
- $$ = node_assign($1, NEW_SVALUE($3));
+ $$ = node_assign($1, $3);
/*%
$$ = dispatch2(assign, $1, $3);
%*/
@@ -1098,7 +1087,7 @@
| mlhs '=' arg_value
{
/*%%%*/
- $1->nd_value = ($1->nd_head) ? NEW_TO_ARY($3) : NEW_ARRAY($3);
+ $1->nd_value = $3;
$$ = $1;
/*%
dispatch2(massign, $1, $3);
@@ -1195,7 +1184,7 @@
| block_call '.' operation2 command_args
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
/*%
$$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
$$ = method_arg($$, $4);
@@ -1204,7 +1193,7 @@
| block_call tCOLON2 operation2 command_args
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
/*%
$$ = dispatch3(call, $1, ripper_intern("::"), $3);
$$ = method_arg($$, $4);
@@ -1216,7 +1205,7 @@
{
/*%%%*/
$<num>$ = dyna_push();
- $<num>1 = ruby_sourceline;
+ $<num>$ = ruby_sourceline;
/*%
%*/
}
@@ -1239,7 +1228,7 @@
command : operation command_args %prec tLOWEST
{
/*%%%*/
- $$ = new_fcall($1, $2);
+ $$ = NEW_FCALL($1, $2);
fixpos($$, $2);
/*%
$$ = dispatch2(command, $1, $2);
@@ -1248,12 +1237,8 @@
| operation command_args cmd_brace_block
{
/*%%%*/
- $$ = new_fcall($1, $2);
- if ($3) {
- block_dup_check($$);
- $3->nd_iter = $$;
- $$ = $3;
- }
+ $$ = NEW_FCALL($1, $2);
+ block_dup_check($2,$3);
fixpos($$, $2);
/*%
$$ = dispatch2(command, $1, $2);
@@ -1263,7 +1248,7 @@
| primary_value '.' operation2 command_args %prec tLOWEST
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
fixpos($$, $1);
/*%
$$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
@@ -1272,12 +1257,8 @@
| primary_value '.' operation2 command_args cmd_brace_block
{
/*%%%*/
- $$ = new_call($1, $3, $4);
- if ($5) {
- block_dup_check($$);
- $5->nd_iter = $$;
- $$ = $5;
- }
+ $$ = NEW_CALL($1, $3, $4);
+ block_dup_check($4,$5);
fixpos($$, $1);
/*%
$$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
@@ -1287,7 +1268,7 @@
| primary_value tCOLON2 operation2 command_args %prec tLOWEST
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
fixpos($$, $1);
/*%
$$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
@@ -1296,12 +1277,8 @@
| primary_value tCOLON2 operation2 command_args cmd_brace_block
{
/*%%%*/
- $$ = new_call($1, $3, $4);
- if ($5) {
- block_dup_check($$);
- $5->nd_iter = $$;
- $$ = $5;
- }
+ $$ = NEW_CALL($1, $3, $4);
+ block_dup_check($4,$5);
fixpos($$, $1);
/*%
$$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
@@ -1311,7 +1288,7 @@
| keyword_super command_args
{
/*%%%*/
- $$ = new_super($2);
+ $$ = NEW_SUPER($2);
fixpos($$, $2);
/*%
$$ = dispatch1(super, $2);
@@ -1329,20 +1306,9 @@
;
mlhs : mlhs_basic
- | tLPAREN mlhs_entry rparen
+ | tLPAREN mlhs rparen
{
/*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(mlhs_paren, $2);
- %*/
- }
- ;
-
-mlhs_entry : mlhs_basic
- | tLPAREN mlhs_entry rparen
- {
- /*%%%*/
$$ = NEW_MASGN(NEW_LIST($2), 0);
/*%
$$ = dispatch1(mlhs_paren, $2);
@@ -1374,6 +1340,14 @@
$$ = mlhs_add_star($1, $3);
%*/
}
+ | mlhs_head tSTAR mlhs_node ',' mlhs_post
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
+ /*%
+ $$ = mlhs_add_star($1, $3);
+ %*/
+ }
| mlhs_head tSTAR
{
/*%%%*/
@@ -1382,6 +1356,14 @@
$$ = mlhs_add_star($1, Qnil);
%*/
}
+ | mlhs_head tSTAR ',' mlhs_post
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, NEW_POSTARG(-1,$4));
+ /*%
+ $$ = mlhs_add_star($1, Qnil);
+ %*/
+ }
| tSTAR mlhs_node
{
/*%%%*/
@@ -1390,6 +1372,14 @@
$$ = mlhs_add_star(mlhs_new(), $2);
%*/
}
+ | tSTAR mlhs_node ',' mlhs_post
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
+ /*%
+ $$ = mlhs_add_star(mlhs_new(), $2);
+ %*/
+ }
| tSTAR
{
/*%%%*/
@@ -1398,10 +1388,18 @@
$$ = mlhs_add_star(mlhs_new(), Qnil);
%*/
}
+ | tSTAR ',' mlhs_head
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, NEW_POSTARG(-1,$3));
+ /*%
+ $$ = mlhs_add_star(mlhs_new(), Qnil);
+ %*/
+ }
;
mlhs_item : mlhs_node
- | tLPAREN mlhs_entry rparen
+ | tLPAREN mlhs rparen
{
/*%%%*/
$$ = $2;
@@ -1429,6 +1427,24 @@
}
;
+mlhs_post : mlhs_item
+ {
+ /*%%%*/
+ $$ = NEW_LIST($1);
+ /*%
+ $$ = mlhs_add(mlhs_new(), $1);
+ %*/
+ }
+ | mlhs_post ',' mlhs_item
+ {
+ /*%%%*/
+ $$ = list_append($1, $3);
+ /*%
+ $$ = mlhs_add($1, $3);
+ %*/
+ }
+ ;
+
mlhs_node : variable
{
/*%%%*/
@@ -1437,7 +1453,7 @@
$$ = $1;
%*/
}
- | primary_value '[' aref_args ']'
+ | primary_value '[' opt_call_args rbracket
{
/*%%%*/
$$ = aryset($1, $3);
@@ -1511,7 +1527,7 @@
$$ = dispatch1(var_field, $1);
%*/
}
- | primary_value '[' aref_args ']'
+ | primary_value '[' opt_call_args rbracket
{
/*%%%*/
$$ = aryset($1, $3);
@@ -1704,12 +1720,16 @@
;
reswords : keyword__LINE__ | keyword__FILE__ | keyword_BEGIN | keyword_END
- | keyword_alias | keyword_and | keyword_begin | keyword_break | keyword_case | keyword_class | keyword_def
- | keyword_defined | keyword_do | keyword_else | keyword_elsif | keyword_end | keyword_ensure | keyword_false
- | keyword_for | keyword_in | keyword_module | keyword_next | keyword_nil | keyword_not
- | keyword_or | keyword_redo | keyword_rescue | keyword_retry | keyword_return | keyword_self | keyword_super
- | keyword_then | keyword_true | keyword_undef | keyword_when | keyword_yield
- | modifier_if | modifier_unless | modifier_while | modifier_until | modifier_rescue
+ | keyword_alias | keyword_and | keyword_begin
+ | keyword_break | keyword_case | keyword_class | keyword_def
+ | keyword_defined | keyword_do | keyword_else | keyword_elsif
+ | keyword_end | keyword_ensure | keyword_false
+ | keyword_for | keyword_in | keyword_module | keyword_next
+ | keyword_nil | keyword_not | keyword_or | keyword_redo
+ | keyword_rescue | keyword_retry | keyword_return | keyword_self
+ | keyword_super | keyword_then | keyword_true | keyword_undef
+ | keyword_when | keyword_yield | keyword_if | keyword_unless
+ | keyword_while | keyword_until
;
arg : lhs '=' arg
@@ -1757,17 +1777,13 @@
$$ = dispatch3(opassign, $1, $2, $3);
%*/
}
- | primary_value '[' aref_args ']' tOP_ASGN arg
+ | primary_value '[' opt_call_args rbracket tOP_ASGN arg
{
/*%%%*/
NODE *args;
value_expr($6);
- args = NEW_LIST($6);
- if ($3 && nd_type($3) != NODE_ARRAY)
- $3 = NEW_LIST($3);
- $3 = list_append($3, NEW_NIL());
- list_concat(args, $3);
+ args = arg_concat($6, $3);
if ($5 == tOROP) {
$5 = 0;
}
@@ -2148,13 +2164,13 @@
$$ = dispatch1(defined, $4);
%*/
}
- | arg '?' arg ':' arg
+ | arg '?' arg opt_nl ':' arg
{
/*%%%*/
- $$ = NEW_IF(cond($1), $3, $5);
+ $$ = NEW_IF(cond($1), $3, $6);
fixpos($$, $1);
/*%
- $$ = dispatch3(ifop, $1, $3, $5);
+ $$ = dispatch3(ifop, $1, $3, $6);
%*/
}
| primary
@@ -2175,27 +2191,16 @@
;
aref_args : none
- | command opt_nl
- {
- /*%%%*/
- rb_warn("parenthesize argument(s) for future version");
- $$ = NEW_LIST($1);
- /*%
- rb_warn0("parenthesize argument(s) for future version");
- $$ = arg_add(arg_new(), $1);
- %*/
- }
| args trailer
{
$$ = $1;
}
- | args ',' tSTAR arg opt_nl
+ | args ',' assocs trailer
{
/*%%%*/
- value_expr($4);
- $$ = arg_concat($1, $4);
+ $$ = list_append($1, NEW_HASH($3));
/*%
- $$ = arg_add_star($1, $4);
+ $$ = arg_add_assocs($1, $3);
%*/
}
| assocs trailer
@@ -2206,66 +2211,32 @@
$$ = arg_add_assocs(arg_new(), $1);
%*/
}
- | tSTAR arg opt_nl
- {
- /*%%%*/
- value_expr($2);
- $$ = newline_node(NEW_SPLAT($2));
- /*%
- $$ = arg_add_star(arg_new(), $2);
- %*/
- }
;
-paren_args : '(' none ')'
+paren_args : '(' opt_call_args rparen
{
/*%%%*/
$$ = $2;
/*%
- $$ = dispatch1(arg_paren, arg_new());
+ $$ = dispatch1(arg_paren, escape_Qundef($2));
%*/
}
- | '(' call_args rparen
- {
- /*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(arg_paren, $2);
- %*/
- }
- | '(' block_call rparen
- {
- /*%%%*/
- rb_warn("parenthesize argument for future version");
- $$ = NEW_LIST($2);
- /*%
- rb_warn0("parenthesize argument for future version");
- $$ = dispatch1(arg_paren, arg_add(arg_new(), $2));
- %*/
- }
- | '(' args ',' block_call rparen
- {
- /*%%%*/
- rb_warn("parenthesize argument for future version");
- $$ = list_append($2, $4);
- /*%
- rb_warn0("parenthesize argument for future version");
- $$ = dispatch1(arg_paren, arg_add($2, $4));
- %*/
- }
;
opt_paren_args : none
| paren_args
;
+opt_call_args : none
+ | call_args
+ ;
+
call_args : command
{
- /*%%%*/
rb_warn("parenthesize argument(s) for future version");
+ /*%%%*/
$$ = NEW_LIST($1);
/*%
- rb_warn0("parenthesize argument(s) for future version");
$$ = arg_add(arg_new(), $1);
%*/
}
@@ -2277,15 +2248,6 @@
$$ = arg_add_optblock($1, $2);
%*/
}
- | args ',' tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_concat($1, $4);
- $$ = arg_blk_pass($$, $5);
- /*%
- arg_add_optblock(arg_add_star($1, $4), $5);
- %*/
- }
| assocs opt_block_arg
{
/*%%%*/
@@ -2296,44 +2258,15 @@
$$ = arg_add_optblock($$, $2);
%*/
}
- | assocs ',' tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_concat(NEW_LIST(NEW_HASH($1)), $4);
- $$ = arg_blk_pass($$, $5);
- /*%
- $$ = arg_add_star(arg_add_assocs(arg_new(), $1), $4);
- $$ = arg_add_optblock($$, $5);
- %*/
- }
| args ',' assocs opt_block_arg
{
/*%%%*/
- $$ = list_append($1, NEW_HASH($3));
+ $$ = arg_append($1, NEW_HASH($3));
$$ = arg_blk_pass($$, $4);
/*%
$$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
%*/
}
- | args ',' assocs ',' tSTAR arg opt_block_arg
- {
- /*%%%*/
- value_expr($6);
- $$ = arg_concat(list_append($1, NEW_HASH($3)), $6);
- $$ = arg_blk_pass($$, $7);
- /*%
- $$ = arg_add_star(arg_add_assocs($1, $3), $6);
- $$ = arg_add_optblock($$, $7);
- %*/
- }
- | tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_blk_pass(NEW_SPLAT($2), $3);
- /*%
- $$ = arg_add_optblock(arg_add_star(arg_new(), $2), $3);
- %*/
- }
| block_arg
/*%c%*/
/*%c
@@ -2359,26 +2292,6 @@
$$ = arg_add_block(arg_add(arg_new(), $1), $3);
%*/
}
- | arg_value ',' tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_concat(NEW_LIST($1), $4);
- $$ = arg_blk_pass($$, $5);
- /*%
- $$ = arg_add_star(arg_add(arg_new(), $1), $4);
- $$ = arg_add_optblock($$, $5);
- %*/
- }
- | arg_value ',' args ',' tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_concat(list_concat(NEW_LIST($1),$3), $6);
- $$ = arg_blk_pass($$, $7);
- /*%
- $$ = arg_add_star(arg_prepend($3, $1), $6);
- $$ = arg_add_optblock($$, $7);
- %*/
- }
| assocs opt_block_arg
{
/*%%%*/
@@ -2388,20 +2301,10 @@
$$ = arg_add_optblock(arg_add_assocs(arg_new(), $1), $2);
%*/
}
- | assocs ',' tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_concat(NEW_LIST(NEW_HASH($1)), $4);
- $$ = arg_blk_pass($$, $5);
- /*%
- $$ = arg_add_star(arg_add_assocs(arg_new(), $1), $4);
- $$ = arg_add_optblock($$, $4);
- %*/
- }
| arg_value ',' assocs opt_block_arg
{
/*%%%*/
- $$ = list_append(NEW_LIST($1), NEW_HASH($3));
+ $$ = arg_append(NEW_LIST($1), NEW_HASH($3));
$$ = arg_blk_pass($$, $4);
/*%
$$ = arg_add_assocs(arg_add(arg_new(), $1), $3);
@@ -2411,43 +2314,13 @@
| arg_value ',' args ',' assocs opt_block_arg
{
/*%%%*/
- $$ = list_append(list_concat(NEW_LIST($1),$3), NEW_HASH($5));
+ $$ = arg_append(list_concat(NEW_LIST($1),$3), NEW_HASH($5));
$$ = arg_blk_pass($$, $6);
/*%
$$ = arg_add_assocs(arg_prepend($3, $1), $5);
$$ = arg_add_optblock($$, $6);
%*/
}
- | arg_value ',' assocs ',' tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_concat(list_append(NEW_LIST($1), NEW_HASH($3)), $6);
- $$ = arg_blk_pass($$, $7);
- /*%
- $$ = arg_add_assocs(arg_add(arg_new(), $1), $3);
- $$ = arg_add_star($$, $6);
- $$ = arg_add_optblock($$, $7);
- %*/
- }
- | arg_value ',' args ',' assocs ',' tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_concat(list_append(list_concat(NEW_LIST($1), $3), NEW_HASH($5)), $8);
- $$ = arg_blk_pass($$, $9);
- /*%
- $$ = arg_add_assocs(arg_prepend($3, $1), $5);
- $$ = arg_add_star($$, $8);
- $$ = arg_add_optblock($$, $9);
- %*/
- }
- | tSTAR arg_value opt_block_arg
- {
- /*%%%*/
- $$ = arg_blk_pass(NEW_SPLAT($2), $3);
- /*%
- $$ = arg_add_optblock(arg_add_star(arg_new(), $2), $3);
- %*/
- }
| block_arg
;
@@ -2509,14 +2382,30 @@
$$ = arg_add(arg_new(), $1);
%*/
}
+ | tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = NEW_SPLAT($2);
+ /*%
+ $$ = arg_add_star(arg_new(), $2);
+ %*/
+ }
| args ',' arg_value
{
/*%%%*/
- $$ = list_append($1, $3);
+ $$ = arg_append($1, $3);
/*%
$$ = arg_add($1, $3);
%*/
}
+ | args ',' tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = arg_concat($1, $4);
+ /*%
+ $$ = arg_add_star($1, $4);
+ %*/
+ }
;
mrhs : args ',' arg_value
@@ -2698,7 +2587,7 @@
| method_call brace_block
{
/*%%%*/
- block_dup_check($$);
+ block_dup_check($1->nd_args, $2);
$2->nd_iter = $1;
$$ = $2;
fixpos($$, $1);
@@ -2783,30 +2672,14 @@
$$ = dispatch2(case, $2, $4);
%*/
}
- | keyword_case expr_value opt_terms keyword_else compstmt keyword_end
- {
- /*%%%*/
- $$ = block_append($2, $5);
- /*%
- $$ = dispatch2(case, $2, dispatch1(else, $5));
- %*/
- }
| keyword_case opt_terms case_body keyword_end
{
/*%%%*/
- $$ = $3;
+ $$ = NEW_CASE(0, $3);
/*%
$$ = dispatch2(case, Qnil, $3);
%*/
}
- | keyword_case opt_terms keyword_else compstmt keyword_end
- {
- /*%%%*/
- $$ = $4;
- /*%
- $$ = dispatch2(case, Qnil, dispatch1(else, $4));
- %*/
- }
| keyword_for for_var keyword_in {COND_PUSH(1);} expr_value do {COND_POP();}
compstmt
keyword_end
@@ -3007,11 +2880,6 @@
/*%c
{ $$ = Qnil; }
%*/
- | ':'
- /*%c%*/
- /*%c
- { $$ = Qnil; }
- %*/
| keyword_then
| term keyword_then
/*%c%*/
@@ -3025,11 +2893,6 @@
/*%c
{ $$ = Qnil; }
%*/
- | ':'
- /*%c%*/
- /*%c
- { $$ = Qnil; }
- %*/
| keyword_do_cond
;
@@ -3062,15 +2925,31 @@
| mlhs
;
-block_param0 : mlhs_item
+bparam_item : bvar
+ | tLPAREN block_param rparen
{
/*%%%*/
+ if (nd_type($2) != NODE_MASGN) {
+ $$ = NEW_MASGN(NEW_LIST($2), 0);
+ }
+ else {
+ $$ = $2;
+ }
+ /*%
+ $$ = dispatch1(mlhs_paren, $2);
+ %*/
+ }
+ ;
+
+bparam_list : bparam_item
+ {
+ /*%%%*/
$$ = NEW_LIST($1);
/*%
$$ = mlhs_add(mlhs_new(), $1);
%*/
}
- | block_param0 ',' mlhs_item
+ | bparam_list ',' bparam_item
{
/*%%%*/
$$ = list_append($1, $3);
@@ -3080,10 +2959,10 @@
}
;
-block_param : block_param0
+block_param : bparam_list
{
/*%%%*/
- if ($1->nd_alen == 1) {
+ if ($1->nd_alen == 1 && nd_type($1->nd_head) != NODE_MASGN) {
$$ = $1->nd_head;
rb_gc_force_recycle((VALUE)$1);
}
@@ -3094,7 +2973,7 @@
$$ = blockvar_new($1);
%*/
}
- | block_param0 ','
+ | bparam_list ','
{
/*%%%*/
$$ = NEW_MASGN($1, 0);
@@ -3102,7 +2981,7 @@
$$ = blockvar_new($1);
%*/
}
- | block_param0 ',' tAMPER lhs
+ | bparam_list ',' tAMPER bvar
{
/*%%%*/
$$ = NEW_BLOCK_PARAM($4, NEW_MASGN($1, 0));
@@ -3110,16 +2989,25 @@
$$ = blockvar_add_block(blockvar_new($1), $4);
%*/
}
- | block_param0 ',' tSTAR lhs ',' tAMPER lhs
+ | bparam_list ',' tSTAR bvar ',' bparam_list ',' tAMPER bvar
{
/*%%%*/
+ $$ = NEW_BLOCK_PARAM($9, NEW_MASGN($1, NEW_POSTARG($4,$6)));
+ /*%
+ $$ = blockvar_add_star(blockvar_new($1), $4);
+ $$ = blockvar_add_block($$, $9);
+ %*/
+ }
+ | bparam_list ',' tSTAR bvar ',' tAMPER bvar
+ {
+ /*%%%*/
$$ = NEW_BLOCK_PARAM($7, NEW_MASGN($1, $4));
/*%
$$ = blockvar_add_star(blockvar_new($1), $4);
$$ = blockvar_add_block($$, $7);
%*/
}
- | block_param0 ',' tSTAR ',' tAMPER lhs
+ | bparam_list ',' tSTAR ',' tAMPER bvar
{
/*%%%*/
$$ = NEW_BLOCK_PARAM($6, NEW_MASGN($1, -1));
@@ -3128,32 +3016,57 @@
$$ = blockvar_add_block($$, $6);
%*/
}
- | block_param0 ',' tSTAR lhs
+ | bparam_list ',' tSTAR ',' bparam_list ',' tAMPER bvar
{
/*%%%*/
+ $$ = NEW_BLOCK_PARAM($8, NEW_MASGN($1, NEW_POSTARG(-1,$5)));
+ /*%
+ $$ = blockvar_add_star(blockvar_new($1), Qnil);
+ $$ = blockvar_add_block($$, $8);
+ %*/
+ }
+ | bparam_list ',' tSTAR bvar
+ {
+ /*%%%*/
$$ = NEW_MASGN($1, $4);
/*%
$$ = blockvar_add_star(blockvar_new($1), $4);
%*/
}
- | block_param0 ',' tSTAR
+ | bparam_list ',' tSTAR bvar ',' bparam_list
{
/*%%%*/
+ $$ = NEW_MASGN($1, NEW_POSTARG($4,$6));
+ /*%
+ $$ = blockvar_add_star(blockvar_new($1), $4);
+ %*/
+ }
+ | bparam_list ',' tSTAR
+ {
+ /*%%%*/
$$ = NEW_MASGN($1, -1);
/*%
$$ = blockvar_add_star(blockvar_new($1), Qnil);
%*/
}
- | tSTAR lhs ',' tAMPER lhs
+ | bparam_list ',' tSTAR ',' bparam_list
{
/*%%%*/
+ $$ = NEW_MASGN($1, NEW_MASGN($1, NEW_POSTARG(-1,$5)));
+ /*%
+ $$ = blockvar_add_star(blockvar_new($1), Qnil);
+ %*/
+ }
+ | tSTAR bvar ',' tAMPER bvar
+ {
+ /*%%%*/
$$ = NEW_BLOCK_PARAM($5, NEW_MASGN(0, $2));
/*%
$$ = blockvar_add_star(blockvar_new(Qnil), $2);
$$ = blockvar_add_block($$, $5);
%*/
}
- | tSTAR ',' tAMPER lhs
+ | tSTAR ',' tAMPER bvar
{
/*%%%*/
$$ = NEW_BLOCK_PARAM($4, NEW_MASGN(0, -1));
@@ -3162,7 +3075,7 @@
$$ = blockvar_add_block($$, $4);
%*/
}
- | tSTAR lhs
+ | tSTAR bvar
{
/*%%%*/
$$ = NEW_MASGN(0, $2);
@@ -3170,6 +3083,23 @@
$$ = blockvar_add_star(blockvar_new(Qnil), $2);
%*/
}
+ | tSTAR bvar ',' bparam_list
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
+ /*%
+ $$ = blockvar_add_star(blockvar_new(Qnil), $2);
+ %*/
+ }
+ | tSTAR bvar ',' bparam_list ',' tAMPER bvar
+ {
+ /*%%%*/
+ $$ = NEW_BLOCK_PARAM($7, NEW_MASGN(0, NEW_POSTARG($2,$4)));
+ /*%
+ $$ = blockvar_add_star(blockvar_new(Qnil), Qnil);
+ $$ = blockvar_add_block($$, $7);
+ %*/
+ }
| tSTAR
{
/*%%%*/
@@ -3178,9 +3108,26 @@
$$ = blockvar_add_star(blockvar_new(Qnil), Qnil);
%*/
}
- | tAMPER lhs
+ | tSTAR ',' bparam_list
{
/*%%%*/
+ $$ = NEW_MASGN(0, NEW_POSTARG(-1,$3));
+ /*%
+ $$ = blockvar_add_star(blockvar_new(Qnil), Qnil);
+ %*/
+ }
+ | tSTAR ',' bparam_list ',' tAMPER bvar
+ {
+ /*%%%*/
+ $$ = NEW_BLOCK_PARAM($6, NEW_MASGN(0, NEW_POSTARG(-1,$3)));
+ /*%
+ $$ = blockvar_add_star(blockvar_new(Qnil), Qnil);
+ $$ = blockvar_add_block($$, $6);
+ %*/
+ }
+ | tAMPER bvar
+ {
+ /*%%%*/
$$ = NEW_BLOCK_PARAM($2, (NODE*)1);
/*%
$$ = blockvar_add_block(blockvar_new(Qnil), $2);
@@ -3236,7 +3183,7 @@
}
;
-bv_decls : bv_decl
+bv_decls : bvar
{
/*%%%*/
$$ = $1;
@@ -3244,7 +3191,7 @@
$$ = FIXME;
%*/
}
- | bv_decls ',' bv_decl
+ | bv_decls ',' bvar
{
/*%%%*/
$$ = block_append($1, $3);
@@ -3254,7 +3201,7 @@
}
;
-bv_decl : tIDENTIFIER
+bvar : tIDENTIFIER
{
/*%%%*/
$$ = new_bv($1, NEW_NIL());
@@ -3350,7 +3297,7 @@
block_call : command do_block
{
/*%%%*/
- block_dup_check($1);
+ block_dup_check($1->nd_args, $2);
$2->nd_iter = $1;
$$ = $2;
fixpos($$, $1);
@@ -3361,7 +3308,7 @@
| block_call '.' operation2 opt_paren_args
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
/*%
$$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
$$ = method_optarg($$, $4);
@@ -3370,7 +3317,7 @@
| block_call tCOLON2 operation2 opt_paren_args
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
/*%
$$ = dispatch3(call, $1, ripper_intern("::"), $3);
$$ = method_optarg($$, $4);
@@ -3381,7 +3328,7 @@
method_call : operation paren_args
{
/*%%%*/
- $$ = new_fcall($1, $2);
+ $$ = NEW_FCALL($1, $2);
fixpos($$, $2);
/*%
$$ = method_arg(dispatch1(fcall, $1), $2);
@@ -3390,7 +3337,7 @@
| primary_value '.' operation2 opt_paren_args
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
fixpos($$, $1);
/*%
$$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
@@ -3400,7 +3347,7 @@
| primary_value tCOLON2 operation2 paren_args
{
/*%%%*/
- $$ = new_call($1, $3, $4);
+ $$ = NEW_CALL($1, $3, $4);
fixpos($$, $1);
/*%
$$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
@@ -3410,42 +3357,52 @@
| primary_value tCOLON2 operation3
{
/*%%%*/
- $$ = new_call($1, $3, 0);
+ $$ = NEW_CALL($1, $3, 0);
/*%
$$ = dispatch3(call, $1, ripper_intern("::"), $3);
%*/
}
- | keyword_super paren_args
+ | primary_value '.' paren_args
{
/*%%%*/
- $$ = new_super($2);
+ $$ = NEW_CALL($1, rb_intern("call"), $3);
+ fixpos($$, $1);
/*%
- $$ = dispatch1(super, $2);
+ $$ = dispatch3(call, dispatch1(paren, $1),
+ ripper_id2sym('.'), rb_intern("call"));
+ $$ = method_optarg($$, $3);
%*/
}
- | keyword_super
+ | primary_value tCOLON2 paren_args
{
/*%%%*/
- $$ = NEW_ZSUPER();
+ $$ = NEW_CALL($1, rb_intern("call"), $3);
+ fixpos($$, $1);
/*%
- $$ = dispatch0(zsuper);
+ $$ = dispatch3(call, dispatch1(paren, $1),
+ ripper_id2sym('.'), rb_intern("call"));
+ $$ = method_optarg($$, $3);
%*/
}
- | tLPAREN compstmt ')' paren_args
+ | keyword_super paren_args
{
/*%%%*/
- if (!$2) $2 = NEW_NIL();
- $$ = new_call($2, rb_intern("call"), $4);
- fixpos($$, $2);
+ $$ = NEW_SUPER($2);
/*%
- $$ = dispatch3(call, dispatch1(paren, $2),
- ripper_id2sym('.'), rb_intern("call"));
- $$ = method_optarg($$, $4);
+ $$ = dispatch1(super, $2);
%*/
}
- | primary_value '[' aref_args ']'
+ | keyword_super
{
/*%%%*/
+ $$ = NEW_ZSUPER();
+ /*%
+ $$ = dispatch0(zsuper);
+ %*/
+ }
+ | primary_value '[' opt_call_args rbracket
+ {
+ /*%%%*/
if ($1 && nd_type($1) == NODE_SELF)
$$ = NEW_FCALL(tAREF, $3);
else
@@ -3509,19 +3466,9 @@
$$ = dispatch2(do_block, escape_Qundef($3), $5);
%*/
}
- | tLAMBDA_ARG
- lambda
- {
- /*%%%*/
- $$ = $2;
- nd_set_type($$, NODE_ITER);
- /*%
- $$ = dispatch2(do_block, Qnil, $2);
- %*/
- }
;
-case_body : keyword_when when_args then
+case_body : keyword_when args then
compstmt
cases
{
@@ -3532,24 +3479,6 @@
%*/
}
;
-when_args : args
- | args ',' tSTAR arg_value
- {
- /*%%%*/
- $$ = list_append($1, NEW_WHEN($4, 0, 0));
- /*%
- $$ = arg_add_star($1, $4);
- %*/
- }
- | tSTAR arg_value
- {
- /*%%%*/
- $$ = NEW_LIST(NEW_WHEN($2, 0, 0));
- /*%
- $$ = arg_add_star(arg_new(), $2);
- %*/
- }
- ;
cases : opt_else
| case_body
@@ -3932,12 +3861,19 @@
yyerror("empty symbol literal");
}
else {
+ VALUE lit;
+
switch (nd_type($$)) {
case NODE_DSTR:
nd_set_type($$, NODE_DSYM);
break;
case NODE_STR:
- if (strlen(RSTRING_PTR($$->nd_lit)) == RSTRING_LEN($$->nd_lit)) {
+ lit = $$->nd_lit;
+ if (RSTRING_LEN(lit) == 0) {
+ yyerror("empty symbol literal");
+ break;
+ }
+ if (strlen(RSTRING_PTR(lit)) == RSTRING_LEN(lit)) {
$$->nd_lit = ID2SYM(rb_intern(RSTRING_PTR($$->nd_lit)));
nd_set_type($$, NODE_LIT);
break;
@@ -4061,73 +3997,121 @@
f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
{
/*%%%*/
- $$ = new_args($1, $3, $5, $6);
+ $$ = new_args($1, $3, $5, 0, $6);
/*%
- $$ = dispatch4(params, $1, $3, $5, escape_Qundef($6));
+ $$ = dispatch5(params, $1, $3, $5, Qnil, escape_Qundef($6));
%*/
}
+ | f_arg ',' f_optarg ',' f_rest_arg ',' f_post_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args($1, $3, $5, $7, $8);
+ /*%
+ $$ = dispatch5(params, $1, $3, $5, $7, escape_Qundef($8));
+ %*/
+ }
| f_arg ',' f_optarg opt_f_block_arg
{
/*%%%*/
- $$ = new_args($1, $3, 0, $4);
+ $$ = new_args($1, $3, 0, 0, $4);
/*%
- $$ = dispatch4(params, $1, $3, Qnil, escape_Qundef($4));
+ $$ = dispatch5(params, $1, $3, Qnil, Qnil, escape_Qundef($4));
%*/
}
+ | f_arg ',' f_optarg ',' f_post_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args($1, $3, 0, $5, $6);
+ /*%
+ $$ = dispatch5(params, $1, $3, Qnil, $5, escape_Qundef($6));
+ %*/
+ }
| f_arg ',' f_rest_arg opt_f_block_arg
{
/*%%%*/
- $$ = new_args($1, 0, $3, $4);
+ $$ = new_args($1, 0, $3, 0, $4);
/*%
- $$ = dispatch4(params, $1, Qnil, $3, escape_Qundef($4));
+ $$ = dispatch5(params, $1, Qnil, $3, Qnil, escape_Qundef($4));
%*/
}
+ | f_arg ',' f_rest_arg ',' f_post_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args($1, 0, $3, $5, $6);
+ /*%
+ $$ = dispatch5(params, $1, Qnil, $3, $5, escape_Qundef($6));
+ %*/
+ }
| f_arg opt_f_block_arg
{
/*%%%*/
- $$ = new_args($1, 0, 0, $2);
+ $$ = new_args($1, 0, 0, 0, $2);
/*%
- $$ = dispatch4(params, $1, Qnil, Qnil, escape_Qundef($2));
+ $$ = dispatch5(params, $1, Qnil, Qnil, Qnil, escape_Qundef($2));
%*/
}
| f_optarg ',' f_rest_arg opt_f_block_arg
{
/*%%%*/
- $$ = new_args(0, $1, $3, $4);
+ $$ = new_args(0, $1, $3, 0, $4);
/*%
- $$ = dispatch4(params, Qnil, $1, $3, escape_Qundef($4));
+ $$ = dispatch5(params, Qnil, $1, $3, Qnil, escape_Qundef($4));
%*/
}
+ | f_optarg ',' f_rest_arg ',' f_post_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args(0, $1, $3, $5, $6);
+ /*%
+ $$ = dispatch5(params, Qnil, $1, $3, $5, escape_Qundef($6));
+ %*/
+ }
| f_optarg opt_f_block_arg
{
/*%%%*/
- $$ = new_args(0, $1, 0, $2);
+ $$ = new_args(0, $1, 0, 0, $2);
/*%
- $$ = dispatch4(params, Qnil, $1, Qnil, escape_Qundef($2));
+ $$ = dispatch5(params, Qnil, $1, Qnil, Qnil, escape_Qundef($2));
%*/
}
+ | f_optarg ',' f_post_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args(0, $1, 0, $3, $4);
+ /*%
+ $$ = dispatch5(params, Qnil, $1, Qnil, $3, escape_Qundef($4));
+ %*/
+ }
| f_rest_arg opt_f_block_arg
{
/*%%%*/
- $$ = new_args(0, 0, $1, $2);
+ $$ = new_args(0, 0, $1, 0, $2);
/*%
- $$ = dispatch4(params, Qnil, Qnil, $1, escape_Qundef($2));
+ $$ = dispatch5(params, Qnil, Qnil, $1, Qnil, escape_Qundef($2));
%*/
}
+ | f_rest_arg ',' f_post_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args(0, 0, $1, $3, $4);
+ /*%
+ $$ = dispatch5(params, Qnil, Qnil, $1, $3, escape_Qundef($4));
+ %*/
+ }
| f_block_arg
{
/*%%%*/
- $$ = new_args(0, 0, 0, $1);
+ $$ = new_args(0, 0, 0, 0, $1);
/*%
- $$ = dispatch4(params, Qnil, Qnil, Qnil, $1);
+ $$ = dispatch5(params, Qnil, Qnil, Qnil, Qnil, $1);
%*/
}
| /* none */
{
/*%%%*/
- $$ = new_args(0, 0, 0, 0);
+ $$ = new_args(0, 0, 0, 0, 0);
/*%
- $$ = dispatch4(params, Qnil, Qnil, Qnil, Qnil);
+ $$ = dispatch5(params, Qnil, Qnil, Qnil, Qnil, Qnil);
%*/
}
;
@@ -4198,7 +4182,7 @@
VALUE arg = ID2SYM($3);
$$ = $1;
if (rb_ary_includes($$, arg)) {
- yyerror("duplicated argument arg");
+ yyerror("duplicated argument name");
}
rb_ary_push($$, arg);
/*%
@@ -4207,6 +4191,24 @@
}
;
+f_post_arg : f_norm_arg
+ {
+ /*%%%*/
+ $$ = NEW_LIST(assignable($1, 0));
+ /*%
+ $$ = mlhs_add(mlhs_new(), $1);
+ %*/
+ }
+ | f_post_arg ',' f_norm_arg
+ {
+ /*%%%*/
+ $$ = list_append($1, assignable($3, 0));
+ /*%
+ $$ = mlhs_add($1, $3);
+ %*/
+ }
+ ;
+
f_opt : tIDENTIFIER '=' arg_value
{
/*%%%*/
@@ -4310,13 +4312,8 @@
singleton : var_ref
{
/*%%%*/
- if (nd_type($1) == NODE_SELF) {
- $$ = NEW_SELF();
- }
- else {
$$ = $1;
value_expr($$);
- }
/*%
$$ = $1;
%*/
@@ -4442,6 +4439,9 @@
rparen : opt_nl ')'
;
+rbracket : opt_nl ']'
+ ;
+
trailer : /* none */
| '\n'
| ','
@@ -4531,7 +4531,7 @@
ripper_dispatch_delayed_token(struct parser_params *parser, int t)
{
int saved_line = ruby_sourceline;
- char *saved_tokp = parser->tokp;
+ const char *saved_tokp = parser->tokp;
ruby_sourceline = parser->delayed_line;
parser->tokp = lex_pbeg + parser->delayed_col;
@@ -4562,7 +4562,8 @@
parser_yyerror(struct parser_params *parser, const char *msg)
{
#ifndef RIPPER
- char *p, *pe, *buf;
+ const char *p, *pe;
+ char *buf;
int len, i;
rb_compile_error("%s", msg);
@@ -4581,17 +4582,18 @@
len = pe - p;
if (len > 4) {
+ char *p2;
buf = ALLOCA_N(char, len+2);
MEMCPY(buf, p, char, len);
buf[len] = '\0';
rb_compile_error_append("%s", buf);
i = lex_p - p;
- p = buf; pe = p + len;
+ p2 = buf; pe = buf + len;
- while (p < pe) {
- if (*p != '\t') *p = ' ';
- p++;
+ while (p2 < pe) {
+ if (*p2 != '\t') *p2 = ' ';
+ p2++;
}
buf[i] = '^';
buf[i+1] = '\0';
@@ -4654,8 +4656,6 @@
}
#endif /* !RIPPER */
-static VALUE lex_get_str(struct parser_params *, VALUE);
-
static VALUE
lex_get_str(struct parser_params *parser, VALUE s)
{
@@ -4853,9 +4853,9 @@
}
static void
-parser_tokadd(struct parser_params *parser, char c)
+parser_tokadd(struct parser_params *parser, int c)
{
- tokenbuf[tokidx++] = c;
+ tokenbuf[tokidx++] = (char)c;
if (tokidx >= toksiz) {
toksiz *= 2;
REALLOC_N(tokenbuf, char, toksiz);
@@ -5053,7 +5053,7 @@
int kcode = 0;
int options = 0;
- int c, opt, kc, found;
+ int c, opt, kc;
newtok();
while (c = nextc(), ISALPHA(c)) {
@@ -5241,10 +5241,17 @@
}
pushback(c);
if (tokadd_string(func, term, paren, "e->nd_nest) == -1) {
+ if (func & STR_FUNC_REGEXP) {
+ ruby_sourceline = nd_line(quote);
+ rb_compile_error(PARSER_ARG "unterminated regexp meets end of file");
+ return tREGEXP_END;
+ }
+ else {
ruby_sourceline = nd_line(quote);
rb_compile_error(PARSER_ARG "unterminated string meets end of file");
return tSTRING_END;
}
+ }
tokfix();
set_yylval_str(rb_str_new(tok(), toklen()));
@@ -5351,7 +5358,7 @@
parser_whole_match_p(struct parser_params *parser,
const char *eos, int len, int indent)
{
- char *p = lex_pbeg;
+ const char *p = lex_pbeg;
int n;
if (indent) {
@@ -5367,7 +5374,7 @@
parser_here_document(struct parser_params *parser, NODE *here)
{
int c, func, indent = 0;
- char *eos, *p, *pend;
+ const char *eos, *p, *pend;
long len;
VALUE str = 0;
@@ -5841,7 +5848,6 @@
c = nextc();
if (c == '<' &&
lex_state != EXPR_END &&
- lex_state != EXPR_END2 &&
lex_state != EXPR_DOT &&
lex_state != EXPR_ENDARG &&
lex_state != EXPR_CLASS &&
@@ -5921,7 +5927,6 @@
case '?':
if (lex_state == EXPR_END ||
- lex_state == EXPR_END2 ||
lex_state == EXPR_ENDARG) {
lex_state = EXPR_VALUE;
return '?';
@@ -6095,18 +6100,9 @@
return tOP_ASGN;
}
if (c == '>') {
- enum lex_state_e state = lex_state;
lex_state = EXPR_ARG;
- switch (state) {
- case EXPR_CMDARG:
- case EXPR_ENDARG:
- case EXPR_ARG:
- case EXPR_END:
- return tLAMBDA_ARG;
- default:
return tLAMBDA;
}
- }
if (IS_BEG() ||
(IS_ARG() && space_seen && !ISSPACE(c))) {
if (IS_ARG()) arg_ambiguous();
@@ -6375,7 +6371,7 @@
lex_state = EXPR_DOT;
return tCOLON2;
}
- if (lex_state == EXPR_END || lex_state == EXPR_END2 ||
+ if (lex_state == EXPR_END ||
lex_state == EXPR_ENDARG || ISSPACE(c)) {
pushback(c);
lex_state = EXPR_BEG;
@@ -6437,10 +6433,6 @@
return '^';
case ';':
- if (lex_state != EXPR_END2 && peek(';')) {
- lex_state = EXPR_END2;
- return keyword_end;
- }
lex_state = EXPR_BEG;
command_start = Qtrue;
return ';';
@@ -6514,7 +6506,7 @@
--paren_nest;
return tLAMBEG;
}
- if (IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_END2)
+ if (IS_ARG() || lex_state == EXPR_END)
c = '{'; /* block (primary) */
else if (lex_state == EXPR_ENDARG)
c = tLBRACE_ARG; /* block (expr) */
@@ -6577,13 +6569,13 @@
return tSTRING_BEG;
case 'W':
- lex_strterm = NEW_STRTERM(str_dquote | STR_FUNC_QWORDS, term, paren);
+ lex_strterm = NEW_STRTERM(str_dword, term, paren);
do {c = nextc();} while (ISSPACE(c));
pushback(c);
return tWORDS_BEG;
case 'w':
- lex_strterm = NEW_STRTERM(str_squote | STR_FUNC_QWORDS, term, paren);
+ lex_strterm = NEW_STRTERM(str_sword, term, paren);
do {c = nextc();} while (ISSPACE(c));
pushback(c);
return tQWORDS_BEG;
@@ -6843,6 +6835,7 @@
lex_state = kw->state;
if (state == EXPR_FNAME) {
set_yylval_id(rb_intern(kw->name));
+ return kw->id[0];
}
if (kw->id[0] == keyword_do) {
if (lpar_beg && lpar_beg == paren_nest) {
@@ -6948,13 +6941,13 @@
return n;
}
-static enum node_type
+enum node_type
nodetype(NODE *node) /* for debug */
{
return (enum node_type)nd_type(node);
}
-static int
+int
nodeline(NODE *node)
{
return nd_line(node);
@@ -6984,7 +6977,7 @@
{
int line = ruby_sourceline;
ruby_sourceline = nd_line(node);
- rb_warning(mesg);
+ rb_warning("%s", mesg);
ruby_sourceline = line;
}
@@ -6993,7 +6986,7 @@
{
int line = ruby_sourceline;
ruby_sourceline = nd_line(node);
- rb_warn(mesg);
+ rb_warn("%s", mesg);
ruby_sourceline = line;
}
@@ -7352,10 +7345,10 @@
}
static void
-block_dup_check(NODE *node)
+block_dup_check(NODE *node1, NODE *node2)
{
- if (node && nd_type(node) == NODE_BLOCK_PASS) {
- compile_error(PARSER_ARG "both block arg and actual block given");
+ if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
+ compile_error("both block arg and actual block given");
}
}
@@ -7394,17 +7387,39 @@
arg_concat(NODE *node1, NODE *node2)
{
if (!node2) return node1;
+ if (nd_type(node1) == NODE_BLOCK_PASS) {
+ node1->nd_iter = arg_concat(node1->nd_iter, node2);
+ return node1;
+ }
return NEW_ARGSCAT(node1, node2);
}
static NODE *
-arg_add(NODE *node1, NODE *node2)
+arg_append(NODE *node1, NODE *node2)
{
if (!node1) return NEW_LIST(node2);
- if (nd_type(node1) == NODE_ARRAY) {
+ switch (nd_type(node1)) {
+ case NODE_ARRAY:
return list_append(node1, node2);
+ case NODE_BLOCK_PASS:
+ node1->nd_head = arg_append(node1->nd_head, node2);
+ return node1;
+ default:
+ return NEW_ARGSPUSH(node1, node2);
}
- else {
+}
+
+static NODE *
+arg_add(NODE *node1, NODE *node2)
+{
+ if (!node1) return NEW_LIST(node2);
+ switch (nd_type(node1)) {
+ case NODE_ARRAY:
+ return list_append(node1, node2);
+ case NODE_BLOCK_PASS:
+ node1->nd_head = arg_add(node1->nd_head, node2);
+ return node1;
+ default:
return NEW_ARGSPUSH(node1, node2);
}
}
@@ -7882,9 +7897,6 @@
nd_set_type(node, NODE_VALUES);
}
}
- else if (nd_type(node) == NODE_SPLAT) {
- node = NEW_SVALUE(node);
- }
}
return node;
}
@@ -7939,32 +7951,13 @@
return node1;
}
-static NODE*
-arg_prepend(NODE *node1, NODE *node2)
-{
- switch (nd_type(node2)) {
- case NODE_ARRAY:
- return list_concat(NEW_LIST(node1), node2);
-
- case NODE_SPLAT:
- return arg_concat(node1, node2->nd_head);
-
- case NODE_BLOCK_PASS:
- node2->nd_body = arg_prepend(node1, node2->nd_body);
- return node2;
-
- default:
- rb_bug("unknown nodetype(%d) for arg_prepend", nd_type(node2));
- }
- return 0; /* not reached */
-}
-
static int
arg_dup_check(ID vid, VALUE m, VALUE list, NODE *node)
{
VALUE sym;
if (!vid) return 0;
+ if (is_junk_id(vid)) return 0;
sym = ID2SYM(vid);
if ((m && rb_ary_includes(m, sym)) || rb_ary_includes(list, sym)) {
ruby_sourceline = nd_line(node);
@@ -7975,21 +7968,21 @@
}
static NODE*
-new_args_gen(struct parser_params *parser, VALUE m, NODE *o, NODE *r, NODE *b)
+new_args_gen(struct parser_params *parser, VALUE m, NODE *o, NODE *r, NODE *p, NODE *b)
{
int saved_line = ruby_sourceline;
- NODE *tmp;
+ NODE *node;
VALUE list;
list = rb_ary_new();
- tmp = o;
- while (tmp) {
- if (!tmp->nd_head) break;
- if (arg_dup_check(tmp->nd_head->nd_vid, m, list, tmp)) {
+ node = o;
+ while (node) {
+ if (!node->nd_head) break;
+ if (arg_dup_check(node->nd_head->nd_vid, m, list, node)) {
yyerror("duplicated optional argument name");
return 0;
}
- tmp = tmp->nd_next;
+ node = node->nd_next;
}
if (RTEST(r)) {
if (arg_dup_check(r->nd_vid, m, list, r)) {
@@ -7997,46 +7990,30 @@
return 0;
}
}
+ if (p) {
+ node = p;
+ while (node) {
+ if (!node->nd_head) break;
+ if (arg_dup_check(node->nd_head->nd_vid, m, list, node)) {
+ yyerror("duplicated argument name");
+ return 0;
+ }
+ node = node->nd_next;
+ }
+ r = NEW_POSTARG(r, p);
+ }
+ node = NEW_ARGS(m, o, r);
if (b) {
if (arg_dup_check(b->nd_vid, m, list, b)) {
yyerror("duplicated block argument name");
return 0;
}
+ node = block_append(node, b);
}
ruby_sourceline = saved_line;
- return block_append(NEW_ARGS(m, o, r), b);
+ return node;
}
-static NODE*
-new_call(NODE *r,ID m, NODE *a)
-{
- if (a && nd_type(a) == NODE_BLOCK_PASS) {
- a->nd_iter = NEW_CALL(r,m,a->nd_head);
- return a;
- }
- return NEW_CALL(r,m,a);
-}
-
-static NODE*
-new_fcall_gen(struct parser_params *parser, ID m, NODE *a)
-{
- if (a && nd_type(a) == NODE_BLOCK_PASS) {
- a->nd_iter = NEW_FCALL(m,a->nd_head);
- return a;
- }
- return NEW_FCALL(m, a);
-}
-
-static NODE*
-new_super(NODE *a)
-{
- if (a && nd_type(a) == NODE_BLOCK_PASS) {
- a->nd_iter = NEW_SUPER(a->nd_head);
- return a;
- }
- return NEW_SUPER(a);
-}
-
static void
local_push_gen(struct parser_params *parser, int inherit_dvars)
{
@@ -8560,11 +8537,12 @@
{
return rb_intern2(name, strlen(name));
}
-#include "debug.h"
+
VALUE
rb_id2sym(ID id)
{
VALUE data;
+
while (!st_lookup(global_symbols.id_sym, id, &data)) {
rb_id2name(id);
}
@@ -8752,6 +8730,7 @@
#else
rb_gc_mark(p->parser_ruby_sourcefile);
rb_gc_mark(p->delayed);
+ rb_gc_mark(p->value);
rb_gc_mark(p->result);
rb_gc_mark(p->parsing_thread);
#endif
@@ -9011,7 +8990,7 @@
{modifier_until, "until"},
{modifier_rescue, "rescue"},
{keyword_alias, "alias"},
- {keyword_defined, "defined"},
+ {keyword_defined, "defined?"},
{keyword_BEGIN, "BEGIN"},
{keyword_END, "END"},
{keyword__LINE__, "__LINE__"},
@@ -9304,7 +9283,7 @@
{
StringValue(msg);
if (obj == Qundef) {
- rb_raise(rb_eArgError, RSTRING_PTR(msg));
+ rb_raise(rb_eArgError, "%s", RSTRING_PTR(msg));
}
return Qnil;
}
@@ -9346,3 +9325,4 @@
rb_intern("&&");
}
#endif /* RIPPER */
+
Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/vm_dump.c 2006-11-10 00:18:12 UTC (rev 579)
@@ -586,11 +586,11 @@
int n = backtrace(trace, MAX_NATIVE_TRACE);
int i;
- printf("-- backtrace of native function call (Use addr2line) --\n");
+ fprintf(stderr, "-- backtrace of native function call (Use addr2line) --\n");
for (i=0; i<n; i++) {
- printf("%p\n", trace[i]);
+ fprintf(stderr, "%p\n", trace[i]);
}
- printf("-------------------------------------------------------\n");
+ fprintf(stderr, "-------------------------------------------------------\n");
}
#endif
}
Modified: trunk/yarvtest/test_block.rb
===================================================================
--- trunk/yarvtest/test_block.rb 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/yarvtest/test_block.rb 2006-11-10 00:18:12 UTC (rev 579)
@@ -83,7 +83,7 @@
iter{|a, $b, @c, d|
[a, $b]
} + [a, $b, @c]
- }
+ } if false # 1.9 doesn't support expr block parameters
end
def test_param3
Modified: trunk/yarvtest/test_class.rb
===================================================================
--- trunk/yarvtest/test_class.rb 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/yarvtest/test_class.rb 2006-11-10 00:18:12 UTC (rev 579)
@@ -214,6 +214,21 @@
:top
}
}
+ ae %q{
+ class C0
+ def m a, &b
+ [a, b]
+ end
+ end
+
+ class C1 < C0
+ def m a, &b
+ super a, &b
+ end
+ end
+
+ C1.new.m(10)
+ }
end
def test_zsuper_from_define_method
Modified: trunk/yarvtest/test_syntax.rb
===================================================================
--- trunk/yarvtest/test_syntax.rb 2006-11-09 01:27:13 UTC (rev 578)
+++ trunk/yarvtest/test_syntax.rb 2006-11-10 00:18:12 UTC (rev 579)
@@ -258,7 +258,8 @@
:ng2
else
:elseng
- end)
+ end
+ )
ae %q(
case
@@ -270,7 +271,8 @@
:ng2
else
:elseng
- end)
+ end
+ )
ae %q(
case
@@ -287,6 +289,24 @@
when 1
end
}
+
+ ae %q{
+ r = nil
+ ary = []
+ case
+ when false
+ r = :ng1
+ when false, false
+ r = :ng2
+ when *ary
+ r = :ng3
+ when false, *ary
+ r = :ng4
+ when true, *ary
+ r = :ok
+ end
+ r
+ }
end
def test_when_splat
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml