mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
e56e8c758d
commit
9d8075b99c
7 changed files with 87 additions and 95 deletions
12
ChangeLog
12
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.
|
||||
|
|
13
compile.c
13
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);
|
||||
|
|
1
gc.c
1
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:
|
||||
|
|
|
@ -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)
|
||||
|
|
49
object.c
49
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);
|
||||
|
|
98
parse.y
98
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, "<<"},
|
||||
|
|
|
@ -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[];
|
||||
|
|
Loading…
Add table
Reference in a new issue