summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-02-20 03:35:44 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-02-20 03:35:44 +0000
commitd88376b1352ad96e35bfc08f2bfce885ed6d72ca (patch)
tree0cd9c4945bf199c8173a37a39407288b31cb342f
parentafca4f0cfd0bcc769451d5160320c7a33b3c4ed1 (diff)
* 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
-rw-r--r--ChangeLog24
-rw-r--r--eval.c54
-rw-r--r--gc.c2
-rw-r--r--node.h2
-rw-r--r--parse.y60
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 <matz@ruby-lang.org>
+
+ * parse.y (clhs): allow "Foo::Bar = x".
+
+Thu Feb 20 04:07:06 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
+
+ * 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 <matz@ruby-lang.org>
+
+ * eval.c (rb_eval): "foo=" should not always be public.
+
Thu Feb 20 01:23:59 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* 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 <node> singleton strings string string1 xstring regexp
%type <node> string_contents xstring_contents string_content
%type <node> words qwords word_list qword_list word
-%type <node> literal numeric dsym cbase cpath
+%type <node> literal numeric dsym cpath clhs
%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
@@ -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);
}