1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* node.h (nd_cpath): nested class/module declaration.

[EXPREIMENTAL]

* eval.c (rb_eval): ditto.

* gc.c (rb_gc_mark_children): ditto.

* parse.y (cpath): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3506 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2003-02-19 09:27:49 +00:00
parent d22fc7c4d8
commit 884efe7c5e
5 changed files with 93 additions and 24 deletions

View file

@ -1,3 +1,14 @@
Wed Feb 19 18:27:42 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* node.h (nd_cpath): nested class/module declaration.
[EXPREIMENTAL]
* eval.c (rb_eval): ditto.
* gc.c (rb_gc_mark_children): ditto.
* parse.y (cpath): ditto.
Tue Feb 18 21:39:27 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_call0): should not report uninitialized warning by

73
eval.c
View file

@ -2219,6 +2219,37 @@ svalue_to_avalue(v)
return tmp;
}
static VALUE
class_prefix(self, cpath)
VALUE self;
NODE *cpath;
{
if (!cpath) {
rb_bug("class path missing");
}
if (cpath->nd_head) {
VALUE c = rb_eval(self, cpath->nd_head);
switch (TYPE(c)) {
case T_CLASS:
case T_MODULE:
break;
default:
rb_raise(rb_eTypeError, "%s is not a class/module",
RSTRING(rb_obj_as_string(c))->ptr);
}
return c;
}
else if (nd_type(cpath) == NODE_COLON2) {
return ruby_cbase;
}
else if (ruby_wrapper) {
return ruby_wrapper;
}
else {
return rb_cObject;
}
}
static void return_check _((void));
#define return_value(v) do {\
if ((prot_tag->retval = (v)) == Qundef) {\
@ -3300,7 +3331,8 @@ rb_eval(self, n)
case NODE_CLASS:
{
VALUE super, klass, tmp;
VALUE super, klass, tmp, cbase;
ID cname;
if (NIL_P(ruby_cbase)) {
rb_raise(rb_eTypeError, "no outer class/module");
@ -3312,14 +3344,16 @@ rb_eval(self, n)
super = 0;
}
if ((ruby_cbase == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
rb_autoload_load(node->nd_cname);
cbase = class_prefix(self, node->nd_cpath);
cname = node->nd_cpath->nd_mid;
if ((cbase == rb_cObject) && rb_autoload_defined(cname)) {
rb_autoload_load(cname);
}
if (rb_const_defined_at(ruby_cbase, node->nd_cname)) {
klass = rb_const_get(ruby_cbase, node->nd_cname);
if (rb_const_defined_at(cbase, cname)) {
klass = rb_const_get(cbase, cname);
if (TYPE(klass) != T_CLASS) {
rb_raise(rb_eTypeError, "%s is not a class",
rb_id2name(node->nd_cname));
rb_id2name(cname));
}
if (super) {
tmp = rb_class_real(RCLASS(klass)->super);
@ -3335,9 +3369,9 @@ rb_eval(self, n)
else {
override_class:
if (!super) super = rb_cObject;
klass = rb_define_class_id(node->nd_cname, super);
rb_set_class_path(klass,ruby_cbase,rb_id2name(node->nd_cname));
rb_const_set(ruby_cbase, node->nd_cname, klass);
klass = rb_define_class_id(cname, super);
rb_set_class_path(klass, cbase, rb_id2name(cname));
rb_const_set(cbase, cname, klass);
}
if (ruby_wrapper) {
rb_extend_object(klass, ruby_wrapper);
@ -3350,28 +3384,31 @@ rb_eval(self, n)
case NODE_MODULE:
{
VALUE module;
VALUE module, cbase;
ID cname;
if (NIL_P(ruby_cbase)) {
rb_raise(rb_eTypeError, "no outer class/module");
}
if ((ruby_cbase == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
rb_autoload_load(node->nd_cname);
cbase = class_prefix(self, node->nd_cpath);
cname = node->nd_cpath->nd_mid;
if ((cbase == rb_cObject) && rb_autoload_defined(cname)) {
rb_autoload_load(cname);
}
if (rb_const_defined_at(ruby_cbase, node->nd_cname)) {
module = rb_const_get(ruby_cbase, node->nd_cname);
if (rb_const_defined_at(cbase, cname)) {
module = rb_const_get(cbase, cname);
if (TYPE(module) != T_MODULE) {
rb_raise(rb_eTypeError, "%s is not a module",
rb_id2name(node->nd_cname));
rb_id2name(cname));
}
if (ruby_safe_level >= 4) {
rb_raise(rb_eSecurityError, "extending module prohibited");
}
}
else {
module = rb_define_module_id(node->nd_cname);
rb_set_class_path(module,ruby_cbase,rb_id2name(node->nd_cname));
rb_const_set(ruby_cbase, node->nd_cname, module);
module = rb_define_module_id(cname);
rb_set_class_path(module, cbase, rb_id2name(cname));
rb_const_set(cbase, cname, module);
}
if (ruby_wrapper) {
rb_extend_object(module, ruby_wrapper);

4
gc.c
View file

@ -648,6 +648,7 @@ rb_gc_mark_children(ptr)
case NODE_MASGN:
case NODE_RESCUE:
case NODE_RESBODY:
case NODE_CLASS:
rb_gc_mark((VALUE)obj->as.node.u2.node);
/* fall through */
case NODE_BLOCK: /* 1,3 */
@ -684,6 +685,7 @@ rb_gc_mark_children(ptr)
case NODE_MATCH3:
case NODE_OP_ASGN_OR:
case NODE_OP_ASGN_AND:
case NODE_MODULE:
rb_gc_mark((VALUE)obj->as.node.u1.node);
/* fall through */
case NODE_METHOD: /* 2 */
@ -696,7 +698,6 @@ rb_gc_mark_children(ptr)
case NODE_CDECL:
case NODE_CVDECL:
case NODE_CVASGN:
case NODE_MODULE:
case NODE_COLON3:
case NODE_OPT_N:
case NODE_EVSTR:
@ -719,7 +720,6 @@ rb_gc_mark_children(ptr)
break;
case NODE_SCOPE: /* 2,3 */
case NODE_CLASS:
case NODE_BLOCK_PASS:
rb_gc_mark((VALUE)obj->as.node.u3.node);
rb_gc_mark((VALUE)obj->as.node.u2.node);

2
node.h
View file

@ -218,7 +218,7 @@ typedef struct RNode {
#define nd_cfnc u1.cfunc
#define nd_argc u2.argc
#define nd_cname u1.id
#define nd_cpath u1.node
#define nd_super u3.node
#define nd_modl u1.id

27
parse.y
View file

@ -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
%type <node> literal numeric dsym cbase cpath
%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
@ -837,6 +837,27 @@ cname : tIDENTIFIER
| tCONSTANT
;
cbase : tCOLON3 cname
{
$$ = NEW_COLON3($2);
}
| cname
{
$$ = NEW_CONST($1);
}
| cbase tCOLON2 cname
{
$$ = NEW_COLON2($1, $3);
}
;
cpath : cbase
{
if (nd_type($$ = $1) == NODE_CONST)
$$ = NEW_COLON2(0, $$->nd_vid);
}
;
fname : tIDENTIFIER
| tCONSTANT
| tFID
@ -1525,7 +1546,7 @@ primary : literal
$$ = NEW_FOR($2, $5, $8);
fixpos($$, $2);
}
| kCLASS cname superclass
| kCLASS cpath superclass
{
if (in_def || in_single)
yyerror("class definition in method body");
@ -1563,7 +1584,7 @@ primary : literal
in_def = $<num>4;
in_single = $<num>6;
}
| kMODULE cname
| kMODULE cpath
{
if (in_def || in_single)
yyerror("module definition in method body");