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:
parent
d22fc7c4d8
commit
884efe7c5e
5 changed files with 93 additions and 24 deletions
11
ChangeLog
11
ChangeLog
|
@ -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
73
eval.c
|
@ -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
4
gc.c
|
@ -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
2
node.h
|
@ -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
27
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
|
||||
%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");
|
||||
|
|
Loading…
Reference in a new issue