diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-02-19 09:27:49 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-02-19 09:27:49 +0000 |
commit | 884efe7c5ecfe5bf0621008b7a535729b4c07b97 (patch) | |
tree | 0380cb0e4887dd83e1047c42285c3eb6e3ae9856 | |
parent | d22fc7c4d8849c86774b049bd6ef02005187c671 (diff) |
* 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
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | eval.c | 73 | ||||
-rw-r--r-- | gc.c | 4 | ||||
-rw-r--r-- | node.h | 2 | ||||
-rw-r--r-- | parse.y | 27 |
5 files changed, 93 insertions, 24 deletions
@@ -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 @@ -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); @@ -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); @@ -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 @@ -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"); |