summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-12-09 16:39:49 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-12-09 16:39:49 +0000
commit9d8075b99cf131e0b2522bcf82a5b47e82d3882e (patch)
tree4215356c5ede9a7dbd0c02a5fcdebece7768d51f
parente56e8c758d8effb54144df0b61ca9d5f6b98a0cd (diff)
* parse.y (expr): redefinable not (!) operator.
* parse.y (arg): ditto. * object.c (rb_obj_not): new method "!". * object.c (rb_obj_not_equal): new method "!=". * object.c (rb_obj_not_match): new method "!~". git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14162 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--compile.c13
-rw-r--r--gc.c1
-rw-r--r--include/ruby/node.h3
-rw-r--r--object.c49
-rw-r--r--parse.y98
-rw-r--r--version.h6
7 files changed, 87 insertions, 95 deletions
diff --git a/ChangeLog b/ChangeLog
index 1f1b4b25e3..c2ebeaca32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Mon Dec 10 01:35:06 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (expr): redefinable not (!) operator.
+
+ * parse.y (arg): ditto.
+
+ * object.c (rb_obj_not): new method "!".
+
+ * object.c (rb_obj_not_equal): new method "!=".
+
+ * object.c (rb_obj_not_match): new method "!~".
+
Sun Dec 9 22:31:36 2007 Tanaka Akira <akr@fsij.org>
* re.c (rb_reg_s_last_match): accept named capture's name.
diff --git a/compile.c b/compile.c
index 629a8b8040..538e811582 100644
--- a/compile.c
+++ b/compile.c
@@ -1796,11 +1796,6 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * cond,
LABEL *then_label, LABEL *else_label)
{
switch (nd_type(cond)) {
- case NODE_NOT:
- compile_branch_condition(iseq, ret, cond->nd_body, else_label,
- then_label);
- break;
-
case NODE_AND:
{
LABEL *label = NEW_LABEL(nd_line(cond));
@@ -3209,14 +3204,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_LABEL(ret, end_label);
break;
}
- case NODE_NOT:{
- COMPILE(ret, "value", node->nd_body);
- ADD_INSN(ret, nd_line(node), putnot);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
case NODE_MASGN:{
compile_massign(iseq, ret, node, poped);
diff --git a/gc.c b/gc.c
index 66f095c09e..68d3fa9ffc 100644
--- a/gc.c
+++ b/gc.c
@@ -949,7 +949,6 @@ gc_mark_children(VALUE ptr, int lev)
gc_mark((VALUE)obj->as.node.u1.node, lev);
/* fall through */
case NODE_FBODY: /* 2 */
- case NODE_NOT:
case NODE_GASGN:
case NODE_LASGN:
case NODE_DASGN:
diff --git a/include/ruby/node.h b/include/ruby/node.h
index eeea3cea99..b93d72596d 100644
--- a/include/ruby/node.h
+++ b/include/ruby/node.h
@@ -67,8 +67,6 @@ enum node_type {
#define NODE_AND NODE_AND
NODE_OR,
#define NODE_OR NODE_OR
- NODE_NOT,
-#define NODE_NOT NODE_NOT
NODE_MASGN,
#define NODE_MASGN NODE_MASGN
NODE_LASGN,
@@ -390,7 +388,6 @@ typedef struct RNode {
#define NEW_ARRAY(a) NEW_NODE(NODE_ARRAY,a,1,0)
#define NEW_ZARRAY() NEW_NODE(NODE_ZARRAY,0,0,0)
#define NEW_HASH(a) NEW_NODE(NODE_HASH,a,0,0)
-#define NEW_NOT(a) NEW_NODE(NODE_NOT,0,a,0)
#define NEW_MASGN(l,r) NEW_NODE(NODE_MASGN,l,0,r)
#define NEW_GASGN(v,val) NEW_NODE(NODE_GASGN,v,val,rb_global_entry(v))
#define NEW_LASGN(v,val) NEW_NODE(NODE_LASGN,v,val,0)
diff --git a/object.c b/object.c
index 689e87a27a..1152b855f2 100644
--- a/object.c
+++ b/object.c
@@ -96,6 +96,33 @@ rb_obj_equal(VALUE obj1, VALUE obj2)
return Qfalse;
}
+/*
+ * call-seq:
+ * !obj => true or false
+ *
+ * Boolean negate.
+ */
+
+static VALUE
+rb_obj_not(VALUE obj)
+{
+ return RTEST(obj) ? Qfalse : Qtrue;
+}
+
+/*
+ * call-seq:
+ * obj != other => true or false
+ *
+ * Returns true if two objects are not-equal, otherwise false.
+ */
+
+static VALUE
+rb_obj_not_equal(VALUE obj1, VALUE obj2)
+{
+ VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
+ return RTEST(result) ? Qfalse : Qtrue;
+}
+
VALUE
rb_class_real(VALUE cl)
{
@@ -991,11 +1018,24 @@ rb_false(VALUE obj)
*/
static VALUE
-rb_obj_pattern_match(VALUE obj1, VALUE obj2)
+rb_obj_match(VALUE obj1, VALUE obj2)
{
return Qnil;
}
+/*
+ * call-seq:
+ * obj !~ other => nil
+ *
+ * Returns true if two objects does not match, using <i>=~</i> method.
+ */
+
+static VALUE
+rb_obj_not_match(VALUE obj1, VALUE obj2)
+{
+ return Qtrue;
+}
+
/***********************************************************************
*
@@ -2307,6 +2347,8 @@ Init_Object(void)
rb_define_alloc_func(rb_cBasicObject, rb_class_allocate_instance);
rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1);
rb_define_method(rb_cBasicObject, "equal?", rb_obj_equal, 1);
+ rb_define_method(rb_cBasicObject, "!@", rb_obj_not, 0);
+ rb_define_method(rb_cBasicObject, "!=", rb_obj_not_equal, 1);
rb_mKernel = rb_define_module("Kernel");
rb_include_module(rb_cObject, rb_mKernel);
@@ -2319,12 +2361,11 @@ Init_Object(void)
rb_define_method(rb_mKernel, "nil?", rb_false, 0);
rb_define_method(rb_mKernel, "===", rb_equal, 1);
- rb_define_method(rb_mKernel, "=~", rb_obj_pattern_match, 1);
-
+ rb_define_method(rb_mKernel, "=~", rb_obj_match, 1);
+ rb_define_method(rb_mKernel, "!~", rb_obj_not_match, 1);
rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);
rb_define_method(rb_mKernel, "class", rb_obj_class, 0);
-
rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0);
rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0);
rb_define_method(rb_mKernel, "initialize_copy", rb_obj_init_copy, 1);
diff --git a/parse.y b/parse.y
index 2cf0ecde31..2aff7adaa9 100644
--- a/parse.y
+++ b/parse.y
@@ -336,8 +336,6 @@ static NODE *cond_gen(struct parser_params*,NODE*);
static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
#define logop(type,node1,node2) logop_gen(parser, type, node1, node2)
-static int cond_negative(NODE**);
-
static NODE *newline_node(NODE*);
static void fixpos(NODE*,NODE*);
@@ -387,8 +385,6 @@ static NODE *ret_args_gen(struct parser_params*,NODE*);
static NODE *arg_blk_pass(NODE*,NODE*);
static NODE *new_yield_gen(struct parser_params*,NODE*);
#define new_yield(node) new_yield_gen(parser, node)
-static NODE *new_not_gen(struct parser_params*,NODE*);
-#define new_not(node) new_not_gen(parser, node)
static NODE *gettable_gen(struct parser_params*,ID);
#define gettable(id) gettable_gen(parser,id)
@@ -890,10 +886,6 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
/*%%%*/
$$ = NEW_IF(cond($3), remove_begin($1), 0);
fixpos($$, $3);
- if (cond_negative(&$$->nd_cond)) {
- $$->nd_else = $$->nd_body;
- $$->nd_body = 0;
- }
/*%
$$ = dispatch2(if_mod, $3, $1);
%*/
@@ -903,10 +895,6 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
/*%%%*/
$$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
fixpos($$, $3);
- if (cond_negative(&$$->nd_cond)) {
- $$->nd_body = $$->nd_else;
- $$->nd_else = 0;
- }
/*%
$$ = dispatch2(unless_mod, $3, $1);
%*/
@@ -920,9 +908,6 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
else {
$$ = NEW_WHILE(cond($3), $1, 1);
}
- if (cond_negative(&$$->nd_cond)) {
- nd_set_type($$, NODE_UNTIL);
- }
/*%
$$ = dispatch2(while_mod, $3, $1);
%*/
@@ -936,9 +921,6 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
else {
$$ = NEW_UNTIL(cond($3), $1, 1);
}
- if (cond_negative(&$$->nd_cond)) {
- nd_set_type($$, NODE_WHILE);
- }
/*%
$$ = dispatch2(until_mod, $3, $1);
%*/
@@ -1166,7 +1148,7 @@ expr : command_call
| keyword_not expr
{
/*%%%*/
- $$ = new_not($2);
+ $$ = call_uni_op($2, '!');
/*%
$$ = dispatch2(unary, ripper_intern("not"), $2);
%*/
@@ -1174,9 +1156,9 @@ expr : command_call
| '!' command_call
{
/*%%%*/
- $$ = new_not($2);
+ $$ = call_uni_op($2, '!');
/*%
- $$ = dispatch2(unary, ID2SYM('!'), $2);
+ $$ = dispatch2(unary, ripper_id2sym('!'), $2);
%*/
}
| arg
@@ -1749,10 +1731,12 @@ op : '|' { ifndef_ripper($$ = '|'); }
| tEQ { ifndef_ripper($$ = tEQ); }
| tEQQ { ifndef_ripper($$ = tEQQ); }
| tMATCH { ifndef_ripper($$ = tMATCH); }
+ | tNMATCH { ifndef_ripper($$ = tNMATCH); }
| '>' { ifndef_ripper($$ = '>'); }
| tGEQ { ifndef_ripper($$ = tGEQ); }
| '<' { ifndef_ripper($$ = '<'); }
| tLEQ { ifndef_ripper($$ = tLEQ); }
+ | tNEQ { ifndef_ripper($$ = tNEQ); }
| tLSHFT { ifndef_ripper($$ = tLSHFT); }
| tRSHFT { ifndef_ripper($$ = tRSHFT); }
| '+' { ifndef_ripper($$ = '+'); }
@@ -1762,6 +1746,7 @@ op : '|' { ifndef_ripper($$ = '|'); }
| '/' { ifndef_ripper($$ = '/'); }
| '%' { ifndef_ripper($$ = '%'); }
| tPOW { ifndef_ripper($$ = tPOW); }
+ | '!' { ifndef_ripper($$ = '!'); }
| '~' { ifndef_ripper($$ = '~'); }
| tUPLUS { ifndef_ripper($$ = tUPLUS); }
| tUMINUS { ifndef_ripper($$ = tUMINUS); }
@@ -2133,7 +2118,7 @@ arg : lhs '=' arg
| arg tNEQ arg
{
/*%%%*/
- $$ = NEW_NOT(call_bin_op($1, tEQ, $3));
+ $$ = call_bin_op($1, tNEQ, $3);
/*%
$$ = dispatch3(binary, $1, ripper_intern("!="), $3);
%*/
@@ -2149,7 +2134,7 @@ arg : lhs '=' arg
| arg tNMATCH arg
{
/*%%%*/
- $$ = NEW_NOT(match_op($1, $3));
+ $$ = call_bin_op($1, tNMATCH, $3);
/*%
$$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
%*/
@@ -2157,7 +2142,7 @@ arg : lhs '=' arg
| '!' arg
{
/*%%%*/
- $$ = new_not($2);
+ $$ = call_uni_op($2, '!');
/*%
$$ = dispatch2(unary, ID2SYM('!'), $2);
%*/
@@ -2659,11 +2644,6 @@ primary : literal
/*%%%*/
$$ = NEW_IF(cond($2), $4, $5);
fixpos($$, $2);
- if (cond_negative(&$$->nd_cond)) {
- NODE *tmp = $$->nd_body;
- $$->nd_body = $$->nd_else;
- $$->nd_else = tmp;
- }
/*%
$$ = dispatch3(if, $2, $4, escape_Qundef($5));
%*/
@@ -2676,11 +2656,6 @@ primary : literal
/*%%%*/
$$ = NEW_UNLESS(cond($2), $4, $5);
fixpos($$, $2);
- if (cond_negative(&$$->nd_cond)) {
- NODE *tmp = $$->nd_body;
- $$->nd_body = $$->nd_else;
- $$->nd_else = tmp;
- }
/*%
$$ = dispatch3(unless, $2, $4, escape_Qundef($5));
%*/
@@ -2692,9 +2667,6 @@ primary : literal
/*%%%*/
$$ = NEW_WHILE(cond($3), $6, 1);
fixpos($$, $3);
- if (cond_negative(&$$->nd_cond)) {
- nd_set_type($$, NODE_UNTIL);
- }
/*%
$$ = dispatch2(while, $3, $6);
%*/
@@ -2706,9 +2678,6 @@ primary : literal
/*%%%*/
$$ = NEW_UNTIL(cond($3), $6, 1);
fixpos($$, $3);
- if (cond_negative(&$$->nd_cond)) {
- nd_set_type($$, NODE_WHILE);
- }
/*%
$$ = dispatch2(until, $3, $6);
%*/
@@ -6115,8 +6084,17 @@ parser_yylex(struct parser_params *parser)
return c;
case '!':
- lex_state = EXPR_BEG;
- if ((c = nextc()) == '=') {
+ c = nextc();
+ if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
+ lex_state = EXPR_ARG;
+ if (c != '@') {
+ pushback(c);
+ }
+ }
+ else {
+ lex_state = EXPR_BEG;
+ }
+ if (c == '=') {
return tNEQ;
}
if (c == '~') {
@@ -6796,12 +6774,10 @@ parser_yylex(struct parser_params *parser)
if ((c = nextc()) != '@') {
pushback(c);
}
+ lex_state = EXPR_ARG;
}
- switch (lex_state) {
- case EXPR_FNAME: case EXPR_DOT:
- lex_state = EXPR_ARG; break;
- default:
- lex_state = EXPR_BEG; break;
+ else {
+ lex_state = EXPR_BEG;
}
return '~';
@@ -8193,20 +8169,6 @@ logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *r
return NEW_NODE(type, left, right, 0);
}
-static int
-cond_negative(NODE **nodep)
-{
- NODE *c = *nodep;
-
- if (!c) return 0;
- switch (nd_type(c)) {
- case NODE_NOT:
- *nodep = c->nd_body;
- return 1;
- }
- return 0;
-}
-
static void
no_blockarg(struct parser_params *parser, NODE *node)
{
@@ -8249,13 +8211,6 @@ new_yield_gen(struct parser_params *parser, NODE *node)
return NEW_YIELD(node, state);
}
-static NODE *
-new_not_gen(struct parser_params *parser, NODE *node)
-{
- value_expr(node);
- return NEW_NOT(cond(node));
-}
-
static NODE*
negate_lit(NODE *node)
{
@@ -8605,6 +8560,7 @@ static const struct {
{'|', "|"},
{'^', "^"},
{'&', "&"},
+ {'!', "!"},
{tCMP, "<=>"},
{'>', ">"},
{tGEQ, ">="},
@@ -8615,12 +8571,12 @@ static const struct {
{tNEQ, "!="},
{tMATCH, "=~"},
{tNMATCH, "!~"},
- {'!', "!"},
{'~', "~"},
- {'!', "!(unary)"},
{'~', "~(unary)"},
- {'!', "!@"},
{'~', "~@"},
+ {'!', "!"},
+ {'!', "!(unary)"},
+ {'!', "!@"},
{tAREF, "[]"},
{tASET, "[]="},
{tLSHFT, "<<"},
diff --git a/version.h b/version.h
index c520913ce4..2624e6f276 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2007-12-09"
+#define RUBY_RELEASE_DATE "2007-12-10"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20071209
+#define RUBY_RELEASE_CODE 20071210
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 12
-#define RUBY_RELEASE_DAY 9
+#define RUBY_RELEASE_DAY 10
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];