ext/internal/node/nodeinfo.c in ruby-internal-0.7.3 vs ext/internal/node/nodeinfo.c in ruby-internal-0.8.0

- old
+ new

@@ -448,13 +448,33 @@ else { return ID2SYM(n->nd_entry->id); } case NEN_FRML: + if(n->nd_frml) { - return LONG2NUM((long)n->nd_frml); + int node_type; + if(0 && nd_type(n) == NODE_OP_ASGN2) + { + /* All children of NODE_OP_ASGN2 are NODE_OP_ASGN2_ARG */ + node_type = NODE_OP_ASGN2_ARG; + } + else + { + node_type = nd_type(n->nd_frml); + } + + dump_node_or_iseq_to_hash( + (VALUE)n->nd_frml, + node_type, + node_hash); + return node_id(n->nd_frml); } + else + { + return Qnil; + } case NEN_HEAD: if(n->nd_head) { int node_type; if(0 && nd_type(n) == NODE_OP_ASGN2) @@ -475,10 +495,34 @@ } else { return Qnil; } + case NEN_IBDY: + if(n->nd_ibdy) + { + int node_type; + if(0 && nd_type(n) == NODE_OP_ASGN2) + { + /* All children of NODE_OP_ASGN2 are NODE_OP_ASGN2_ARG */ + node_type = NODE_OP_ASGN2_ARG; + } + else + { + node_type = nd_type(n->nd_ibdy); + } + + dump_node_or_iseq_to_hash( + (VALUE)n->nd_ibdy, + node_type, + node_hash); + return node_id(n->nd_ibdy); + } + else + { + return Qnil; + } case NEN_ITER: if(n->nd_iter) { int node_type; if(0 && nd_type(n) == NODE_OP_ASGN2) @@ -599,23 +643,10 @@ } case NEN_NTH: { return LONG2NUM((long)n->nd_nth); } - case NEN_OID: - if(n->nd_oid == 0) - { - return Qfalse; - } - else if(n->nd_oid == 1) - { - return Qtrue; - } - else - { - return ID2SYM(n->nd_oid); - } case NEN_OPT: if(n->nd_opt) { int node_type; if(0 && nd_type(n) == NODE_OP_ASGN2) @@ -678,27 +709,10 @@ /* TODO: would like to dump flags, not type */ return rb_assoc_new( INT2NUM(TYPE((VALUE)n->nd_orig)), (VALUE)n->nd_orig); } - case NEN_PID: - if(n->nd_pid == 0) - { - return Qfalse; - } - else if(n->nd_pid == 1) - { - return Qtrue; - } - else - { - return ID2SYM(n->nd_pid); - } - case NEN_PLEN: - { - return LONG2NUM((long)n->nd_plen); - } case NEN_RECV: if(n->nd_recv) { int node_type; if(0 && nd_type(n) == NODE_OP_ASGN2) @@ -744,21 +758,32 @@ else { return Qnil; } case NEN_REST: - if(n->nd_rest == 0) + if(n->nd_rest) { - return Qfalse; + int node_type; + if(0 && nd_type(n) == NODE_OP_ASGN2) + { + /* All children of NODE_OP_ASGN2 are NODE_OP_ASGN2_ARG */ + node_type = NODE_OP_ASGN2_ARG; + } + else + { + node_type = nd_type(n->nd_rest); + } + + dump_node_or_iseq_to_hash( + (VALUE)n->nd_rest, + node_type, + node_hash); + return node_id(n->nd_rest); } - else if(n->nd_rest == 1) - { - return Qtrue; - } else { - return ID2SYM(n->nd_rest); + return Qnil; } case NEN_RVAL: if(n->nd_2nd) { int node_type; @@ -953,14 +978,10 @@ } else { return ID2SYM(n->nd_vid); } - case NEN_VISI: - { - return LONG2NUM((long)n->nd_visi); - } } rb_raise(rb_eArgError, "Invalid Node_Elem_Name %d", nen); } void load_node_elem(enum Node_Elem_Name nen, VALUE v, NODE * n, VALUE node_hash, VALUE id_hash) @@ -1363,11 +1384,31 @@ n->nd_entry = rb_global_entry(SYM2ID(v)); return; } case NEN_FRML: { - n->nd_frml = NUM2LONG(v); + if(v == Qnil) + { + n->nd_frml = 0; + } + else + { + VALUE nid = rb_hash_aref(id_hash, v); + if(RTEST(nid)) + { + n->nd_frml = id_to_node(nid); + } + else + { + n->u1.node = (NODE *)load_node_or_iseq_from_hash( + v, node_hash, id_hash); + if(nd_type(n->u1.node) == NODE_OP_ASGN2_ARG) + { + nd_set_type(n->u1.node, NODE_OP_ASGN2); + } + } + } return; } case NEN_HEAD: { if(v == Qnil) @@ -1391,10 +1432,35 @@ } } } return; } + case NEN_IBDY: + { + if(v == Qnil) + { + n->nd_ibdy = 0; + } + else + { + VALUE nid = rb_hash_aref(id_hash, v); + if(RTEST(nid)) + { + n->nd_ibdy = id_to_node(nid); + } + else + { + n->u2.node = (NODE *)load_node_or_iseq_from_hash( + v, node_hash, id_hash); + if(nd_type(n->u2.node) == NODE_OP_ASGN2_ARG) + { + nd_set_type(n->u2.node, NODE_OP_ASGN2); + } + } + } + return; + } case NEN_ITER: { if(v == Qnil) { n->nd_iter = 0; @@ -1520,26 +1586,10 @@ case NEN_NTH: { n->nd_nth = NUM2LONG(v); return; } - case NEN_OID: - { - if(v == Qfalse) - { - n->nd_oid = 0; - } - else if(v == Qfalse) - { - n->nd_oid = 1; - } - else - { - n->nd_oid = SYM2ID(v); - } - return; - } case NEN_OPT: { if(v == Qnil) { n->nd_opt = 0; @@ -1598,31 +1648,10 @@ *(VALUE *)(&n->nd_orig) = RARRAY_PTR(v)[1]; break; } return; } - case NEN_PID: - { - if(v == Qfalse) - { - n->nd_pid = 0; - } - else if(v == Qfalse) - { - n->nd_pid = 1; - } - else - { - n->nd_pid = SYM2ID(v); - } - return; - } - case NEN_PLEN: - { - n->nd_plen = NUM2LONG(v); - return; - } case NEN_RECV: { if(v == Qnil) { n->nd_recv = 0; @@ -1671,21 +1700,30 @@ } return; } case NEN_REST: { - if(v == Qfalse) + if(v == Qnil) { n->nd_rest = 0; } - else if(v == Qfalse) - { - n->nd_rest = 1; - } else { - n->nd_rest = SYM2ID(v); + VALUE nid = rb_hash_aref(id_hash, v); + if(RTEST(nid)) + { + n->nd_rest = id_to_node(nid); + } + else + { + n->u2.node = (NODE *)load_node_or_iseq_from_hash( + v, node_hash, id_hash); + if(nd_type(n->u2.node) == NODE_OP_ASGN2_ARG) + { + nd_set_type(n->u2.node, NODE_OP_ASGN2); + } + } } return; } case NEN_RVAL: { @@ -1919,15 +1957,10 @@ { n->nd_vid = SYM2ID(v); } return; } - case NEN_VISI: - { - n->nd_visi = NUM2LONG(v); - return; - } } rb_raise(rb_eRuntimeError, "Internal error: invalid Node_Elem_Name %d", nen); } /* @@ -2014,10 +2047,20 @@ NODE * n; Data_Get_Struct(self, NODE, n); return LONG2NUM(n->nd_alen); } /* + * Return the Node's _argc_ member. The return type is an + * Integer. + */ +static VALUE node_argc(VALUE self) +{ + NODE * n; + Data_Get_Struct(self, NODE, n); + return LONG2NUM(n->nd_argc); +} +/* * Return the Node's _args_ member. The return type is * either a Node or an Object. */ static VALUE node_args(VALUE self) { @@ -2111,10 +2154,37 @@ NODE * n; Data_Get_Struct(self, NODE, n); return LONG2NUM((long)(n->nd_cfnc)); } /* + * Return the Node's _clss_ member. The return type is + * either a Node or an Object. + */ +static VALUE node_clss(VALUE self) +{ + NODE * n; + Data_Get_Struct(self, NODE, n); + + if(TYPE(n->nd_clss) == T_NODE) + { + if(0 && nd_type(n) == NODE_OP_ASGN2) + { + return wrap_node_as( + (NODE *)n->nd_clss, + rb_cNodeSubclass[NODE_OP_ASGN2_ARG]); + } + else + { + return wrap_node((NODE *)n->nd_clss); + } + } + else + { + return (VALUE)n->nd_clss; + } +} +/* * Return the Node's _cnt_ member. The return type is an * Integer. */ static VALUE node_cnt(VALUE self) { @@ -2503,10 +2573,37 @@ { return (VALUE)n->nd_opt; } } /* + * Return the Node's _orig_ member. The return type is + * either a Node or an Object. + */ +static VALUE node_orig(VALUE self) +{ + NODE * n; + Data_Get_Struct(self, NODE, n); + + if(TYPE(n->nd_orig) == T_NODE) + { + if(0 && nd_type(n) == NODE_OP_ASGN2) + { + return wrap_node_as( + (NODE *)n->nd_orig, + rb_cNodeSubclass[NODE_OP_ASGN2_ARG]); + } + else + { + return wrap_node((NODE *)n->nd_orig); + } + } + else + { + return (VALUE)n->nd_orig; + } +} +/* * Return the Node's _recv_ member. The return type is * either a Node or an Object. */ static VALUE node_recv(VALUE self) { @@ -2557,28 +2654,34 @@ { return (VALUE)n->nd_resq; } } /* - * Return the Node's _rest_ member. The return type is a - * Symbol. + * Return the Node's _rest_ member. The return type is + * either a Node or an Object. */ static VALUE node_rest(VALUE self) { NODE * n; Data_Get_Struct(self, NODE, n); - if(n->nd_rest == 0) + + if(TYPE(n->nd_rest) == T_NODE) { - return Qfalse; + if(0 && nd_type(n) == NODE_OP_ASGN2) + { + return wrap_node_as( + (NODE *)n->nd_rest, + rb_cNodeSubclass[NODE_OP_ASGN2_ARG]); + } + else + { + return wrap_node((NODE *)n->nd_rest); + } } - else if(n->nd_rest == 1) - { - return Qtrue; - } else { - return ID2SYM(n->nd_rest); + return (VALUE)n->nd_rest; } } /* * Return the Node's _rval_ member. The return type is * either a Node or an Object. @@ -2820,14 +2923,14 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_ALIAS] = rb_cALIAS; rb_iv_set(rb_cALIAS, "__member__", members); rb_iv_set(rb_cALIAS, "__type__", INT2NUM(NODE_ALIAS)); rb_define_singleton_method(rb_cALIAS, "members", node_s_members, 0); - rb_define_method(rb_cALIAS, "first", node_1st, 0); - rb_ary_push(members, rb_str_new2("first")); rb_define_method(rb_cALIAS, "second", node_2nd, 0); rb_ary_push(members, rb_str_new2("second")); + rb_define_method(rb_cALIAS, "first", node_1st, 0); + rb_ary_push(members, rb_str_new2("first")); } /* Document-class: Node::ALLOCA * A node used for temporary allocation of memory on platforms that do * not support alloca. @@ -2841,16 +2944,10 @@ rb_cNodeSubclass[NODE_ALLOCA] = rb_cALLOCA; rb_iv_set(rb_cALLOCA, "__member__", members); rb_iv_set(rb_cALLOCA, "__type__", INT2NUM(NODE_ALLOCA)); rb_define_singleton_method(rb_cALLOCA, "members", node_s_members, 0); - /* Document-method: cfnc - * a pointer to the allocated memory - */ - rb_define_method(rb_cALLOCA, "cfnc", node_cfnc, 0); - rb_ary_push(members, rb_str_new2("cfnc")); - /* Document-method: value * a pointer to the previously allocated temporary node */ rb_define_method(rb_cALLOCA, "value", node_value, 0); rb_ary_push(members, rb_str_new2("value")); @@ -2858,10 +2955,16 @@ /* Document-method: cnt * the number of bytes allocated */ rb_define_method(rb_cALLOCA, "cnt", node_cnt, 0); rb_ary_push(members, rb_str_new2("cnt")); + + /* Document-method: cfnc + * a pointer to the allocated memory + */ + rb_define_method(rb_cALLOCA, "cfnc", node_cfnc, 0); + rb_ary_push(members, rb_str_new2("cfnc")); } #endif /* Document-class: Node::AND * Represents a logical 'and' of the form: @@ -2906,22 +3009,22 @@ * an assignment node to assign the rest arg, if it is present */ rb_define_method(rb_cARGS, "rest", node_rest, 0); rb_ary_push(members, rb_str_new2("rest")); + /* Document-method: cnt + * the number of required arguments + */ + rb_define_method(rb_cARGS, "cnt", node_cnt, 0); + rb_ary_push(members, rb_str_new2("cnt")); + /* Document-method: opt * a list of assignment nodes to assign default values to the * optional arguments if no argument is specified */ rb_define_method(rb_cARGS, "opt", node_opt, 0); rb_ary_push(members, rb_str_new2("opt")); - - /* Document-method: cnt - * the number of required arguments - */ - rb_define_method(rb_cARGS, "cnt", node_cnt, 0); - rb_ary_push(members, rb_str_new2("cnt")); } /* Document-class: Node::ARGSCAT * Represents the concatenation of a list of arguments and a splatted * value, e.g.: @@ -2983,24 +3086,24 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_ARRAY] = rb_cARRAY; rb_iv_set(rb_cARRAY, "__member__", members); rb_iv_set(rb_cARRAY, "__type__", INT2NUM(NODE_ARRAY)); rb_define_singleton_method(rb_cARRAY, "members", node_s_members, 0); - rb_define_method(rb_cARRAY, "alen", node_alen, 0); - rb_ary_push(members, rb_str_new2("alen")); - /* Document-method: head - * the first element of the array - */ - rb_define_method(rb_cARRAY, "head", node_head, 0); - rb_ary_push(members, rb_str_new2("head")); - /* Document-method: next * the tail of the array */ rb_define_method(rb_cARRAY, "next", node_next, 0); rb_ary_push(members, rb_str_new2("next")); + + /* Document-method: head + * the first element of the array + */ + rb_define_method(rb_cARRAY, "head", node_head, 0); + rb_ary_push(members, rb_str_new2("head")); + rb_define_method(rb_cARRAY, "alen", node_alen, 0); + rb_ary_push(members, rb_str_new2("alen")); } /* Document-class: Node::ATTRASGN * Represents attribute assignment in the form: * recv.mid = args @@ -3013,10 +3116,16 @@ rb_cNodeSubclass[NODE_ATTRASGN] = rb_cATTRASGN; rb_iv_set(rb_cATTRASGN, "__member__", members); rb_iv_set(rb_cATTRASGN, "__type__", INT2NUM(NODE_ATTRASGN)); rb_define_singleton_method(rb_cATTRASGN, "members", node_s_members, 0); + /* Document-method: mid + * the id of the attribute, with a trailing '=' sign + */ + rb_define_method(rb_cATTRASGN, "mid", node_mid, 0); + rb_ary_push(members, rb_str_new2("mid")); + /* Document-method: recv * the receiver of the method */ rb_define_method(rb_cATTRASGN, "recv", node_recv, 0); rb_ary_push(members, rb_str_new2("recv")); @@ -3024,16 +3133,31 @@ /* Document-method: args * the arguments to the method */ rb_define_method(rb_cATTRASGN, "args", node_args, 0); rb_ary_push(members, rb_str_new2("args")); + } - /* Document-method: mid - * the id of the attribute, with a trailing '=' sign + /* Document-class: Node::ATTRSET + * A placeholder for an attribute writer method, which can added to a + * class by using attr_writer: + * attr_writer :attribute + * Its reader counterpart is IVAR. + */ + { + VALUE rb_cATTRSET = rb_define_class_under(rb_cNode, "ATTRSET", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_ATTRSET] = rb_cATTRSET; + rb_iv_set(rb_cATTRSET, "__member__", members); + rb_iv_set(rb_cATTRSET, "__type__", INT2NUM(NODE_ATTRSET)); + rb_define_singleton_method(rb_cATTRSET, "members", node_s_members, 0); + + /* Document-method: vid + * the name of the attribute, with a leading '@' sign */ - rb_define_method(rb_cATTRASGN, "mid", node_mid, 0); - rb_ary_push(members, rb_str_new2("mid")); + rb_define_method(rb_cATTRSET, "vid", node_vid, 0); + rb_ary_push(members, rb_str_new2("vid")); } /* Document-class: Node::BACK_REF * Represents one of the regex back reference variables: * * $& - last match @@ -3096,21 +3220,21 @@ rb_cNodeSubclass[NODE_BLOCK] = rb_cBLOCK; rb_iv_set(rb_cBLOCK, "__member__", members); rb_iv_set(rb_cBLOCK, "__type__", INT2NUM(NODE_BLOCK)); rb_define_singleton_method(rb_cBLOCK, "members", node_s_members, 0); - /* Document-method: head - * the first expression in the block of code - */ - rb_define_method(rb_cBLOCK, "head", node_head, 0); - rb_ary_push(members, rb_str_new2("head")); - /* Document-method: next * the second expression in the block of code */ rb_define_method(rb_cBLOCK, "next", node_next, 0); rb_ary_push(members, rb_str_new2("next")); + + /* Document-method: head + * the first expression in the block of code + */ + rb_define_method(rb_cBLOCK, "head", node_head, 0); + rb_ary_push(members, rb_str_new2("head")); } /* Document-class: Node::BLOCK_ARG * Represents a block argument in a method definition, e.g.: * def foo(&arg) @@ -3214,16 +3338,10 @@ rb_cNodeSubclass[NODE_CALL] = rb_cCALL; rb_iv_set(rb_cCALL, "__member__", members); rb_iv_set(rb_cCALL, "__type__", INT2NUM(NODE_CALL)); rb_define_singleton_method(rb_cCALL, "members", node_s_members, 0); - /* Document-method: args - * the arguments to the method - */ - rb_define_method(rb_cCALL, "args", node_args, 0); - rb_ary_push(members, rb_str_new2("args")); - /* Document-method: mid * the method id */ rb_define_method(rb_cCALL, "mid", node_mid, 0); rb_ary_push(members, rb_str_new2("mid")); @@ -3231,10 +3349,16 @@ /* Document-method: recv * the receiver of the method */ rb_define_method(rb_cCALL, "recv", node_recv, 0); rb_ary_push(members, rb_str_new2("recv")); + + /* Document-method: args + * the arguments to the method + */ + rb_define_method(rb_cCALL, "args", node_args, 0); + rb_ary_push(members, rb_str_new2("args")); } /* Document-class: Node::CASE * Represents the value portion of a case/end block, e.g.: * case head @@ -3247,10 +3371,12 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_CASE] = rb_cCASE; rb_iv_set(rb_cCASE, "__member__", members); rb_iv_set(rb_cCASE, "__type__", INT2NUM(NODE_CASE)); rb_define_singleton_method(rb_cCASE, "members", node_s_members, 0); + rb_define_method(rb_cCASE, "next", node_next, 0); + rb_ary_push(members, rb_str_new2("next")); /* Document-method: head * the value to select on */ rb_define_method(rb_cCASE, "head", node_head, 0); @@ -3260,12 +3386,10 @@ * a linked list of nodes, each node representing a when * conditional */ rb_define_method(rb_cCASE, "body", node_body, 0); rb_ary_push(members, rb_str_new2("body")); - rb_define_method(rb_cCASE, "next", node_next, 0); - rb_ary_push(members, rb_str_new2("next")); } /* Document-class: Node::CDECL * Represents constant assignment of the form: * vid = value @@ -3289,10 +3413,26 @@ */ rb_define_method(rb_cCDECL, "vid", node_vid, 0); rb_ary_push(members, rb_str_new2("vid")); } + /* Document-class: Node::CFUNC + * A placeholder for a function implemented in C. + */ + { + VALUE rb_cCFUNC = rb_define_class_under(rb_cNode, "CFUNC", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_CFUNC] = rb_cCFUNC; + rb_iv_set(rb_cCFUNC, "__member__", members); + rb_iv_set(rb_cCFUNC, "__type__", INT2NUM(NODE_CFUNC)); + rb_define_singleton_method(rb_cCFUNC, "members", node_s_members, 0); + rb_define_method(rb_cCFUNC, "cfnc", node_cfnc, 0); + rb_ary_push(members, rb_str_new2("cfnc")); + rb_define_method(rb_cCFUNC, "argc", node_argc, 0); + rb_ary_push(members, rb_str_new2("argc")); + } + /* Document-class: Node::CLASS * Represents a class definition, e.g.: * class cpath * body * end @@ -3349,21 +3489,21 @@ rb_cNodeSubclass[NODE_COLON2] = rb_cCOLON2; rb_iv_set(rb_cCOLON2, "__member__", members); rb_iv_set(rb_cCOLON2, "__type__", INT2NUM(NODE_COLON2)); rb_define_singleton_method(rb_cCOLON2, "members", node_s_members, 0); - /* Document-method: head - * an expression specifying the class in which to do the lookup - */ - rb_define_method(rb_cCOLON2, "head", node_head, 0); - rb_ary_push(members, rb_str_new2("head")); - /* Document-method: mid * the name of the method or constant to call/look up */ rb_define_method(rb_cCOLON2, "mid", node_mid, 0); rb_ary_push(members, rb_str_new2("mid")); + + /* Document-method: head + * an expression specifying the class in which to do the lookup + */ + rb_define_method(rb_cCOLON2, "head", node_head, 0); + rb_ary_push(members, rb_str_new2("head")); } /* Document-class: Node::COLON3 * Represents a constant lookup or method call in class Object. This * expression has the form: @@ -3402,10 +3542,45 @@ */ rb_define_method(rb_cCONST, "vid", node_vid, 0); rb_ary_push(members, rb_str_new2("vid")); } + /* Document-class: Node::CREF + * A temporary node used to store the value of ruby_cref or + * ruby_top_cref and later restore it. The cref holds a reference to + * the cbase, which, among other things, is used for constant and class + * variable lookup. + * + * It should never be evaluated as an expression. + */ + { + VALUE rb_cCREF = rb_define_class_under(rb_cNode, "CREF", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_CREF] = rb_cCREF; + rb_iv_set(rb_cCREF, "__member__", members); + rb_iv_set(rb_cCREF, "__type__", INT2NUM(NODE_CREF)); + rb_define_singleton_method(rb_cCREF, "members", node_s_members, 0); + + /* Document-method: next + * the previous value of ruby_cref or ruby_top_cref + */ + rb_define_method(rb_cCREF, "next", node_next, 0); + rb_ary_push(members, rb_str_new2("next")); + + /* Document-method: body + * always 0 (false) + */ + rb_define_method(rb_cCREF, "body", node_body, 0); + rb_ary_push(members, rb_str_new2("body")); + + /* Document-method: clss + * the new class to use for the cbase. + */ + rb_define_method(rb_cCREF, "clss", node_clss, 0); + rb_ary_push(members, rb_str_new2("clss")); + } + /* Document-class: Node::CVAR * Represents a class variable retrieval. The result of the expression * is the value of the class variable. */ { @@ -3564,16 +3739,10 @@ rb_cNodeSubclass[NODE_DEFN] = rb_cDEFN; rb_iv_set(rb_cDEFN, "__member__", members); rb_iv_set(rb_cDEFN, "__type__", INT2NUM(NODE_DEFN)); rb_define_singleton_method(rb_cDEFN, "members", node_s_members, 0); - /* Document-method: defn - * the body of the method definition - */ - rb_define_method(rb_cDEFN, "defn", node_defn, 0); - rb_ary_push(members, rb_str_new2("defn")); - /* Document-method: mid * the name of the method* defn the body of the method */ rb_define_method(rb_cDEFN, "mid", node_mid, 0); rb_ary_push(members, rb_str_new2("mid")); @@ -3581,10 +3750,16 @@ /* Document-method: noex * the flags which should be used to define the method */ rb_define_method(rb_cDEFN, "noex", node_noex, 0); rb_ary_push(members, rb_str_new2("noex")); + + /* Document-method: defn + * the body of the method definition + */ + rb_define_method(rb_cDEFN, "defn", node_defn, 0); + rb_ary_push(members, rb_str_new2("defn")); } /* Document-class: Node::DEFS * Represents a singleton method definition, e.g.: * def recv.mid @@ -3596,24 +3771,47 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_DEFS] = rb_cDEFS; rb_iv_set(rb_cDEFS, "__member__", members); rb_iv_set(rb_cDEFS, "__type__", INT2NUM(NODE_DEFS)); rb_define_singleton_method(rb_cDEFS, "members", node_s_members, 0); + + /* Document-method: mid + * the name of the method* defn the body of the method + */ + rb_define_method(rb_cDEFS, "mid", node_mid, 0); + rb_ary_push(members, rb_str_new2("mid")); rb_define_method(rb_cDEFS, "defn", node_defn, 0); rb_ary_push(members, rb_str_new2("defn")); /* Document-method: recv * the object to whose singleton class the new method is to be added */ rb_define_method(rb_cDEFS, "recv", node_recv, 0); rb_ary_push(members, rb_str_new2("recv")); + } - /* Document-method: mid - * the name of the method* defn the body of the method + /* Document-class: Node::DMETHOD + * A placeholder for a method defined using define_method where the + * passed block is created from a Method object, e.g.: + * define_method(:name, method(:foo)) + * + * See also BMETHOD. + */ + { + VALUE rb_cDMETHOD = rb_define_class_under(rb_cNode, "DMETHOD", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_DMETHOD] = rb_cDMETHOD; + rb_iv_set(rb_cDMETHOD, "__member__", members); + rb_iv_set(rb_cDMETHOD, "__type__", INT2NUM(NODE_DMETHOD)); + rb_define_singleton_method(rb_cDMETHOD, "members", node_s_members, 0); + + /* Document-method: cval + * the Method object passed to define_method, which contains the + * body of the method */ - rb_define_method(rb_cDEFS, "mid", node_mid, 0); - rb_ary_push(members, rb_str_new2("mid")); + rb_define_method(rb_cDMETHOD, "cval", node_cval, 0); + rb_ary_push(members, rb_str_new2("cval")); } /* Document-class: Node::DOT2 * Represents a range created with the form: * beg..end @@ -3624,24 +3822,24 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_DOT2] = rb_cDOT2; rb_iv_set(rb_cDOT2, "__member__", members); rb_iv_set(rb_cDOT2, "__type__", INT2NUM(NODE_DOT2)); rb_define_singleton_method(rb_cDOT2, "members", node_s_members, 0); + rb_define_method(rb_cDOT2, "state", node_state, 0); + rb_ary_push(members, rb_str_new2("state")); - /* Document-method: beg - * the beginning of the range - */ - rb_define_method(rb_cDOT2, "beg", node_beg, 0); - rb_ary_push(members, rb_str_new2("beg")); - /* Document-method: end * the end of the range */ rb_define_method(rb_cDOT2, "end", node_end, 0); rb_ary_push(members, rb_str_new2("end")); - rb_define_method(rb_cDOT2, "state", node_state, 0); - rb_ary_push(members, rb_str_new2("state")); + + /* Document-method: beg + * the beginning of the range + */ + rb_define_method(rb_cDOT2, "beg", node_beg, 0); + rb_ary_push(members, rb_str_new2("beg")); } /* Document-class: Node::DOT3 * Represents a range created with the form: * beg...end @@ -3652,24 +3850,24 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_DOT3] = rb_cDOT3; rb_iv_set(rb_cDOT3, "__member__", members); rb_iv_set(rb_cDOT3, "__type__", INT2NUM(NODE_DOT3)); rb_define_singleton_method(rb_cDOT3, "members", node_s_members, 0); + rb_define_method(rb_cDOT3, "state", node_state, 0); + rb_ary_push(members, rb_str_new2("state")); - /* Document-method: beg - * the beginning of the range - */ - rb_define_method(rb_cDOT3, "beg", node_beg, 0); - rb_ary_push(members, rb_str_new2("beg")); - /* Document-method: end * the end of the range */ rb_define_method(rb_cDOT3, "end", node_end, 0); rb_ary_push(members, rb_str_new2("end")); - rb_define_method(rb_cDOT3, "state", node_state, 0); - rb_ary_push(members, rb_str_new2("state")); + + /* Document-method: beg + * the beginning of the range + */ + rb_define_method(rb_cDOT3, "beg", node_beg, 0); + rb_ary_push(members, rb_str_new2("beg")); } /* Document-class: Node::DREGX * Represents a regular expresion with interpolation. The node is * evaluated by duplicating the regex stored in the 'lit' element, then @@ -3921,10 +4119,42 @@ rb_iv_set(rb_cFALSE, "__member__", members); rb_iv_set(rb_cFALSE, "__type__", INT2NUM(NODE_FALSE)); rb_define_singleton_method(rb_cFALSE, "members", node_s_members, 0); } + /* Document-class: Node::FBODY + * A placeholder for a method alias, which can be added to a class by + * using alias or alias_method: + * alias old new + */ + { + VALUE rb_cFBODY = rb_define_class_under(rb_cNode, "FBODY", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_FBODY] = rb_cFBODY; + rb_iv_set(rb_cFBODY, "__member__", members); + rb_iv_set(rb_cFBODY, "__type__", INT2NUM(NODE_FBODY)); + rb_define_singleton_method(rb_cFBODY, "members", node_s_members, 0); + + /* Document-method: orig + * the origin class + */ + rb_define_method(rb_cFBODY, "orig", node_orig, 0); + rb_ary_push(members, rb_str_new2("orig")); + + /* Document-method: mid + * the name of the method + */ + rb_define_method(rb_cFBODY, "mid", node_mid, 0); + rb_ary_push(members, rb_str_new2("mid")); + + /* Document-method: head + * the method body + */ + rb_define_method(rb_cFBODY, "head", node_head, 0); + rb_ary_push(members, rb_str_new2("head")); + } + /* Document-class: Node::FCALL * Represents a method call in the form: * mid(args). * * This makes a method call on an object using self as the implicit @@ -3936,21 +4166,21 @@ rb_cNodeSubclass[NODE_FCALL] = rb_cFCALL; rb_iv_set(rb_cFCALL, "__member__", members); rb_iv_set(rb_cFCALL, "__type__", INT2NUM(NODE_FCALL)); rb_define_singleton_method(rb_cFCALL, "members", node_s_members, 0); - /* Document-method: args - * the arguments to the method - */ - rb_define_method(rb_cFCALL, "args", node_args, 0); - rb_ary_push(members, rb_str_new2("args")); - /* Document-method: mid * the method id */ rb_define_method(rb_cFCALL, "mid", node_mid, 0); rb_ary_push(members, rb_str_new2("mid")); + + /* Document-method: args + * the arguments to the method + */ + rb_define_method(rb_cFCALL, "args", node_args, 0); + rb_ary_push(members, rb_str_new2("args")); } /* Document-class: Node::FLIP2 * Represents part of an awk-like flip-flop expression of the form: * if beg..end then @@ -3970,21 +4200,21 @@ * to use in the flip-flop expression (usually 2 for $_) */ rb_define_method(rb_cFLIP2, "cnt", node_cnt, 0); rb_ary_push(members, rb_str_new2("cnt")); - /* Document-method: beg - * the beginning of the range - */ - rb_define_method(rb_cFLIP2, "beg", node_beg, 0); - rb_ary_push(members, rb_str_new2("beg")); - /* Document-method: end * the end of the range */ rb_define_method(rb_cFLIP2, "end", node_end, 0); rb_ary_push(members, rb_str_new2("end")); + + /* Document-method: beg + * the beginning of the range + */ + rb_define_method(rb_cFLIP2, "beg", node_beg, 0); + rb_ary_push(members, rb_str_new2("beg")); } /* Document-class: Node::FLIP3 * Represents part of a sed-like flip-flop expression of the form: * if beg..end then @@ -4004,21 +4234,21 @@ * to use in the flip-flop expression (usually 2 for $_) */ rb_define_method(rb_cFLIP3, "cnt", node_cnt, 0); rb_ary_push(members, rb_str_new2("cnt")); - /* Document-method: beg - * the beginning of the range - */ - rb_define_method(rb_cFLIP3, "beg", node_beg, 0); - rb_ary_push(members, rb_str_new2("beg")); - /* Document-method: end * the end of the range */ rb_define_method(rb_cFLIP3, "end", node_end, 0); rb_ary_push(members, rb_str_new2("end")); + + /* Document-method: beg + * the beginning of the range + */ + rb_define_method(rb_cFLIP3, "beg", node_beg, 0); + rb_ary_push(members, rb_str_new2("beg")); } /* Document-class: Node::FOR * Represents a loop constructed with the 'for' keyword, e.g.: * for var in iter do @@ -4039,10 +4269,18 @@ rb_cNodeSubclass[NODE_FOR] = rb_cFOR; rb_iv_set(rb_cFOR, "__member__", members); rb_iv_set(rb_cFOR, "__type__", INT2NUM(NODE_FOR)); rb_define_singleton_method(rb_cFOR, "members", node_s_members, 0); + /* Document-method: var + * an assignment node which assigns the next value in the sequence + * to a variable, which may or may not be local. May also be a + * multiple assignment. + */ + rb_define_method(rb_cFOR, "var", node_var, 0); + rb_ary_push(members, rb_str_new2("var")); + /* Document-method: body * the body of the loop */ rb_define_method(rb_cFOR, "body", node_body, 0); rb_ary_push(members, rb_str_new2("body")); @@ -4050,18 +4288,10 @@ /* Document-method: iter * the sequence over which to iterate */ rb_define_method(rb_cFOR, "iter", node_iter, 0); rb_ary_push(members, rb_str_new2("iter")); - - /* Document-method: var - * an assignment node which assigns the next value in the sequence - * to a variable, which may or may not be local. May also be a - * multiple assignment. - */ - rb_define_method(rb_cFOR, "var", node_var, 0); - rb_ary_push(members, rb_str_new2("var")); } /* Document-class: Node::GASGN * Represents global variable assignment. */ @@ -4178,16 +4408,10 @@ rb_cNodeSubclass[NODE_IF] = rb_cIF; rb_iv_set(rb_cIF, "__member__", members); rb_iv_set(rb_cIF, "__type__", INT2NUM(NODE_IF)); rb_define_singleton_method(rb_cIF, "members", node_s_members, 0); - /* Document-method: cond - * the condition to evaluate - */ - rb_define_method(rb_cIF, "cond", node_cond, 0); - rb_ary_push(members, rb_str_new2("cond")); - /* Document-method: body * the expression to evaluate if the expression is true, or false * if the expression is empty */ rb_define_method(rb_cIF, "body", node_body, 0); @@ -4197,10 +4421,16 @@ * the expression to evaluate if the expression is false, or false * if the expression is empty */ rb_define_method(rb_cIF, "else", node_else, 0); rb_ary_push(members, rb_str_new2("else")); + + /* Document-method: cond + * the condition to evaluate + */ + rb_define_method(rb_cIF, "cond", node_cond, 0); + rb_ary_push(members, rb_str_new2("cond")); } /* Document-class: Node::IFUNC * A temporary node used in iteration. */ @@ -4210,28 +4440,28 @@ rb_cNodeSubclass[NODE_IFUNC] = rb_cIFUNC; rb_iv_set(rb_cIFUNC, "__member__", members); rb_iv_set(rb_cIFUNC, "__type__", INT2NUM(NODE_IFUNC)); rb_define_singleton_method(rb_cIFUNC, "members", node_s_members, 0); - /* Document-method: cfnc - * a pointer to the C function to which to yield + /* Document-method: state + * always 0 */ - rb_define_method(rb_cIFUNC, "cfnc", node_cfnc, 0); - rb_ary_push(members, rb_str_new2("cfnc")); + rb_define_method(rb_cIFUNC, "state", node_state, 0); + rb_ary_push(members, rb_str_new2("state")); /* Document-method: tval * the user-specified data to be passed as the second argument to * cfnc */ rb_define_method(rb_cIFUNC, "tval", node_tval, 0); rb_ary_push(members, rb_str_new2("tval")); - /* Document-method: state - * always 0 + /* Document-method: cfnc + * a pointer to the C function to which to yield */ - rb_define_method(rb_cIFUNC, "state", node_state, 0); - rb_ary_push(members, rb_str_new2("state")); + rb_define_method(rb_cIFUNC, "cfnc", node_cfnc, 0); + rb_ary_push(members, rb_str_new2("cfnc")); } /* Document-class: Node::ITER * Represents an iteration loop, e.g.: * iter do |*args| @@ -4251,10 +4481,18 @@ rb_cNodeSubclass[NODE_ITER] = rb_cITER; rb_iv_set(rb_cITER, "__member__", members); rb_iv_set(rb_cITER, "__type__", INT2NUM(NODE_ITER)); rb_define_singleton_method(rb_cITER, "members", node_s_members, 0); + /* Document-method: var + * an assignment node which assigns the next value in the sequence + * to a variable, which may or may not be local. May also be a + * multiple assignment. + */ + rb_define_method(rb_cITER, "var", node_var, 0); + rb_ary_push(members, rb_str_new2("var")); + /* Document-method: body * the body of the loop */ rb_define_method(rb_cITER, "body", node_body, 0); rb_ary_push(members, rb_str_new2("body")); @@ -4263,18 +4501,10 @@ * an expression which calls the desired iteration method, usually * recv.each */ rb_define_method(rb_cITER, "iter", node_iter, 0); rb_ary_push(members, rb_str_new2("iter")); - - /* Document-method: var - * an assignment node which assigns the next value in the sequence - * to a variable, which may or may not be local. May also be a - * multiple assignment. - */ - rb_define_method(rb_cITER, "var", node_var, 0); - rb_ary_push(members, rb_str_new2("var")); } /* Document-class: Node::IVAR * A placeholder for an attribute reader method, which can added to a * class by using attr_reader: @@ -4310,18 +4540,18 @@ /* Document-method: value * the value to assign to the local variable */ rb_define_method(rb_cLASGN, "value", node_value, 0); rb_ary_push(members, rb_str_new2("value")); + rb_define_method(rb_cLASGN, "cnt", node_cnt, 0); + rb_ary_push(members, rb_str_new2("cnt")); /* Document-method: vid * the name of the local variable */ rb_define_method(rb_cLASGN, "vid", node_vid, 0); rb_ary_push(members, rb_str_new2("vid")); - rb_define_method(rb_cLASGN, "cnt", node_cnt, 0); - rb_ary_push(members, rb_str_new2("cnt")); } /* Document-class: Node::LIT * Represents a literal object. The result of the expression is the * object contained in this node. @@ -4349,18 +4579,18 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_LVAR] = rb_cLVAR; rb_iv_set(rb_cLVAR, "__member__", members); rb_iv_set(rb_cLVAR, "__type__", INT2NUM(NODE_LVAR)); rb_define_singleton_method(rb_cLVAR, "members", node_s_members, 0); + rb_define_method(rb_cLVAR, "cnt", node_cnt, 0); + rb_ary_push(members, rb_str_new2("cnt")); /* Document-method: vid * the name of the local variable to retrieve. */ rb_define_method(rb_cLVAR, "vid", node_vid, 0); rb_ary_push(members, rb_str_new2("vid")); - rb_define_method(rb_cLVAR, "cnt", node_cnt, 0); - rb_ary_push(members, rb_str_new2("cnt")); } /* Document-class: Node::MASGN * Represents multiple assignment. */ @@ -4370,27 +4600,27 @@ rb_cNodeSubclass[NODE_MASGN] = rb_cMASGN; rb_iv_set(rb_cMASGN, "__member__", members); rb_iv_set(rb_cMASGN, "__type__", INT2NUM(NODE_MASGN)); rb_define_singleton_method(rb_cMASGN, "members", node_s_members, 0); - /* Document-method: args + /* Document-method: value * TODO */ - rb_define_method(rb_cMASGN, "args", node_args, 0); - rb_ary_push(members, rb_str_new2("args")); + rb_define_method(rb_cMASGN, "value", node_value, 0); + rb_ary_push(members, rb_str_new2("value")); /* Document-method: head * TODO */ rb_define_method(rb_cMASGN, "head", node_head, 0); rb_ary_push(members, rb_str_new2("head")); - /* Document-method: value + /* Document-method: args * TODO */ - rb_define_method(rb_cMASGN, "value", node_value, 0); - rb_ary_push(members, rb_str_new2("value")); + rb_define_method(rb_cMASGN, "args", node_args, 0); + rb_ary_push(members, rb_str_new2("args")); } /* Document-class: Node::MATCH * Represents a regular expression match in a conditional, e.g.: * if /lit/ then @@ -4411,21 +4641,21 @@ rb_cNodeSubclass[NODE_MATCH] = rb_cMATCH; rb_iv_set(rb_cMATCH, "__member__", members); rb_iv_set(rb_cMATCH, "__type__", INT2NUM(NODE_MATCH)); rb_define_singleton_method(rb_cMATCH, "members", node_s_members, 0); - /* Document-method: lit - * the regular expression to use in the condition. - */ - rb_define_method(rb_cMATCH, "lit", node_lit, 0); - rb_ary_push(members, rb_str_new2("lit")); - /* Document-method: value * the value to compare against */ rb_define_method(rb_cMATCH, "value", node_value, 0); rb_ary_push(members, rb_str_new2("value")); + + /* Document-method: lit + * the regular expression to use in the condition. + */ + rb_define_method(rb_cMATCH, "lit", node_lit, 0); + rb_ary_push(members, rb_str_new2("lit")); } /* Document-class: Node::MATCH2 * Represents a match in a conditional with a regular expression using * interpolation, e.g.: @@ -4449,24 +4679,24 @@ rb_cNodeSubclass[NODE_MATCH2] = rb_cMATCH2; rb_iv_set(rb_cMATCH2, "__member__", members); rb_iv_set(rb_cMATCH2, "__type__", INT2NUM(NODE_MATCH2)); rb_define_singleton_method(rb_cMATCH2, "members", node_s_members, 0); - /* Document-method: recv - * the regular expression on the left hand side of the match - * operator - */ - rb_define_method(rb_cMATCH2, "recv", node_recv, 0); - rb_ary_push(members, rb_str_new2("recv")); - /* Document-method: value * the expression on the right hand side of the match operator, or * an expression returning $_ if there is nothing on the right hand * side */ rb_define_method(rb_cMATCH2, "value", node_value, 0); rb_ary_push(members, rb_str_new2("value")); + + /* Document-method: recv + * the regular expression on the left hand side of the match + * operator + */ + rb_define_method(rb_cMATCH2, "recv", node_recv, 0); + rb_ary_push(members, rb_str_new2("recv")); } /* Document-class: Node::MATCH3 * Represents a regular expression match of the form: * recv =~ /value/ @@ -4480,21 +4710,21 @@ rb_cNodeSubclass[NODE_MATCH3] = rb_cMATCH3; rb_iv_set(rb_cMATCH3, "__member__", members); rb_iv_set(rb_cMATCH3, "__type__", INT2NUM(NODE_MATCH3)); rb_define_singleton_method(rb_cMATCH3, "members", node_s_members, 0); - /* Document-method: recv - * the left hand side of the match - */ - rb_define_method(rb_cMATCH3, "recv", node_recv, 0); - rb_ary_push(members, rb_str_new2("recv")); - /* Document-method: value * the right hand side of the match */ rb_define_method(rb_cMATCH3, "value", node_value, 0); rb_ary_push(members, rb_str_new2("value")); + + /* Document-method: recv + * the left hand side of the match + */ + rb_define_method(rb_cMATCH3, "recv", node_recv, 0); + rb_ary_push(members, rb_str_new2("recv")); } /* Document-class: Node::MEMO * A node used for temporary storage. * @@ -4516,10 +4746,34 @@ rb_iv_set(rb_cMEMO, "__member__", members); rb_iv_set(rb_cMEMO, "__type__", INT2NUM(NODE_MEMO)); rb_define_singleton_method(rb_cMEMO, "members", node_s_members, 0); } + /* Document-class: Node::METHOD + * A placeholder for a method entry in a class's method table. + */ + { + VALUE rb_cMETHOD = rb_define_class_under(rb_cNode, "METHOD", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_METHOD] = rb_cMETHOD; + rb_iv_set(rb_cMETHOD, "__member__", members); + rb_iv_set(rb_cMETHOD, "__type__", INT2NUM(NODE_METHOD)); + rb_define_singleton_method(rb_cMETHOD, "members", node_s_members, 0); + + /* Document-method: noex + * the method's flags + */ + rb_define_method(rb_cMETHOD, "noex", node_noex, 0); + rb_ary_push(members, rb_str_new2("noex")); + + /* Document-method: body + * the body of the method + */ + rb_define_method(rb_cMETHOD, "body", node_body, 0); + rb_ary_push(members, rb_str_new2("body")); + } + /* Document-class: Node::MODULE * Represents a module definition, e.g.: * module cpath * body * end @@ -4548,10 +4802,29 @@ */ rb_define_method(rb_cMODULE, "body", node_body, 0); rb_ary_push(members, rb_str_new2("body")); } + /* Document-class: Node::NEWLINE + * Represents the termination of a line. This is used for calling + * event hooks when a new line of code is reached. + */ + { + VALUE rb_cNEWLINE = rb_define_class_under(rb_cNode, "NEWLINE", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_NEWLINE] = rb_cNEWLINE; + rb_iv_set(rb_cNEWLINE, "__member__", members); + rb_iv_set(rb_cNEWLINE, "__type__", INT2NUM(NODE_NEWLINE)); + rb_define_singleton_method(rb_cNEWLINE, "members", node_s_members, 0); + + /* Document-method: next + * the expression on the next line + */ + rb_define_method(rb_cNEWLINE, "next", node_next, 0); + rb_ary_push(members, rb_str_new2("next")); + } + /* Document-class: Node::NEXT * Represents the 'next' keyword. * Causes control to be transferred to the end of the loop, causing the * next value in the sequence to be retrieved. */ @@ -4576,10 +4849,28 @@ rb_iv_set(rb_cNIL, "__member__", members); rb_iv_set(rb_cNIL, "__type__", INT2NUM(NODE_NIL)); rb_define_singleton_method(rb_cNIL, "members", node_s_members, 0); } + /* Document-class: Node::NOT + * Represents a logical negation. + */ + { + VALUE rb_cNOT = rb_define_class_under(rb_cNode, "NOT", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_NOT] = rb_cNOT; + rb_iv_set(rb_cNOT, "__member__", members); + rb_iv_set(rb_cNOT, "__type__", INT2NUM(NODE_NOT)); + rb_define_singleton_method(rb_cNOT, "members", node_s_members, 0); + + /* Document-method: body + * the value to negate. + */ + rb_define_method(rb_cNOT, "body", node_body, 0); + rb_ary_push(members, rb_str_new2("body")); + } + /* Document-class: Node::NTH_REF * Represents the nth match data item, e.g. $1, $2, etc. */ { VALUE rb_cNTH_REF = rb_define_class_under(rb_cNode, "NTH_REF", rb_cNode); @@ -4650,16 +4941,10 @@ rb_cNodeSubclass[NODE_OP_ASGN1] = rb_cOP_ASGN1; rb_iv_set(rb_cOP_ASGN1, "__member__", members); rb_iv_set(rb_cOP_ASGN1, "__type__", INT2NUM(NODE_OP_ASGN1)); rb_define_singleton_method(rb_cOP_ASGN1, "members", node_s_members, 0); - /* Document-method: args - * the arguments to the assigment - */ - rb_define_method(rb_cOP_ASGN1, "args", node_args, 0); - rb_ary_push(members, rb_str_new2("args")); - /* Document-method: mid * 0, 1, or the name a method to call to calculate the value of the * rhs */ rb_define_method(rb_cOP_ASGN1, "mid", node_mid, 0); @@ -4668,10 +4953,16 @@ /* Document-method: recv * the receiver of the assignment */ rb_define_method(rb_cOP_ASGN1, "recv", node_recv, 0); rb_ary_push(members, rb_str_new2("recv")); + + /* Document-method: args + * the arguments to the assigment + */ + rb_define_method(rb_cOP_ASGN1, "args", node_args, 0); + rb_ary_push(members, rb_str_new2("args")); } /* Document-class: Node::OP_ASGN2 * Represents attribute assignment of the form: * recv.attr op value @@ -4690,28 +4981,28 @@ rb_cNodeSubclass[NODE_OP_ASGN2] = rb_cOP_ASGN2; rb_iv_set(rb_cOP_ASGN2, "__member__", members); rb_iv_set(rb_cOP_ASGN2, "__type__", INT2NUM(NODE_OP_ASGN2)); rb_define_singleton_method(rb_cOP_ASGN2, "members", node_s_members, 0); - /* Document-method: recv - * the receiver of the attribute + /* Document-method: value + * the value to assign to the attribute */ - rb_define_method(rb_cOP_ASGN2, "recv", node_recv, 0); - rb_ary_push(members, rb_str_new2("recv")); + rb_define_method(rb_cOP_ASGN2, "value", node_value, 0); + rb_ary_push(members, rb_str_new2("value")); /* Document-method: next * another node of type OP_ASGN2 which contains more information * about the assignment operation than can fit in this node alone */ rb_define_method(rb_cOP_ASGN2, "next", node_next, 0); rb_ary_push(members, rb_str_new2("next")); - /* Document-method: value - * the value to assign to the attribute + /* Document-method: recv + * the receiver of the attribute */ - rb_define_method(rb_cOP_ASGN2, "value", node_value, 0); - rb_ary_push(members, rb_str_new2("value")); + rb_define_method(rb_cOP_ASGN2, "recv", node_recv, 0); + rb_ary_push(members, rb_str_new2("recv")); } /* Document-class: Node::OP_ASGN2_ARG * Actually a node of type OP_ASGN2, this is a placeholder for * additional information about the assignment than can fit in a single @@ -4723,16 +5014,10 @@ rb_cNodeSubclass[NODE_OP_ASGN2_ARG] = rb_cOP_ASGN2_ARG; rb_iv_set(rb_cOP_ASGN2_ARG, "__member__", members); rb_iv_set(rb_cOP_ASGN2_ARG, "__type__", INT2NUM(NODE_OP_ASGN2_ARG)); rb_define_singleton_method(rb_cOP_ASGN2_ARG, "members", node_s_members, 0); - /* Document-method: vid - * The method to call on the receiver to retrieve the attribute - */ - rb_define_method(rb_cOP_ASGN2_ARG, "vid", node_vid, 0); - rb_ary_push(members, rb_str_new2("vid")); - /* Document-method: aid * The method to call on the receiver to set the attribute */ rb_define_method(rb_cOP_ASGN2_ARG, "aid", node_aid, 0); rb_ary_push(members, rb_str_new2("aid")); @@ -4742,10 +5027,16 @@ * be 0 (false) to indicate "logical or" or 1 (nil) to indicate * "logical and". */ rb_define_method(rb_cOP_ASGN2_ARG, "mid", node_mid, 0); rb_ary_push(members, rb_str_new2("mid")); + + /* Document-method: vid + * The method to call on the receiver to retrieve the attribute + */ + rb_define_method(rb_cOP_ASGN2_ARG, "vid", node_vid, 0); + rb_ary_push(members, rb_str_new2("vid")); } /* Document-class: Node::OP_ASGN_AND * Represents an expression of the form: * recv &&= value @@ -4760,22 +5051,22 @@ rb_cNodeSubclass[NODE_OP_ASGN_AND] = rb_cOP_ASGN_AND; rb_iv_set(rb_cOP_ASGN_AND, "__member__", members); rb_iv_set(rb_cOP_ASGN_AND, "__type__", INT2NUM(NODE_OP_ASGN_AND)); rb_define_singleton_method(rb_cOP_ASGN_AND, "members", node_s_members, 0); - /* Document-method: recv - * an expression representing the left hand side of the assignment - */ - rb_define_method(rb_cOP_ASGN_AND, "recv", node_recv, 0); - rb_ary_push(members, rb_str_new2("recv")); - /* Document-method: value * an expression representing the assignment that should be * performed if the left hand side is true */ rb_define_method(rb_cOP_ASGN_AND, "value", node_value, 0); rb_ary_push(members, rb_str_new2("value")); + + /* Document-method: recv + * an expression representing the left hand side of the assignment + */ + rb_define_method(rb_cOP_ASGN_AND, "recv", node_recv, 0); + rb_ary_push(members, rb_str_new2("recv")); } /* Document-class: Node::OP_ASGN_OR * Represents an expression of the form: * recv ||= value @@ -4944,22 +5235,22 @@ rb_cNodeSubclass[NODE_RESCUE] = rb_cRESCUE; rb_iv_set(rb_cRESCUE, "__member__", members); rb_iv_set(rb_cRESCUE, "__type__", INT2NUM(NODE_RESCUE)); rb_define_singleton_method(rb_cRESCUE, "members", node_s_members, 0); - /* Document-method: head - * the body of the block to evaluate - */ - rb_define_method(rb_cRESCUE, "head", node_head, 0); - rb_ary_push(members, rb_str_new2("head")); - /* Document-method: resq * the expression to be evaluated if an exception is raised */ rb_define_method(rb_cRESCUE, "resq", node_resq, 0); rb_ary_push(members, rb_str_new2("resq")); + /* Document-method: head + * the body of the block to evaluate + */ + rb_define_method(rb_cRESCUE, "head", node_head, 0); + rb_ary_push(members, rb_str_new2("head")); + /* Document-method: else * the expression to be evaluated if no exception is raised */ rb_define_method(rb_cRESCUE, "else", node_else, 0); rb_ary_push(members, rb_str_new2("else")); @@ -5057,22 +5348,22 @@ * the scope */ rb_define_method(rb_cSCOPE, "tbl", node_tbl, 0); rb_ary_push(members, rb_str_new2("tbl")); + /* Document-method: next + * the body of the lexical scope + */ + rb_define_method(rb_cSCOPE, "next", node_next, 0); + rb_ary_push(members, rb_str_new2("next")); + /* Document-method: rval * holds information about which class(es) to search for constants * in this scope */ rb_define_method(rb_cSCOPE, "rval", node_rval, 0); rb_ary_push(members, rb_str_new2("rval")); - - /* Document-method: next - * the body of the lexical scope - */ - rb_define_method(rb_cSCOPE, "next", node_next, 0); - rb_ary_push(members, rb_str_new2("next")); } /* Document-class: Node::SELF * Represents the keyword 'self'. */ @@ -5143,10 +5434,35 @@ */ rb_define_method(rb_cSUPER, "args", node_args, 0); rb_ary_push(members, rb_str_new2("args")); } + /* Document-class: Node::SVALUE + * Represents the collection of multiple values of the right hand side + * of an assignment into a single value, for use in single assignment, + * e.g.: + * lhs = a, b, c + * The argument to this node is an Array. + * If it is length 0, returns nil. + * If it is length 1, returns the first element in the array. + * Otherwise, returns the array. + */ + { + VALUE rb_cSVALUE = rb_define_class_under(rb_cNode, "SVALUE", rb_cNode); + members = rb_ary_new(); + rb_cNodeSubclass[NODE_SVALUE] = rb_cSVALUE; + rb_iv_set(rb_cSVALUE, "__member__", members); + rb_iv_set(rb_cSVALUE, "__type__", INT2NUM(NODE_SVALUE)); + rb_define_singleton_method(rb_cSVALUE, "members", node_s_members, 0); + + /* Document-method: head + * an expression which returns an Array. + */ + rb_define_method(rb_cSVALUE, "head", node_head, 0); + rb_ary_push(members, rb_str_new2("head")); + } + /* Document-class: Node::TO_ARY * Represents a conversion from one object type to an array type. * Evaluation of this node converts its argument to an array by calling * \#to_ary on the argument. */ @@ -5210,10 +5526,12 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_UNTIL] = rb_cUNTIL; rb_iv_set(rb_cUNTIL, "__member__", members); rb_iv_set(rb_cUNTIL, "__type__", INT2NUM(NODE_UNTIL)); rb_define_singleton_method(rb_cUNTIL, "members", node_s_members, 0); + rb_define_method(rb_cUNTIL, "state", node_state, 0); + rb_ary_push(members, rb_str_new2("state")); /* Document-method: body * the body of the loop */ rb_define_method(rb_cUNTIL, "body", node_body, 0); @@ -5222,12 +5540,10 @@ /* Document-method: cond * a condition to terminate the loop when it becomes true */ rb_define_method(rb_cUNTIL, "cond", node_cond, 0); rb_ary_push(members, rb_str_new2("cond")); - rb_define_method(rb_cUNTIL, "state", node_state, 0); - rb_ary_push(members, rb_str_new2("state")); } /* Document-class: Node::VALIAS * Represents an alias expression of the form: * alias 1st 2nd @@ -5239,14 +5555,14 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_VALIAS] = rb_cVALIAS; rb_iv_set(rb_cVALIAS, "__member__", members); rb_iv_set(rb_cVALIAS, "__type__", INT2NUM(NODE_VALIAS)); rb_define_singleton_method(rb_cVALIAS, "members", node_s_members, 0); - rb_define_method(rb_cVALIAS, "first", node_1st, 0); - rb_ary_push(members, rb_str_new2("first")); rb_define_method(rb_cVALIAS, "second", node_2nd, 0); rb_ary_push(members, rb_str_new2("second")); + rb_define_method(rb_cVALIAS, "first", node_1st, 0); + rb_ary_push(members, rb_str_new2("first")); } /* Document-class: Node::VCALL * Represents a local variable or a method call without an explicit * receiver, to be determined at run-time. @@ -5302,10 +5618,16 @@ rb_cNodeSubclass[NODE_WHEN] = rb_cWHEN; rb_iv_set(rb_cWHEN, "__member__", members); rb_iv_set(rb_cWHEN, "__type__", INT2NUM(NODE_WHEN)); rb_define_singleton_method(rb_cWHEN, "members", node_s_members, 0); + /* Document-method: next + * the next expression to be evaluated if the condition is false + */ + rb_define_method(rb_cWHEN, "next", node_next, 0); + rb_ary_push(members, rb_str_new2("next")); + /* Document-method: head * a value to compare against, or a condition to be tested */ rb_define_method(rb_cWHEN, "head", node_head, 0); rb_ary_push(members, rb_str_new2("head")); @@ -5313,16 +5635,10 @@ /* Document-method: body * an expression to evaluate if the condition evaluates to true */ rb_define_method(rb_cWHEN, "body", node_body, 0); rb_ary_push(members, rb_str_new2("body")); - - /* Document-method: next - * the next expression to be evaluated if the condition is false - */ - rb_define_method(rb_cWHEN, "next", node_next, 0); - rb_ary_push(members, rb_str_new2("next")); } /* Document-class: Node::WHILE * Represents a loop constructed with the 'while' keyword, e.g.: * while cond do @@ -5334,10 +5650,12 @@ members = rb_ary_new(); rb_cNodeSubclass[NODE_WHILE] = rb_cWHILE; rb_iv_set(rb_cWHILE, "__member__", members); rb_iv_set(rb_cWHILE, "__type__", INT2NUM(NODE_WHILE)); rb_define_singleton_method(rb_cWHILE, "members", node_s_members, 0); + rb_define_method(rb_cWHILE, "state", node_state, 0); + rb_ary_push(members, rb_str_new2("state")); /* Document-method: body * the body of the loop */ rb_define_method(rb_cWHILE, "body", node_body, 0); @@ -5346,12 +5664,10 @@ /* Document-method: cond * a condition to terminate the loop when it becomes false */ rb_define_method(rb_cWHILE, "cond", node_cond, 0); rb_ary_push(members, rb_str_new2("cond")); - rb_define_method(rb_cWHILE, "state", node_state, 0); - rb_ary_push(members, rb_str_new2("state")); } /* Document-class: Node::XSTR * Represents a string object inside backticks, e.g.: * `lit` @@ -5384,20 +5700,20 @@ rb_cNodeSubclass[NODE_YIELD] = rb_cYIELD; rb_iv_set(rb_cYIELD, "__member__", members); rb_iv_set(rb_cYIELD, "__type__", INT2NUM(NODE_YIELD)); rb_define_singleton_method(rb_cYIELD, "members", node_s_members, 0); - /* Document-method: head - * the value to yield - */ - rb_define_method(rb_cYIELD, "head", node_head, 0); - rb_ary_push(members, rb_str_new2("head")); - /* Document-method: state * if nonzero, splats the value before yielding */ rb_define_method(rb_cYIELD, "state", node_state, 0); rb_ary_push(members, rb_str_new2("state")); + + /* Document-method: head + * the value to yield + */ + rb_define_method(rb_cYIELD, "head", node_head, 0); + rb_ary_push(members, rb_str_new2("head")); } /* Document-class: Node::ZARRAY * Represents an array of zero elements. Evalation of this node * creates a new array of length zero.