From d88376b1352ad96e35bfc08f2bfce885ed6d72ca Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 20 Feb 2003 03:35:44 +0000 Subject: * parse.y (clhs): allow "Foo::Bar = x". * parse.y (primary): "self[n]=x" can be legal even when "[]=" is private. changes submitted in [ruby-talk:63982] * parse.y (aryset): ditto. * parse.y (attrset): "self.foo=x" can be legal even when "foo=" is private. * eval.c (is_defined): private "[]=" and "foo=" support. * eval.c (rb_eval): ditto. * eval.c (assign): ditto. * eval.c (rb_eval): "foo=" should not always be public. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 24 ++++++++++++++++++++++++ eval.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- gc.c | 2 +- node.h | 2 +- parse.y | 60 ++++++++++++++++++++++++++++++++++++++++++------------------ 5 files changed, 107 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ca1681704..f6fcf5b605 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +Thu Feb 20 10:11:30 2003 Yukihiro Matsumoto + + * parse.y (clhs): allow "Foo::Bar = x". + +Thu Feb 20 04:07:06 2003 Nobuyoshi Nakada + + * parse.y (primary): "self[n]=x" can be legal even when "[]=" is + private. changes submitted in [ruby-talk:63982] + + * parse.y (aryset): ditto. + + * parse.y (attrset): "self.foo=x" can be legal even when "foo=" + is private. + + * eval.c (is_defined): private "[]=" and "foo=" support. + + * eval.c (rb_eval): ditto. + + * eval.c (assign): ditto. + +Thu Feb 20 03:58:34 2003 Yukihiro Matsumoto + + * eval.c (rb_eval): "foo=" should not always be public. + Thu Feb 20 01:23:59 2003 Nobuyoshi Nakada * eval.c (rb_thread_restore_context): inhibit interrupts in diff --git a/eval.c b/eval.c index 6cb8224479..ee34bdac66 100644 --- a/eval.c +++ b/eval.c @@ -1923,8 +1923,9 @@ is_defined(self, node, buf) val = self; goto check_bound; - case NODE_CALL: case NODE_ATTRASGN: + if (node->nd_recv == (NODE *)1) goto check_bound; + case NODE_CALL: PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { val = rb_eval(self, node->nd_recv); @@ -2776,15 +2777,23 @@ rb_eval(self, n) { VALUE recv; int argc; VALUE *argv; /* used in SETUP_ARGS */ + int scope; TMP_PROTECT; BEGIN_CALLARGS; - recv = rb_eval(self, node->nd_recv); + if (node->nd_recv == (NODE *)1) { + recv = self; + scope = 1; + } + else { + recv = rb_eval(self, node->nd_recv); + scope = 0; + } SETUP_ARGS(node->nd_args); END_CALLARGS; SET_CURRENT_SOURCE(); - rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0); + rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope); result = argv[argc-1]; } break; @@ -3000,11 +3009,16 @@ rb_eval(self, n) break; case NODE_CDECL: - if (NIL_P(ruby_cbase)) { - rb_raise(rb_eTypeError, "no class/module to define constant"); - } result = rb_eval(self, node->nd_value); - rb_const_set(ruby_cbase, node->nd_vid, result); + if (node->nd_vid == 0) { + rb_const_set(class_prefix(self, node->nd_else), node->nd_else->nd_mid, result); + } + else { + if (NIL_P(ruby_cbase)) { + rb_raise(rb_eTypeError, "no class/module to define constant"); + } + rb_const_set(ruby_cbase, node->nd_vid, result); + } break; case NODE_CVDECL: @@ -3239,10 +3253,7 @@ rb_eval(self, n) } } - if (node->nd_noex == NOEX_PUBLIC) { - noex = NOEX_PUBLIC; /* means is is an attrset */ - } - else if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) { + if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) { noex = NOEX_PRIVATE; } else if (SCOPE_TEST(SCOPE_PROTECTED)) { @@ -4106,7 +4117,12 @@ assign(self, lhs, val, pcall) break; case NODE_CDECL: - rb_const_set(ruby_cbase, lhs->nd_vid, val); + if (lhs->nd_vid == 0) { + rb_const_set(class_prefix(self, lhs->nd_else), lhs->nd_else->nd_mid, val); + } + else { + rb_const_set(ruby_cbase, lhs->nd_vid, val); + } break; case NODE_CVDECL: @@ -4128,12 +4144,20 @@ assign(self, lhs, val, pcall) case NODE_ATTRASGN: { VALUE recv; - recv = rb_eval(self, lhs->nd_recv); + int scope; + if (lhs->nd_recv == (NODE *)1) { + recv = self; + scope = 1; + } + else { + recv = rb_eval(self, lhs->nd_recv); + scope = 0; + } if (!lhs->nd_args) { /* attr set */ ruby_current_node = lhs; SET_CURRENT_SOURCE(); - rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, 0); + rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, scope); } else { /* array set */ @@ -4144,7 +4168,7 @@ assign(self, lhs, val, pcall) ruby_current_node = lhs; SET_CURRENT_SOURCE(); rb_call(CLASS_OF(recv), recv, lhs->nd_mid, - RARRAY(args)->len, RARRAY(args)->ptr, 0); + RARRAY(args)->len, RARRAY(args)->ptr, scope); } } break; diff --git a/gc.c b/gc.c index 49be3b1f6b..a018688046 100644 --- a/gc.c +++ b/gc.c @@ -695,7 +695,6 @@ rb_gc_mark_children(ptr) case NODE_DASGN: case NODE_DASGN_CURR: case NODE_IASGN: - case NODE_CDECL: case NODE_CVDECL: case NODE_CVASGN: case NODE_COLON3: @@ -721,6 +720,7 @@ rb_gc_mark_children(ptr) case NODE_SCOPE: /* 2,3 */ case NODE_BLOCK_PASS: + case NODE_CDECL: rb_gc_mark((VALUE)obj->as.node.u3.node); rb_gc_mark((VALUE)obj->as.node.u2.node); break; diff --git a/node.h b/node.h index 8b667853e5..da2f2f4f52 100644 --- a/node.h +++ b/node.h @@ -273,7 +273,7 @@ typedef struct RNode { #define NEW_DASGN(v,val) rb_node_newnode(NODE_DASGN,v,val,0) #define NEW_DASGN_CURR(v,val) rb_node_newnode(NODE_DASGN_CURR,v,val,0) #define NEW_IASGN(v,val) rb_node_newnode(NODE_IASGN,v,val,0) -#define NEW_CDECL(v,val) rb_node_newnode(NODE_CDECL,v,val,0) +#define NEW_CDECL(v,val,path) rb_node_newnode(NODE_CDECL,v,val,path) #define NEW_CVASGN(v,val) rb_node_newnode(NODE_CVASGN,v,val,0) #define NEW_CVDECL(v,val) rb_node_newnode(NODE_CVDECL,v,val,0) #define NEW_OP_ASGN1(p,id,a) rb_node_newnode(NODE_OP_ASGN1,p,id,a) diff --git a/parse.y b/parse.y index 2d0682f929..b848fe71e7 100644 --- a/parse.y +++ b/parse.y @@ -240,7 +240,7 @@ static void top_local_setup(); %type singleton strings string string1 xstring regexp %type string_contents xstring_contents string_content %type words qwords word_list qword_list word -%type literal numeric dsym cbase cpath +%type literal numeric dsym cpath clhs %type bodystmt compstmt stmts stmt expr arg primary command command_call method_call %type expr_value arg_value primary_value %type if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure @@ -483,6 +483,10 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem $1->nd_value = NEW_RESTARY($3); $$ = $1; } + | clhs '=' command_call + { + $$ = node_assign($1, $3); + } | var_lhs tOP_ASGN command_call { value_expr($3); @@ -570,6 +574,10 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem { $$ = node_assign($1, NEW_SVALUE($3)); } + | clhs '=' mrhs + { + $$ = node_assign($1, NEW_SVALUE($3)); + } | mlhs '=' arg_value { $1->nd_value = $3; @@ -580,6 +588,10 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem $1->nd_value = $3; $$ = $1; } + | clhs '=' arg + { + $$ = node_assign($1, $3); + } | expr ; @@ -830,6 +842,14 @@ lhs : variable } ; +clhs : primary_value tCOLON2 tCONSTANT + { + if (in_def || in_single) + yyerror("dynamic constant assignment"); + $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3)); + } + ; + cname : tIDENTIFIER { yyerror("class/module name must be CONSTANT"); @@ -837,27 +857,20 @@ cname : tIDENTIFIER | tCONSTANT ; -cbase : tCOLON3 cname +cpath : tCOLON3 cname { $$ = NEW_COLON3($2); } | cname { - $$ = NEW_CONST($1); + $$ = NEW_COLON2(0, $$); } - | cbase tCOLON2 cname + | primary_value tCOLON2 cname { $$ = NEW_COLON2($1, $3); } ; -cpath : cbase - { - if (nd_type($$ = $1) == NODE_CONST) - $$ = NEW_COLON2(0, $$->nd_vid); - } - ; - fname : tIDENTIFIER | tCONSTANT | tFID @@ -1423,7 +1436,10 @@ primary : literal } | primary_value '[' aref_args ']' { - $$ = NEW_CALL($1, tAREF, $3); + if (nd_type($1) == NODE_SELF) + $$ = NEW_FCALL(tAREF, $3); + else + $$ = NEW_CALL($1, tAREF, $3); } | tLBRACK aref_args ']' { @@ -1612,7 +1628,6 @@ primary : literal kEND { $$ = NEW_DEFN($2, $4, $5, NOEX_PRIVATE); - if (is_attrset_id($2)) $$->nd_noex = NOEX_PUBLIC; fixpos($$, $4); local_pop(); in_def--; @@ -4648,9 +4663,12 @@ call_op(recv, id, narg, arg1) value_expr(recv); if (narg == 1) { value_expr(arg1); + arg1 = NEW_LIST(arg1); } - - return NEW_CALL(recv, id, narg==1?NEW_LIST(arg1):0); + else { + arg1 = 0; + } + return NEW_CALL(recv, id, arg1); } static NODE* @@ -4788,7 +4806,7 @@ assignable(id, val) else if (is_const_id(id)) { if (in_def || in_single) yyerror("dynamic constant assignment"); - return NEW_CDECL(id, val); + return NEW_CDECL(id, val, 0); } else if (is_class_id(id)) { if (in_def || in_single) return NEW_CVASGN(id, val); @@ -4804,7 +4822,10 @@ static NODE * aryset(recv, idx) NODE *recv, *idx; { - value_expr(recv); + if (recv && nd_type(recv) == NODE_SELF) + recv = (NODE *)1; + else + value_expr(recv); return NEW_ATTRASGN(recv, tASET, idx); } @@ -4822,7 +4843,10 @@ attrset(recv, id) NODE *recv; ID id; { - value_expr(recv); + if (recv && nd_type(recv) == NODE_SELF) + recv = (NODE *)1; + else + value_expr(recv); return NEW_ATTRASGN(recv, rb_id_attrset(id), 0); } -- cgit v1.2.3