ext/cached/ruby-1.8.4/internal/node/nodeinfo.c in ruby-internal-0.6.0 vs ext/cached/ruby-1.8.4/internal/node/nodeinfo.c in ruby-internal-0.7.0
- old
+ new
@@ -2893,92 +2893,90 @@
{
rb_cNodeSubclass[j] = Qnil;
}
- /* Document-class: Node::DASGN_CURR
- * Represents dynamic local variable assignment in the current frame.
- * See DASGN for a description of how dynamic assignment works.
+ /* Document-class: Node::ALIAS
+ * Represents an alias expression of the form:
+ * alias 1st 2nd
+ * where 2nd is the name of an existing method and 1st is the name of
+ * its new alias.
*/
{
- VALUE rb_cDASGN_CURR = rb_define_class_under(rb_cNode, "DASGN_CURR", rb_cNode);
+ VALUE rb_cALIAS = rb_define_class_under(rb_cNode, "ALIAS", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_DASGN_CURR] = rb_cDASGN_CURR;
- rb_iv_set(rb_cDASGN_CURR, "__member__", members);
- rb_iv_set(rb_cDASGN_CURR, "__type__", INT2NUM(NODE_DASGN_CURR));
- rb_define_singleton_method(rb_cDASGN_CURR, "members", node_s_members, 0);
-
- /* Document-method: value
- * the value to assign to the local variable
- */
- rb_define_method(rb_cDASGN_CURR, "value", node_value, 0);
- rb_ary_push(members, rb_str_new2("value"));
-
- /* Document-method: vid
- * the name of the local variable
- */
- rb_define_method(rb_cDASGN_CURR, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ 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"));
}
- /* Document-class: Node::UNTIL
- * Represents a loop constructed with the 'until' keyword, e.g.:
- * until cond do
- * body
- * end
+ /* Document-class: Node::ALLOCA
+ * A node used for temporary allocation of memory on platforms that do
+ * not support alloca.
+ *
+ * It should never be evaluated as an expression.
*/
+#ifdef HAVE_NODE_ALLOCA
{
- VALUE rb_cUNTIL = rb_define_class_under(rb_cNode, "UNTIL", rb_cNode);
+ VALUE rb_cALLOCA = rb_define_class_under(rb_cNode, "ALLOCA", rb_cNode);
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_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: body
- * the body of the loop
+ /* Document-method: cfnc
+ * a pointer to the allocated memory
*/
- rb_define_method(rb_cUNTIL, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cALLOCA, "cfnc", node_cfnc, 0);
+ rb_ary_push(members, rb_str_new2("cfnc"));
- /* Document-method: cond
- * a condition to terminate the loop when it becomes true
+ /* Document-method: value
+ * a pointer to the previously allocated temporary node
*/
- 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"));
+ rb_define_method(rb_cALLOCA, "value", node_value, 0);
+ rb_ary_push(members, rb_str_new2("value"));
+
+ /* 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"));
}
+#endif
- /* Document-class: Node::BACK_REF
- * Represents one of the regex back reference variables:
- * * $& - last match
- * * $` - pre
- * * $' - post
- * * $+ - last
+ /* Document-class: Node::AND
+ * Represents a logical 'and' of the form:
+ * first && second
+ * The expression will short-circuit and yield the result of the left
+ * hand side if it is false or nil, else it will evaluate the right
+ * hand side and use it as the result of the expression.
*/
{
- VALUE rb_cBACK_REF = rb_define_class_under(rb_cNode, "BACK_REF", rb_cNode);
+ VALUE rb_cAND = rb_define_class_under(rb_cNode, "AND", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_BACK_REF] = rb_cBACK_REF;
- rb_iv_set(rb_cBACK_REF, "__member__", members);
- rb_iv_set(rb_cBACK_REF, "__type__", INT2NUM(NODE_BACK_REF));
- rb_define_singleton_method(rb_cBACK_REF, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_AND] = rb_cAND;
+ rb_iv_set(rb_cAND, "__member__", members);
+ rb_iv_set(rb_cAND, "__type__", INT2NUM(NODE_AND));
+ rb_define_singleton_method(rb_cAND, "members", node_s_members, 0);
- /* Document-method: nth
- * the integer representation of the character of the variable to
- * reference, one of '&', '`', '\'', or '+'
+ /* Document-method: first
+ * the expression on the left hand side
*/
- rb_define_method(rb_cBACK_REF, "nth", node_nth, 0);
- rb_ary_push(members, rb_str_new2("nth"));
+ rb_define_method(rb_cAND, "first", node_1st, 0);
+ rb_ary_push(members, rb_str_new2("first"));
- /* Document-method: cnt
- * the index into the local variable table where the match data is
- * stored
+ /* Document-method: second
+ * the expression on the right hand side
*/
- rb_define_method(rb_cBACK_REF, "cnt", node_cnt, 0);
- rb_ary_push(members, rb_str_new2("cnt"));
+ rb_define_method(rb_cAND, "second", node_2nd, 0);
+ rb_ary_push(members, rb_str_new2("second"));
}
/* Document-class: Node::ARGS
* Represents the arguments to a method.
*/
@@ -3008,224 +3006,187 @@
*/
rb_define_method(rb_cARGS, "cnt", node_cnt, 0);
rb_ary_push(members, rb_str_new2("cnt"));
}
- /* Document-class: Node::OP_ASGN_AND
- * Represents an expression of the form:
- * recv &&= value
- * Ruby will evaluate the expression on the left hand side of the
- * assignment; if it is true, then it will assign the result of the
- * expression on the right hand side to the receiver on the left hand
- * side.
+ /* Document-class: Node::ARGSCAT
+ * Represents the concatenation of a list of arguments and a splatted
+ * value, e.g.:
+ * a, b, *value
+ * Evaluates head to create an array. Evaluates body and performs a
+ * splat operation on the result to create another array (see SPLAT).
+ * Concatenates the the second array onto the end of the first to
+ * produce the result.
*/
{
- VALUE rb_cOP_ASGN_AND = rb_define_class_under(rb_cNode, "OP_ASGN_AND", rb_cNode);
+ VALUE rb_cARGSCAT = rb_define_class_under(rb_cNode, "ARGSCAT", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_ARGSCAT] = rb_cARGSCAT;
+ rb_iv_set(rb_cARGSCAT, "__member__", members);
+ rb_iv_set(rb_cARGSCAT, "__type__", INT2NUM(NODE_ARGSCAT));
+ rb_define_singleton_method(rb_cARGSCAT, "members", node_s_members, 0);
- /* Document-method: value
- * an expression representing the assignment that should be
- * performed if the left hand side is true
+ /* Document-method: head
+ * a list of fixed arguments
*/
- rb_define_method(rb_cOP_ASGN_AND, "value", node_value, 0);
- rb_ary_push(members, rb_str_new2("value"));
+ rb_define_method(rb_cARGSCAT, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
- /* Document-method: recv
- * an expression representing the left hand side of the assignment
+ /* Document-method: body
+ * the last argument, which will be splatted onto the end of the
+ * fixed arguments
*/
- rb_define_method(rb_cOP_ASGN_AND, "recv", node_recv, 0);
- rb_ary_push(members, rb_str_new2("recv"));
+ rb_define_method(rb_cARGSCAT, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
}
- /* Document-class: Node::RETURN
- * Represents the 'return' keyword. Evaluation of this node results in
- * a return from the current method. If no argument is supplied,
- * returns nil, otherwise returns the result of the supplied
- * expression.
+ /* Document-class: Node::ARGSPUSH
+ * Represents the splat portion of the index in an expression:
+ * obj[arg, arg, *head] = body
+ * Evaluates head to create an array. Evaluates body and pushes the
+ * result onto the end of the array, which will then be used to form
+ * the arguments of the method call.
*/
{
- VALUE rb_cRETURN = rb_define_class_under(rb_cNode, "RETURN", rb_cNode);
+ VALUE rb_cARGSPUSH = rb_define_class_under(rb_cNode, "ARGSPUSH", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_RETURN] = rb_cRETURN;
- rb_iv_set(rb_cRETURN, "__member__", members);
- rb_iv_set(rb_cRETURN, "__type__", INT2NUM(NODE_RETURN));
- rb_define_singleton_method(rb_cRETURN, "members", node_s_members, 0);
-
- /* Document-method: stts
- * an expression representing the value to return
- */
- rb_define_method(rb_cRETURN, "stts", node_stts, 0);
- rb_ary_push(members, rb_str_new2("stts"));
+ rb_cNodeSubclass[NODE_ARGSPUSH] = rb_cARGSPUSH;
+ rb_iv_set(rb_cARGSPUSH, "__member__", members);
+ rb_iv_set(rb_cARGSPUSH, "__type__", INT2NUM(NODE_ARGSPUSH));
+ rb_define_singleton_method(rb_cARGSPUSH, "members", node_s_members, 0);
+ rb_define_method(rb_cARGSPUSH, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
+ rb_define_method(rb_cARGSPUSH, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
}
- /* Document-class: Node::RESCUE
- * Represents part of a rescue expression of the form:
- * head rescue expr
- *
- * or the longer form:
- * begin
- * head
- * rescue exception
- * expr
- * end
- *
- * or the form using the else keyword:
- * begin
- * head
- * rescue exception
- * expr
- * else
- * else_expr
- * end
- *
- * The head expression is first evaluated, and if an exception is
- * raised, evaluates the resq node. If no exception is raised, the
- * else node is evaluated if it is not false (0).
- *
- * The resq node will be a RESBDOY node, which will test the exception
- * to see if it matches one of the expected types. If it does it will
- * handle the exception, otherwise it will allow the expression to pass
- * to the outer scope.
+ /* Document-class: Node::ARRAY
+ * Represents an array of elements. Evaluation of this node creates a
+ * new Array by evalating the given expressions and placing them into
+ * the array.
*/
{
- VALUE rb_cRESCUE = rb_define_class_under(rb_cNode, "RESCUE", rb_cNode);
+ VALUE rb_cARRAY = rb_define_class_under(rb_cNode, "ARRAY", rb_cNode);
members = rb_ary_new();
- 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);
+ 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);
/* Document-method: head
- * the body of the block to evaluate
+ * the first element of the array
*/
- rb_define_method(rb_cRESCUE, "head", node_head, 0);
+ 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-method: else
- * the expression to be evaluated if no exception is raised
+ /* Document-method: next
+ * the tail of the array
*/
- rb_define_method(rb_cRESCUE, "else", node_else, 0);
- rb_ary_push(members, rb_str_new2("else"));
-
- /* 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"));
+ rb_define_method(rb_cARRAY, "next", node_next, 0);
+ rb_ary_push(members, rb_str_new2("next"));
}
- /* Document-class: Node::LIT
- * Represents a literal object. The result of the expression is the
- * object contained in this node.
+ /* Document-class: Node::ATTRASGN
+ * Represents attribute assignment in the form:
+ * recv.mid = args
+ * or:
+ * recv.mid=(args).
*/
{
- VALUE rb_cLIT = rb_define_class_under(rb_cNode, "LIT", rb_cNode);
+ VALUE rb_cATTRASGN = rb_define_class_under(rb_cNode, "ATTRASGN", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_LIT] = rb_cLIT;
- rb_iv_set(rb_cLIT, "__member__", members);
- rb_iv_set(rb_cLIT, "__type__", INT2NUM(NODE_LIT));
- rb_define_singleton_method(rb_cLIT, "members", node_s_members, 0);
+ 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: lit
- * the object
+ /* Document-method: args
+ * the arguments to the method
*/
- rb_define_method(rb_cLIT, "lit", node_lit, 0);
- rb_ary_push(members, rb_str_new2("lit"));
+ 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
+ */
+ 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"));
}
- /* Document-class: Node::SELF
- * Represents the keyword 'self'.
+ /* 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_cSELF = rb_define_class_under(rb_cNode, "SELF", rb_cNode);
+ VALUE rb_cATTRSET = rb_define_class_under(rb_cNode, "ATTRSET", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_SELF] = rb_cSELF;
- rb_iv_set(rb_cSELF, "__member__", members);
- rb_iv_set(rb_cSELF, "__type__", INT2NUM(NODE_SELF));
- rb_define_singleton_method(rb_cSELF, "members", node_s_members, 0);
+ 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_cATTRSET, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::IFUNC
- * A temporary node used in iteration.
+ /* Document-class: Node::BACK_REF
+ * Represents one of the regex back reference variables:
+ * * $& - last match
+ * * $` - pre
+ * * $' - post
+ * * $+ - last
*/
{
- VALUE rb_cIFUNC = rb_define_class_under(rb_cNode, "IFUNC", rb_cNode);
+ VALUE rb_cBACK_REF = rb_define_class_under(rb_cNode, "BACK_REF", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_BACK_REF] = rb_cBACK_REF;
+ rb_iv_set(rb_cBACK_REF, "__member__", members);
+ rb_iv_set(rb_cBACK_REF, "__type__", INT2NUM(NODE_BACK_REF));
+ rb_define_singleton_method(rb_cBACK_REF, "members", node_s_members, 0);
- /* Document-method: cfnc
- * a pointer to the C function to which to yield
+ /* Document-method: nth
+ * the integer representation of the character of the variable to
+ * reference, one of '&', '`', '\'', or '+'
*/
- rb_define_method(rb_cIFUNC, "cfnc", node_cfnc, 0);
- rb_ary_push(members, rb_str_new2("cfnc"));
+ rb_define_method(rb_cBACK_REF, "nth", node_nth, 0);
+ rb_ary_push(members, rb_str_new2("nth"));
- /* Document-method: tval
- * the user-specified data to be passed as the second argument to
- * cfnc
+ /* Document-method: cnt
+ * the index into the local variable table where the match data is
+ * stored
*/
- rb_define_method(rb_cIFUNC, "tval", node_tval, 0);
- rb_ary_push(members, rb_str_new2("tval"));
-
- /* Document-method: state
- * always 0
- */
- rb_define_method(rb_cIFUNC, "state", node_state, 0);
- rb_ary_push(members, rb_str_new2("state"));
+ rb_define_method(rb_cBACK_REF, "cnt", node_cnt, 0);
+ rb_ary_push(members, rb_str_new2("cnt"));
}
- /* Document-class: Node::ZSUPER
- * Represents the keyword 'super' when used without parens nor
- * arguments. The arguments to the base class method are obtained from
- * the arguments passed to the current method, which are store in the
- * current frame.
+ /* Document-class: Node::BEGIN
+ * Represents a begin/end block.
*
- * Can also be a placeholder for a method when its implementation is
- * deferred to the base class.
+ * TODO: Need an example
*/
{
- VALUE rb_cZSUPER = rb_define_class_under(rb_cNode, "ZSUPER", rb_cNode);
+ VALUE rb_cBEGIN = rb_define_class_under(rb_cNode, "BEGIN", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_ZSUPER] = rb_cZSUPER;
- rb_iv_set(rb_cZSUPER, "__member__", members);
- rb_iv_set(rb_cZSUPER, "__type__", INT2NUM(NODE_ZSUPER));
- rb_define_singleton_method(rb_cZSUPER, "members", node_s_members, 0);
- }
-
- /* Document-class: Node::WHILE
- * Represents a loop constructed with the 'while' keyword, e.g.:
- * while cond do
- * body
- * end
- */
- {
- VALUE rb_cWHILE = rb_define_class_under(rb_cNode, "WHILE", rb_cNode);
- 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);
-
- /* Document-method: body
- * the body of the loop
- */
- rb_define_method(rb_cWHILE, "body", node_body, 0);
+ rb_cNodeSubclass[NODE_BEGIN] = rb_cBEGIN;
+ rb_iv_set(rb_cBEGIN, "__member__", members);
+ rb_iv_set(rb_cBEGIN, "__type__", INT2NUM(NODE_BEGIN));
+ rb_define_singleton_method(rb_cBEGIN, "members", node_s_members, 0);
+ rb_define_method(rb_cBEGIN, "body", node_body, 0);
rb_ary_push(members, rb_str_new2("body"));
-
- /* 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::BLOCK
* Represents a block of code (a succession of multiple expressions).
* A single block node can hold two expressions: one expression to be
@@ -3255,142 +3216,248 @@
*/
rb_define_method(rb_cBLOCK, "next", node_next, 0);
rb_ary_push(members, rb_str_new2("next"));
}
- /* Document-class: Node::FCALL
- * Represents a method call in the form:
- * mid(args).
+ /* Document-class: Node::BLOCK_ARG
+ * Represents a block argument in a method definition, e.g.:
+ * def foo(&arg)
+ * end
+ */
+ {
+ VALUE rb_cBLOCK_ARG = rb_define_class_under(rb_cNode, "BLOCK_ARG", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_BLOCK_ARG] = rb_cBLOCK_ARG;
+ rb_iv_set(rb_cBLOCK_ARG, "__member__", members);
+ rb_iv_set(rb_cBLOCK_ARG, "__type__", INT2NUM(NODE_BLOCK_ARG));
+ rb_define_singleton_method(rb_cBLOCK_ARG, "members", node_s_members, 0);
+
+ /* Document-method: cnt
+ * the index into the local variable table of the name of the block
+ * argument, not including the implicit variables.
+ */
+ rb_define_method(rb_cBLOCK_ARG, "cnt", node_cnt, 0);
+ rb_ary_push(members, rb_str_new2("cnt"));
+ }
+
+ /* Document-class: Node::BLOCK_PASS
+ * Represents an object being passed to a method as a block, e.g.:
+ * foo(&bar)
*
- * This makes a method call on an object using self as the implicit
- * receiver.
+ * The body node is first evaluates to get an object, then #to_proc to
+ * convert it into a proc if necessary. The iter node is then
+ * evaluated to call a method, passing the proc as a block parameter to
+ * the method.
*/
{
- VALUE rb_cFCALL = rb_define_class_under(rb_cNode, "FCALL", rb_cNode);
+ VALUE rb_cBLOCK_PASS = rb_define_class_under(rb_cNode, "BLOCK_PASS", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_BLOCK_PASS] = rb_cBLOCK_PASS;
+ rb_iv_set(rb_cBLOCK_PASS, "__member__", members);
+ rb_iv_set(rb_cBLOCK_PASS, "__type__", INT2NUM(NODE_BLOCK_PASS));
+ rb_define_singleton_method(rb_cBLOCK_PASS, "members", node_s_members, 0);
- /* Document-method: args
- * the arguments to the method
+ /* Document-method: body
+ * the object to pass as a block
*/
- rb_define_method(rb_cFCALL, "args", node_args, 0);
- rb_ary_push(members, rb_str_new2("args"));
+ rb_define_method(rb_cBLOCK_PASS, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
- /* Document-method: mid
- * the method id
+ /* Document-method: iter
+ * an expression which calls a method
*/
- rb_define_method(rb_cFCALL, "mid", node_mid, 0);
- rb_ary_push(members, rb_str_new2("mid"));
+ rb_define_method(rb_cBLOCK_PASS, "iter", node_iter, 0);
+ rb_ary_push(members, rb_str_new2("iter"));
}
- /* Document-class: Node::DREGX_ONCE
- * Represents a regular expression with interpolation with the 'once'
- * flag set. The regular expression is only interpolated the first
- * time it is encountered.
+ /* Document-class: Node::BMETHOD
+ * A placeholder for a method defined using define_method, e.g.:
+ * define_method(:foo) {
+ * ...
+ * }
+ *
+ * See also DMETHOD.
*/
{
- VALUE rb_cDREGX_ONCE = rb_define_class_under(rb_cNode, "DREGX_ONCE", rb_cNode);
+ VALUE rb_cBMETHOD = rb_define_class_under(rb_cNode, "BMETHOD", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_DREGX_ONCE] = rb_cDREGX_ONCE;
- rb_iv_set(rb_cDREGX_ONCE, "__member__", members);
- rb_iv_set(rb_cDREGX_ONCE, "__type__", INT2NUM(NODE_DREGX_ONCE));
- rb_define_singleton_method(rb_cDREGX_ONCE, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_BMETHOD] = rb_cBMETHOD;
+ rb_iv_set(rb_cBMETHOD, "__member__", members);
+ rb_iv_set(rb_cBMETHOD, "__type__", INT2NUM(NODE_BMETHOD));
+ rb_define_singleton_method(rb_cBMETHOD, "members", node_s_members, 0);
- /* Document-method: lit
- * a string
+ /* Document-method: cval
+ * the Proc object passed to define_method, which contains the body
+ * of the method
*/
- rb_define_method(rb_cDREGX_ONCE, "lit", node_lit, 0);
- rb_ary_push(members, rb_str_new2("lit"));
+ rb_define_method(rb_cBMETHOD, "cval", node_cval, 0);
+ rb_ary_push(members, rb_str_new2("cval"));
+ }
- /* Document-method: cflag
- * a bitfield containing the options used in the regular
- * expression. See DREGX for a list of valid values.
- */
- rb_define_method(rb_cDREGX_ONCE, "cflag", node_cflag, 0);
- rb_ary_push(members, rb_str_new2("cflag"));
+ /* Document-class: Node::BREAK
+ * Represents the 'break' keyword. Causes control to be transferred
+ * out of the current loop.
+ */
+ {
+ VALUE rb_cBREAK = rb_define_class_under(rb_cNode, "BREAK", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_BREAK] = rb_cBREAK;
+ rb_iv_set(rb_cBREAK, "__member__", members);
+ rb_iv_set(rb_cBREAK, "__type__", INT2NUM(NODE_BREAK));
+ rb_define_singleton_method(rb_cBREAK, "members", node_s_members, 0);
- /* Document-method: next
- * a list of expressions to be appended onto the string
+ /* Document-method: stts
+ * the value to be used as the "return" value of the loop, 0 if nil is to be used.
*/
- rb_define_method(rb_cDREGX_ONCE, "next", node_next, 0);
- rb_ary_push(members, rb_str_new2("next"));
+ rb_define_method(rb_cBREAK, "stts", node_stts, 0);
+ rb_ary_push(members, rb_str_new2("stts"));
}
- /* Document-class: Node::ARGSPUSH
- * Represents the splat portion of the index in an expression:
- * obj[arg, arg, *head] = body
- * Evaluates head to create an array. Evaluates body and pushes the
- * result onto the end of the array, which will then be used to form
- * the arguments of the method call.
+ /* Document-class: Node::CALL
+ * Represents a method call in the form recv.mid(args).
*/
{
- VALUE rb_cARGSPUSH = rb_define_class_under(rb_cNode, "ARGSPUSH", rb_cNode);
+ VALUE rb_cCALL = rb_define_class_under(rb_cNode, "CALL", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_ARGSPUSH] = rb_cARGSPUSH;
- rb_iv_set(rb_cARGSPUSH, "__member__", members);
- rb_iv_set(rb_cARGSPUSH, "__type__", INT2NUM(NODE_ARGSPUSH));
- rb_define_singleton_method(rb_cARGSPUSH, "members", node_s_members, 0);
- rb_define_method(rb_cARGSPUSH, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
- rb_define_method(rb_cARGSPUSH, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ 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"));
+
+ /* 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-class: Node::OPT_N
- * Represents the top-level loop when the -n or -p options are used
- * with the interpreter.
+ /* Document-class: Node::CASE
+ * Represents the value portion of a case/end block, e.g.:
+ * case head
+ * body
+ * end
+ * next
*/
{
- VALUE rb_cOPT_N = rb_define_class_under(rb_cNode, "OPT_N", rb_cNode);
+ VALUE rb_cCASE = rb_define_class_under(rb_cNode, "CASE", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_OPT_N] = rb_cOPT_N;
- rb_iv_set(rb_cOPT_N, "__member__", members);
- rb_iv_set(rb_cOPT_N, "__type__", INT2NUM(NODE_OPT_N));
- rb_define_singleton_method(rb_cOPT_N, "members", node_s_members, 0);
+ 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);
+ /* Document-method: head
+ * the value to select on
+ */
+ rb_define_method(rb_cCASE, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
+
/* Document-method: body
- * the body of the loop
+ * a linked list of nodes, each node representing a when
+ * conditional
*/
- rb_define_method(rb_cOPT_N, "body", node_body, 0);
+ 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::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
- * OP_ASGN2 node.
+ /* Document-class: Node::CDECL
+ * Represents constant assignment of the form:
+ * vid = value
*/
{
- VALUE rb_cOP_ASGN2_ARG = rb_define_class_under(rb_cNode, "OP_ASGN2_ARG", rb_cNode);
+ VALUE rb_cCDECL = rb_define_class_under(rb_cNode, "CDECL", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_CDECL] = rb_cCDECL;
+ rb_iv_set(rb_cCDECL, "__member__", members);
+ rb_iv_set(rb_cCDECL, "__type__", INT2NUM(NODE_CDECL));
+ rb_define_singleton_method(rb_cCDECL, "members", node_s_members, 0);
+ /* Document-method: value
+ * the value to be assigned to the constant
+ */
+ rb_define_method(rb_cCDECL, "value", node_value, 0);
+ rb_ary_push(members, rb_str_new2("value"));
+
/* Document-method: vid
- * The method to call on the receiver to retrieve the attribute
+ * the name of the constant to be assigned, all uppercase
*/
- rb_define_method(rb_cOP_ASGN2_ARG, "vid", node_vid, 0);
+ rb_define_method(rb_cCDECL, "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
+ /* 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
+ *
+ * or:
+ * class cpath < super
+ * body
+ * end
+ *
+ * The class definition is evaluated in a new lexical scope.
+ *
+ * The result of the expression is the last expression evaluated in the
+ * body.
+ */
+ {
+ VALUE rb_cCLASS = rb_define_class_under(rb_cNode, "CLASS", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_CLASS] = rb_cCLASS;
+ rb_iv_set(rb_cCLASS, "__member__", members);
+ rb_iv_set(rb_cCLASS, "__type__", INT2NUM(NODE_CLASS));
+ rb_define_singleton_method(rb_cCLASS, "members", node_s_members, 0);
+
+ /* Document-method: cpath
+ * the name of the class to define
*/
- rb_define_method(rb_cOP_ASGN2_ARG, "aid", node_aid, 0);
- rb_ary_push(members, rb_str_new2("aid"));
+ rb_define_method(rb_cCLASS, "cpath", node_cpath, 0);
+ rb_ary_push(members, rb_str_new2("cpath"));
- /* Document-method: mid
- * The operation to apply to the attribute before setting it. May
- * be 0 (false) to indicate "logical or" or 1 (nil) to indicate
- * "logical and".
+ /* Document-method: body
+ * the body of the class definition
*/
- rb_define_method(rb_cOP_ASGN2_ARG, "mid", node_mid, 0);
- rb_ary_push(members, rb_str_new2("mid"));
+ rb_define_method(rb_cCLASS, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
+
+ /* Document-method: super
+ * an expression returning the base class, or false if there is no
+ * base class specified
+ */
+ rb_define_method(rb_cCLASS, "super", node_super, 0);
+ rb_ary_push(members, rb_str_new2("super"));
}
/* Document-class: Node::COLON2
* Represents a constant lookup in a particular class. This expression
* has the form:
@@ -3418,42 +3485,10 @@
*/
rb_define_method(rb_cCOLON2, "mid", node_mid, 0);
rb_ary_push(members, rb_str_new2("mid"));
}
- /* 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: head
- * the method body
- */
- rb_define_method(rb_cFBODY, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
-
- /* 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-class: Node::COLON3
* Represents a constant lookup or method call in class Object. This
* expression has the form:
* ::mid
*/
@@ -3470,553 +3505,352 @@
*/
rb_define_method(rb_cCOLON3, "mid", node_mid, 0);
rb_ary_push(members, rb_str_new2("mid"));
}
- /* Document-class: Node::ITER
- * Represents an iteration loop, e.g.:
- * iter do |*args|
- * assign args to var
- * body
- * end
- *
- * A new block is created so that dynamic variables created inside the
- * loop do not persist once the loop has terminated.
- *
- * If the iter node is a POSTEXE node, indicates that the expression
- * should be evaluated when the program terminates.
+ /* Document-class: Node::CONST
+ * Represents a constant lookup in the current class. The current
+ * class is the class in which the containing scope was defined. The
+ * result of the expression is the value of the constant.
*/
{
- VALUE rb_cITER = rb_define_class_under(rb_cNode, "ITER", rb_cNode);
+ VALUE rb_cCONST = rb_define_class_under(rb_cNode, "CONST", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_CONST] = rb_cCONST;
+ rb_iv_set(rb_cCONST, "__member__", members);
+ rb_iv_set(rb_cCONST, "__type__", INT2NUM(NODE_CONST));
+ rb_define_singleton_method(rb_cCONST, "members", node_s_members, 0);
- /* Document-method: body
- * the body of the loop
+ /* Document-method: vid
+ * the name of the constant to look up
*/
- rb_define_method(rb_cITER, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
-
- /* Document-method: iter
- * 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"));
+ rb_define_method(rb_cCONST, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::NOT
- * Represents a logical negation.
+ /* 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_cNOT = rb_define_class_under(rb_cNode, "NOT", rb_cNode);
+ VALUE rb_cCREF = rb_define_class_under(rb_cNode, "CREF", 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);
+ 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: body
- * the value to negate.
+ * always 0 (false)
*/
- rb_define_method(rb_cNOT, "body", node_body, 0);
+ rb_define_method(rb_cCREF, "body", node_body, 0);
rb_ary_push(members, rb_str_new2("body"));
- }
- /* Document-class: Node::SUPER
- * Represents the keyword 'super' when used with parens or with arguments.
- */
- {
- VALUE rb_cSUPER = rb_define_class_under(rb_cNode, "SUPER", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_SUPER] = rb_cSUPER;
- rb_iv_set(rb_cSUPER, "__member__", members);
- rb_iv_set(rb_cSUPER, "__type__", INT2NUM(NODE_SUPER));
- rb_define_singleton_method(rb_cSUPER, "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: args
- * the arguments to be passed to the base class
+ /* Document-method: clss
+ * the new class to use for the cbase.
*/
- rb_define_method(rb_cSUPER, "args", node_args, 0);
- rb_ary_push(members, rb_str_new2("args"));
+ rb_define_method(rb_cCREF, "clss", node_clss, 0);
+ rb_ary_push(members, rb_str_new2("clss"));
}
- /* Document-class: Node::FALSE
- * Represents the keyword 'false'.
+ /* Document-class: Node::CVAR
+ * Represents a class variable retrieval. The result of the expression
+ * is the value of the class variable.
*/
{
- VALUE rb_cFALSE = rb_define_class_under(rb_cNode, "FALSE", rb_cNode);
+ VALUE rb_cCVAR = rb_define_class_under(rb_cNode, "CVAR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_FALSE] = rb_cFALSE;
- 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);
- }
+ rb_cNodeSubclass[NODE_CVAR] = rb_cCVAR;
+ rb_iv_set(rb_cCVAR, "__member__", members);
+ rb_iv_set(rb_cCVAR, "__type__", INT2NUM(NODE_CVAR));
+ rb_define_singleton_method(rb_cCVAR, "members", node_s_members, 0);
- /* Document-class: Node::CALL
- * Represents a method call in the form recv.mid(args).
- */
- {
- VALUE rb_cCALL = rb_define_class_under(rb_cNode, "CALL", rb_cNode);
- members = rb_ary_new();
- 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
+ /* Document-method: vid
+ * the name of the class variable, with two leading '@' characters.
*/
- 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"));
-
- /* 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"));
+ rb_define_method(rb_cCVAR, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::OP_ASGN_OR
- * Represents an expression of the form:
- * recv ||= value
- * Ruby will evaluate the expression on the left hand side. If it is
- * undefined, nil, or false, then ruby will evaluate the expression on
- * the right hand side and assign it to recv. The expression will
- * short-circuit if recv is defined and true (non-false, non-nil).
+ /* Document-class: Node::CVASGN
+ * Represents class variable assignment in a method context.
*/
{
- VALUE rb_cOP_ASGN_OR = rb_define_class_under(rb_cNode, "OP_ASGN_OR", rb_cNode);
+ VALUE rb_cCVASGN = rb_define_class_under(rb_cNode, "CVASGN", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_OP_ASGN_OR] = rb_cOP_ASGN_OR;
- rb_iv_set(rb_cOP_ASGN_OR, "__member__", members);
- rb_iv_set(rb_cOP_ASGN_OR, "__type__", INT2NUM(NODE_OP_ASGN_OR));
- rb_define_singleton_method(rb_cOP_ASGN_OR, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_CVASGN] = rb_cCVASGN;
+ rb_iv_set(rb_cCVASGN, "__member__", members);
+ rb_iv_set(rb_cCVASGN, "__type__", INT2NUM(NODE_CVASGN));
+ rb_define_singleton_method(rb_cCVASGN, "members", node_s_members, 0);
- /* Document-method: aid
- * if this indicator is nonzero, ruby will check to see if the
- * provided expression is defined, otherwise it will assume that
- * the provided expression is defined.
- */
- rb_define_method(rb_cOP_ASGN_OR, "aid", node_aid, 0);
- rb_ary_push(members, rb_str_new2("aid"));
-
/* Document-method: value
- * the right hand side of the assignment
+ * an expression whose result is the new value of the class
+ * variable
*/
- rb_define_method(rb_cOP_ASGN_OR, "value", node_value, 0);
+ rb_define_method(rb_cCVASGN, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
- /* Document-method: recv
- * the receiver of the assignment
+ /* Document-method: vid
+ * the name of the class variable to assign
*/
- rb_define_method(rb_cOP_ASGN_OR, "recv", node_recv, 0);
- rb_ary_push(members, rb_str_new2("recv"));
+ rb_define_method(rb_cCVASGN, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::TRUE
- * Represents the keyword 'true'.
+ /* Document-class: Node::CVDECL
+ * Represents class variable assignment in a class context.
+ *
+ * A warning is emitted if the variable already exists.
*/
{
- VALUE rb_cTRUE = rb_define_class_under(rb_cNode, "TRUE", rb_cNode);
+ VALUE rb_cCVDECL = rb_define_class_under(rb_cNode, "CVDECL", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_TRUE] = rb_cTRUE;
- rb_iv_set(rb_cTRUE, "__member__", members);
- rb_iv_set(rb_cTRUE, "__type__", INT2NUM(NODE_TRUE));
- rb_define_singleton_method(rb_cTRUE, "members", node_s_members, 0);
- }
+ rb_cNodeSubclass[NODE_CVDECL] = rb_cCVDECL;
+ rb_iv_set(rb_cCVDECL, "__member__", members);
+ rb_iv_set(rb_cCVDECL, "__type__", INT2NUM(NODE_CVDECL));
+ rb_define_singleton_method(rb_cCVDECL, "members", node_s_members, 0);
- /* Document-class: Node::MASGN
- * Represents multiple assignment.
- */
- {
- VALUE rb_cMASGN = rb_define_class_under(rb_cNode, "MASGN", rb_cNode);
- members = rb_ary_new();
- 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
- * TODO
- */
- rb_define_method(rb_cMASGN, "args", node_args, 0);
- rb_ary_push(members, rb_str_new2("args"));
-
- /* Document-method: head
- * TODO
- */
- rb_define_method(rb_cMASGN, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
-
/* Document-method: value
- * TODO
+ * an expression whose result is the new value of the class
+ * variable
*/
- rb_define_method(rb_cMASGN, "value", node_value, 0);
+ rb_define_method(rb_cCVDECL, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
- }
- /* Document-class: Node::EVSTR
- * Represents a single string interpolation.
- *
- * Evaluates the given expression and converts its result to a string
- * with #to_s.
- */
- {
- VALUE rb_cEVSTR = rb_define_class_under(rb_cNode, "EVSTR", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_EVSTR] = rb_cEVSTR;
- rb_iv_set(rb_cEVSTR, "__member__", members);
- rb_iv_set(rb_cEVSTR, "__type__", INT2NUM(NODE_EVSTR));
- rb_define_singleton_method(rb_cEVSTR, "members", node_s_members, 0);
-
- /* Document-method: body
- * an expression to evaluate
+ /* Document-method: vid
+ * the name of the class variable to assign
*/
- rb_define_method(rb_cEVSTR, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cCVDECL, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::MATCH
- * Represents a regular expression match in a conditional, e.g.:
- * if /lit/ then
- * ...
- * end
- *
- * This expression is equivalent to:
- * if /lit/ =~ $_ then
- * ...
- * end
- *
- * On ruby 1.8 and newer, this type of expression causes ruby to emit a
- * warning, unless script is running with -e.
+ /* Document-class: Node::DASGN
+ * Represents dynamic local variable assignment. Dynamic assignment
+ * differs from static assignment in that the slots for static local
+ * variables are allocated when the method is called, wereas slots for
+ * dynamic variables are allocated when the variable is first assigned
+ * to. When searching for the variable, dynamic assignment searches
+ * backward up the stack to see if the variable exists in any previous
+ * block in the current frame; if it does, it assigns to the slot found
+ * in that block, otherwise it creates a new variable slot. As a
+ * result, dynamic assignment is typically much slower than static
+ * assignment.
*/
{
- VALUE rb_cMATCH = rb_define_class_under(rb_cNode, "MATCH", rb_cNode);
+ VALUE rb_cDASGN = rb_define_class_under(rb_cNode, "DASGN", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_DASGN] = rb_cDASGN;
+ rb_iv_set(rb_cDASGN, "__member__", members);
+ rb_iv_set(rb_cDASGN, "__type__", INT2NUM(NODE_DASGN));
+ rb_define_singleton_method(rb_cDASGN, "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
+ * the value to assign to the local variable
*/
- rb_define_method(rb_cMATCH, "value", node_value, 0);
+ rb_define_method(rb_cDASGN, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
- }
- /* Document-class: Node::ENSURE
- * Represents an ensure expression, e.g.:
- * begin
- * head
- * ensure
- * ensr
- * end
- *
- * The head expression is first evaluated. After the expression is
- * evaluated, whether or not the expression raises an exception, the
- * ensr expression is evaluated.
- *
- * See also RESCUE and RESBDOY.
- */
- {
- VALUE rb_cENSURE = rb_define_class_under(rb_cNode, "ENSURE", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_ENSURE] = rb_cENSURE;
- rb_iv_set(rb_cENSURE, "__member__", members);
- rb_iv_set(rb_cENSURE, "__type__", INT2NUM(NODE_ENSURE));
- rb_define_singleton_method(rb_cENSURE, "members", node_s_members, 0);
-
- /* Document-method: head
- * the expression to protect
+ /* Document-method: vid
+ * the name of the local variable
*/
- rb_define_method(rb_cENSURE, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
-
- /* Document-method: ensr
- * the expression to evaluate after the head is evaluated
- */
- rb_define_method(rb_cENSURE, "ensr", node_ensr, 0);
- rb_ary_push(members, rb_str_new2("ensr"));
+ rb_define_method(rb_cDASGN, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::CDECL
- * Represents constant assignment of the form:
- * vid = value
+ /* Document-class: Node::DASGN_CURR
+ * Represents dynamic local variable assignment in the current frame.
+ * See DASGN for a description of how dynamic assignment works.
*/
{
- VALUE rb_cCDECL = rb_define_class_under(rb_cNode, "CDECL", rb_cNode);
+ VALUE rb_cDASGN_CURR = rb_define_class_under(rb_cNode, "DASGN_CURR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_CDECL] = rb_cCDECL;
- rb_iv_set(rb_cCDECL, "__member__", members);
- rb_iv_set(rb_cCDECL, "__type__", INT2NUM(NODE_CDECL));
- rb_define_singleton_method(rb_cCDECL, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_DASGN_CURR] = rb_cDASGN_CURR;
+ rb_iv_set(rb_cDASGN_CURR, "__member__", members);
+ rb_iv_set(rb_cDASGN_CURR, "__type__", INT2NUM(NODE_DASGN_CURR));
+ rb_define_singleton_method(rb_cDASGN_CURR, "members", node_s_members, 0);
/* Document-method: value
- * the value to be assigned to the constant
+ * the value to assign to the local variable
*/
- rb_define_method(rb_cCDECL, "value", node_value, 0);
+ rb_define_method(rb_cDASGN_CURR, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
/* Document-method: vid
- * the name of the constant to be assigned, all uppercase
+ * the name of the local variable
*/
- rb_define_method(rb_cCDECL, "vid", node_vid, 0);
+ rb_define_method(rb_cDASGN_CURR, "vid", node_vid, 0);
rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::DXSTR
- * Represents a string object with interpolation inside backticks,
- * e.g.:
- * `lit#{next}`
- *
- * The node is evaluated by duplicating the string stored in the 'lit'
- * element, then iterating over the nodes stored in the 'next' element.
- * Each node found should evalate to an string, and each resulting
- * string is appended onto the original string.
- *
- * The resulting string is executed in a subshell and the output from
- * its stdout stored in a string, which becomes the result of the
- * expression. Interpolation is represented with the EVSTR node.
+ /* Document-class: Node::DEFINED
+ * Represents an expression using the 'defined?' keyword. The result
+ * is either nil or a string describing the expression.
*/
{
- VALUE rb_cDXSTR = rb_define_class_under(rb_cNode, "DXSTR", rb_cNode);
+ VALUE rb_cDEFINED = rb_define_class_under(rb_cNode, "DEFINED", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_DXSTR] = rb_cDXSTR;
- rb_iv_set(rb_cDXSTR, "__member__", members);
- rb_iv_set(rb_cDXSTR, "__type__", INT2NUM(NODE_DXSTR));
- rb_define_singleton_method(rb_cDXSTR, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_DEFINED] = rb_cDEFINED;
+ rb_iv_set(rb_cDEFINED, "__member__", members);
+ rb_iv_set(rb_cDEFINED, "__type__", INT2NUM(NODE_DEFINED));
+ rb_define_singleton_method(rb_cDEFINED, "members", node_s_members, 0);
- /* Document-method: lit
- * a string
+ /* Document-method: head
+ * the expression to inspect
*/
- rb_define_method(rb_cDXSTR, "lit", node_lit, 0);
- rb_ary_push(members, rb_str_new2("lit"));
-
- /* Document-method: next
- * a list of expressions to be appended onto the string
- */
- rb_define_method(rb_cDXSTR, "next", node_next, 0);
- rb_ary_push(members, rb_str_new2("next"));
+ rb_define_method(rb_cDEFINED, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
}
- /* Document-class: Node::VCALL
- * Represents a local variable or a method call without an explicit
- * receiver, to be determined at run-time.
- */
- {
- VALUE rb_cVCALL = rb_define_class_under(rb_cNode, "VCALL", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_VCALL] = rb_cVCALL;
- rb_iv_set(rb_cVCALL, "__member__", members);
- rb_iv_set(rb_cVCALL, "__type__", INT2NUM(NODE_VCALL));
- rb_define_singleton_method(rb_cVCALL, "members", node_s_members, 0);
-
- /* Document-method: mid
- * the name of the variable or method
- */
- rb_define_method(rb_cVCALL, "mid", node_mid, 0);
- rb_ary_push(members, rb_str_new2("mid"));
- }
-
- /* Document-class: Node::ZARRAY
- * Represents an array of zero elements. Evalation of this node
- * creates a new array of length zero.
- */
- {
- VALUE rb_cZARRAY = rb_define_class_under(rb_cNode, "ZARRAY", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_ZARRAY] = rb_cZARRAY;
- rb_iv_set(rb_cZARRAY, "__member__", members);
- rb_iv_set(rb_cZARRAY, "__type__", INT2NUM(NODE_ZARRAY));
- rb_define_singleton_method(rb_cZARRAY, "members", node_s_members, 0);
- }
-
- /* Document-class: Node::BLOCK_ARG
- * Represents a block argument in a method definition, e.g.:
- * def foo(&arg)
+ /* Document-class: Node::DEFN
+ * Represents a method definition, e.g.:
+ * def mid
+ * defn
* end
*/
{
- VALUE rb_cBLOCK_ARG = rb_define_class_under(rb_cNode, "BLOCK_ARG", rb_cNode);
+ VALUE rb_cDEFN = rb_define_class_under(rb_cNode, "DEFN", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_BLOCK_ARG] = rb_cBLOCK_ARG;
- rb_iv_set(rb_cBLOCK_ARG, "__member__", members);
- rb_iv_set(rb_cBLOCK_ARG, "__type__", INT2NUM(NODE_BLOCK_ARG));
- rb_define_singleton_method(rb_cBLOCK_ARG, "members", node_s_members, 0);
+ 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: cnt
- * the index into the local variable table of the name of the block
- * argument, not including the implicit variables.
+ /* Document-method: defn
+ * the body of the method definition
*/
- rb_define_method(rb_cBLOCK_ARG, "cnt", node_cnt, 0);
- rb_ary_push(members, rb_str_new2("cnt"));
- }
+ rb_define_method(rb_cDEFN, "defn", node_defn, 0);
+ rb_ary_push(members, rb_str_new2("defn"));
- /* Document-class: Node::AND
- * Represents a logical 'and' of the form:
- * first && second
- * The expression will short-circuit and yield the result of the left
- * hand side if it is false or nil, else it will evaluate the right
- * hand side and use it as the result of the expression.
- */
- {
- VALUE rb_cAND = rb_define_class_under(rb_cNode, "AND", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_AND] = rb_cAND;
- rb_iv_set(rb_cAND, "__member__", members);
- rb_iv_set(rb_cAND, "__type__", INT2NUM(NODE_AND));
- rb_define_singleton_method(rb_cAND, "members", node_s_members, 0);
-
- /* Document-method: first
- * the expression on the left hand side
+ /* Document-method: mid
+ * the name of the method* defn the body of the method
*/
- rb_define_method(rb_cAND, "first", node_1st, 0);
- rb_ary_push(members, rb_str_new2("first"));
+ rb_define_method(rb_cDEFN, "mid", node_mid, 0);
+ rb_ary_push(members, rb_str_new2("mid"));
- /* Document-method: second
- * the expression on the right hand side
+ /* Document-method: noex
+ * the flags which should be used to define the method
*/
- rb_define_method(rb_cAND, "second", node_2nd, 0);
- rb_ary_push(members, rb_str_new2("second"));
+ rb_define_method(rb_cDEFN, "noex", node_noex, 0);
+ rb_ary_push(members, rb_str_new2("noex"));
}
- /* Document-class: Node::SCLASS
- * Represents the body of a singleton class definition, e.g.:
- * class << recv
- * body
+ /* Document-class: Node::DEFS
+ * Represents a singleton method definition, e.g.:
+ * def recv.mid
+ * defn
* end
- *
- * The class definition is evaluated in a new lexical scope.
- *
- * The result of the expression is the last expression evaluated in the
- * body.
*/
{
- VALUE rb_cSCLASS = rb_define_class_under(rb_cNode, "SCLASS", rb_cNode);
+ VALUE rb_cDEFS = rb_define_class_under(rb_cNode, "DEFS", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_SCLASS] = rb_cSCLASS;
- rb_iv_set(rb_cSCLASS, "__member__", members);
- rb_iv_set(rb_cSCLASS, "__type__", INT2NUM(NODE_SCLASS));
- rb_define_singleton_method(rb_cSCLASS, "members", node_s_members, 0);
+ 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);
+ rb_define_method(rb_cDEFS, "defn", node_defn, 0);
+ rb_ary_push(members, rb_str_new2("defn"));
- /* Document-method: body
- * the body of the class definition
+ /* Document-method: mid
+ * the name of the method* defn the body of the method
*/
- rb_define_method(rb_cSCLASS, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cDEFS, "mid", node_mid, 0);
+ rb_ary_push(members, rb_str_new2("mid"));
/* Document-method: recv
- * the object whose singleton class is to be modified
+ * the object to whose singleton class the new method is to be added
*/
- rb_define_method(rb_cSCLASS, "recv", node_recv, 0);
+ rb_define_method(rb_cDEFS, "recv", node_recv, 0);
rb_ary_push(members, rb_str_new2("recv"));
}
- /* Document-class: Node::DEFINED
- * Represents an expression using the 'defined?' keyword. The result
- * is either nil or a string describing the expression.
+ /* 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_cDEFINED = rb_define_class_under(rb_cNode, "DEFINED", rb_cNode);
+ VALUE rb_cDMETHOD = rb_define_class_under(rb_cNode, "DMETHOD", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_DEFINED] = rb_cDEFINED;
- rb_iv_set(rb_cDEFINED, "__member__", members);
- rb_iv_set(rb_cDEFINED, "__type__", INT2NUM(NODE_DEFINED));
- rb_define_singleton_method(rb_cDEFINED, "members", node_s_members, 0);
+ 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: head
- * the expression to inspect
+ /* Document-method: cval
+ * the Method object passed to define_method, which contains the
+ * body of the method
*/
- rb_define_method(rb_cDEFINED, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
+ rb_define_method(rb_cDMETHOD, "cval", node_cval, 0);
+ rb_ary_push(members, rb_str_new2("cval"));
}
- /* Document-class: Node::VALIAS
- * Represents an alias expression of the form:
- * alias 1st 2nd
- * where 2nd is the name of a variable and 1st is the name of its new
- * alias.
+ /* Document-class: Node::DOT2
+ * Represents a range created with the form:
+ * beg..end
+ * Creates a range which does not exclude the range end.
*/
{
- VALUE rb_cVALIAS = rb_define_class_under(rb_cNode, "VALIAS", rb_cNode);
+ VALUE rb_cDOT2 = rb_define_class_under(rb_cNode, "DOT2", rb_cNode);
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_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);
- /* Document-class: Node::REDO
- * Represents the 'redo' keyword. Causes control to be transferred to
- * the beginning of the loop. The loop assignment is not repeated.
- */
- {
- VALUE rb_cREDO = rb_define_class_under(rb_cNode, "REDO", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_REDO] = rb_cREDO;
- rb_iv_set(rb_cREDO, "__member__", members);
- rb_iv_set(rb_cREDO, "__type__", INT2NUM(NODE_REDO));
- rb_define_singleton_method(rb_cREDO, "members", node_s_members, 0);
+ /* 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-class: Node::BLOCK_PASS
- * Represents an object being passed to a method as a block, e.g.:
- * foo(&bar)
- *
- * The body node is first evaluates to get an object, then #to_proc to
- * convert it into a proc if necessary. The iter node is then
- * evaluated to call a method, passing the proc as a block parameter to
- * the method.
+ /* Document-class: Node::DOT3
+ * Represents a range created with the form:
+ * beg...end
+ * Creates a range which excludes the range end.
*/
{
- VALUE rb_cBLOCK_PASS = rb_define_class_under(rb_cNode, "BLOCK_PASS", rb_cNode);
+ VALUE rb_cDOT3 = rb_define_class_under(rb_cNode, "DOT3", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_BLOCK_PASS] = rb_cBLOCK_PASS;
- rb_iv_set(rb_cBLOCK_PASS, "__member__", members);
- rb_iv_set(rb_cBLOCK_PASS, "__type__", INT2NUM(NODE_BLOCK_PASS));
- rb_define_singleton_method(rb_cBLOCK_PASS, "members", node_s_members, 0);
+ 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);
- /* Document-method: body
- * the object to pass as a block
+ /* Document-method: beg
+ * the beginning of the range
*/
- rb_define_method(rb_cBLOCK_PASS, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cDOT3, "beg", node_beg, 0);
+ rb_ary_push(members, rb_str_new2("beg"));
- /* Document-method: iter
- * an expression which calls a method
+ /* Document-method: end
+ * the end of the range
*/
- rb_define_method(rb_cBLOCK_PASS, "iter", node_iter, 0);
- rb_ary_push(members, rb_str_new2("iter"));
+ 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-class: Node::DREGX
* Represents a regular expresion with interpolation. The node is
* evaluated by duplicating the regex stored in the 'lit' element, then
@@ -4061,83 +3895,69 @@
*/
rb_define_method(rb_cDREGX, "next", node_next, 0);
rb_ary_push(members, rb_str_new2("next"));
}
- /* Document-class: Node::DEFN
- * Represents a method definition, e.g.:
- * def mid
- * defn
- * end
+ /* Document-class: Node::DREGX_ONCE
+ * Represents a regular expression with interpolation with the 'once'
+ * flag set. The regular expression is only interpolated the first
+ * time it is encountered.
*/
{
- VALUE rb_cDEFN = rb_define_class_under(rb_cNode, "DEFN", rb_cNode);
+ VALUE rb_cDREGX_ONCE = rb_define_class_under(rb_cNode, "DREGX_ONCE", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_DREGX_ONCE] = rb_cDREGX_ONCE;
+ rb_iv_set(rb_cDREGX_ONCE, "__member__", members);
+ rb_iv_set(rb_cDREGX_ONCE, "__type__", INT2NUM(NODE_DREGX_ONCE));
+ rb_define_singleton_method(rb_cDREGX_ONCE, "members", node_s_members, 0);
- /* Document-method: mid
- * the name of the method* defn the body of the method
+ /* Document-method: lit
+ * a string
*/
- rb_define_method(rb_cDEFN, "mid", node_mid, 0);
- rb_ary_push(members, rb_str_new2("mid"));
+ rb_define_method(rb_cDREGX_ONCE, "lit", node_lit, 0);
+ rb_ary_push(members, rb_str_new2("lit"));
- /* Document-method: defn
- * the body of the method definition
+ /* Document-method: cflag
+ * a bitfield containing the options used in the regular
+ * expression. See DREGX for a list of valid values.
*/
- rb_define_method(rb_cDEFN, "defn", node_defn, 0);
- rb_ary_push(members, rb_str_new2("defn"));
+ rb_define_method(rb_cDREGX_ONCE, "cflag", node_cflag, 0);
+ rb_ary_push(members, rb_str_new2("cflag"));
- /* Document-method: noex
- * the flags which should be used to define the method
+ /* Document-method: next
+ * a list of expressions to be appended onto the string
*/
- rb_define_method(rb_cDEFN, "noex", node_noex, 0);
- rb_ary_push(members, rb_str_new2("noex"));
+ rb_define_method(rb_cDREGX_ONCE, "next", node_next, 0);
+ rb_ary_push(members, rb_str_new2("next"));
}
- /* Document-class: Node::SCOPE
- * Represents a lexical scope.
- *
- * A new scope is created when a method is invoked. The scope node
- * holds information about local variables and arguments to the method.
- * The first two variables in the local variable table are the implicit
- * variables $_ and $~.
- *
- * The next variables listed in the local variable table are the
- * arguments to the method. More information about the arguments to
- * the method are stored in the ARGS node, which will either be the
- * first node in the scope or the first node in the BLOCK held by the
- * scope.
+ /* Document-class: Node::DSTR
+ * Represents a string object with interpolation. The node is
+ * evaluated by duplicating the string stored in the 'lit' element,
+ * then iterating over the nodes stored in the 'next' element. Each
+ * node found should evalate to a string, and each resulting string is
+ * appended onto the regex. Interpolation is represented with the
+ * EVSTR node.
*/
{
- VALUE rb_cSCOPE = rb_define_class_under(rb_cNode, "SCOPE", rb_cNode);
+ VALUE rb_cDSTR = rb_define_class_under(rb_cNode, "DSTR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_SCOPE] = rb_cSCOPE;
- rb_iv_set(rb_cSCOPE, "__member__", members);
- rb_iv_set(rb_cSCOPE, "__type__", INT2NUM(NODE_SCOPE));
- rb_define_singleton_method(rb_cSCOPE, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_DSTR] = rb_cDSTR;
+ rb_iv_set(rb_cDSTR, "__member__", members);
+ rb_iv_set(rb_cDSTR, "__type__", INT2NUM(NODE_DSTR));
+ rb_define_singleton_method(rb_cDSTR, "members", node_s_members, 0);
- /* Document-method: tbl
- * the names of the local variables* next the first expression in
- * the scope
+ /* Document-method: lit
+ * a string
*/
- rb_define_method(rb_cSCOPE, "tbl", node_tbl, 0);
- rb_ary_push(members, rb_str_new2("tbl"));
+ rb_define_method(rb_cDSTR, "lit", node_lit, 0);
+ rb_ary_push(members, rb_str_new2("lit"));
- /* 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
+ * a list of expressions to be appended onto the string
*/
- rb_define_method(rb_cSCOPE, "next", node_next, 0);
+ rb_define_method(rb_cDSTR, "next", node_next, 0);
rb_ary_push(members, rb_str_new2("next"));
}
/* Document-class: Node::DSYM
* Represents a symbol with interpolation, e.g.:
@@ -4161,766 +3981,812 @@
rb_ary_push(members, rb_str_new2("lit"));
rb_define_method(rb_cDSYM, "next", node_next, 0);
rb_ary_push(members, rb_str_new2("next"));
}
- /* Document-class: Node::BMETHOD
- * A placeholder for a method defined using define_method, e.g.:
- * define_method(:foo) {
- * ...
- * }
- *
- * See also DMETHOD.
+ /* Document-class: Node::DVAR
+ * Represents dynamic local variable retrieval. See also DASGN.
*/
{
- VALUE rb_cBMETHOD = rb_define_class_under(rb_cNode, "BMETHOD", rb_cNode);
+ VALUE rb_cDVAR = rb_define_class_under(rb_cNode, "DVAR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_BMETHOD] = rb_cBMETHOD;
- rb_iv_set(rb_cBMETHOD, "__member__", members);
- rb_iv_set(rb_cBMETHOD, "__type__", INT2NUM(NODE_BMETHOD));
- rb_define_singleton_method(rb_cBMETHOD, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_DVAR] = rb_cDVAR;
+ rb_iv_set(rb_cDVAR, "__member__", members);
+ rb_iv_set(rb_cDVAR, "__type__", INT2NUM(NODE_DVAR));
+ rb_define_singleton_method(rb_cDVAR, "members", node_s_members, 0);
- /* Document-method: cval
- * the Proc object passed to define_method, which contains the body
- * of the method
+ /* Document-method: vid
+ * the name of the local variable to retrieve.
*/
- rb_define_method(rb_cBMETHOD, "cval", node_cval, 0);
- rb_ary_push(members, rb_str_new2("cval"));
+ rb_define_method(rb_cDVAR, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::IF
- * Represents a conditional of the form:
- * if cond then
- * body
- * end
+ /* Document-class: Node::DXSTR
+ * Represents a string object with interpolation inside backticks,
+ * e.g.:
+ * `lit#{next}`
*
- * or the form:
- * if cond then
- * body
- * else
- * else
- * end
+ * The node is evaluated by duplicating the string stored in the 'lit'
+ * element, then iterating over the nodes stored in the 'next' element.
+ * Each node found should evalate to an string, and each resulting
+ * string is appended onto the original string.
*
- * The condition is first evaluated. If it is true, then body is
- * evaluated, otherwise else is evaluated. The result is the value of
- * the expression evaluated, or nil if there was no expression
- * present.
- *
- * A conditional block using elsif has another IF node as the else
- * expression.
+ * The resulting string is executed in a subshell and the output from
+ * its stdout stored in a string, which becomes the result of the
+ * expression. Interpolation is represented with the EVSTR node.
*/
{
- VALUE rb_cIF = rb_define_class_under(rb_cNode, "IF", rb_cNode);
+ VALUE rb_cDXSTR = rb_define_class_under(rb_cNode, "DXSTR", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_DXSTR] = rb_cDXSTR;
+ rb_iv_set(rb_cDXSTR, "__member__", members);
+ rb_iv_set(rb_cDXSTR, "__type__", INT2NUM(NODE_DXSTR));
+ rb_define_singleton_method(rb_cDXSTR, "members", node_s_members, 0);
- /* Document-method: cond
- * the condition to evaluate
+ /* Document-method: lit
+ * a string
*/
- rb_define_method(rb_cIF, "cond", node_cond, 0);
- rb_ary_push(members, rb_str_new2("cond"));
+ rb_define_method(rb_cDXSTR, "lit", node_lit, 0);
+ rb_ary_push(members, rb_str_new2("lit"));
- /* Document-method: body
- * the expression to evaluate if the expression is true, or false
- * if the expression is empty
+ /* Document-method: next
+ * a list of expressions to be appended onto the string
*/
- rb_define_method(rb_cIF, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
-
- /* Document-method: else
- * 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"));
+ rb_define_method(rb_cDXSTR, "next", node_next, 0);
+ rb_ary_push(members, rb_str_new2("next"));
}
- /* Document-class: Node::WHEN
- * Represents either a conditional in a case/end block:
- * case value
- * when head
- * body
- * next
+ /* Document-class: Node::ENSURE
+ * Represents an ensure expression, e.g.:
+ * begin
+ * head
+ * ensure
+ * ensr
* end
*
- * or the first element of a a case/end block with no conditional:
- * case
- * when head
- * body
- * next
- * end
+ * The head expression is first evaluated. After the expression is
+ * evaluated, whether or not the expression raises an exception, the
+ * ensr expression is evaluated.
*
- * In the first case, value is evaluated and head is evaluated, and
- * they are compared using head === value. If the result is true, then
- * body is evaluated and no more when conditions are tried, otherwise
- * the interpreter evaluates the next node.
- *
- * In the second case, head is tested using rtest(value). If the
- * result is true, then body is evaluated and no more when conditions
- * are tried, otherwise the interpreter evaluates the next node.
- *
- * If the condition evaluates to false and there are no more when
- * conditions to try, the result of the expression is nil.
- *
- * If the next expression to try is not a WHEN node, then it represents
- * an else element and is evaluated unconditionally.
+ * See also RESCUE and RESBDOY.
*/
{
- VALUE rb_cWHEN = rb_define_class_under(rb_cNode, "WHEN", rb_cNode);
+ VALUE rb_cENSURE = rb_define_class_under(rb_cNode, "ENSURE", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_ENSURE] = rb_cENSURE;
+ rb_iv_set(rb_cENSURE, "__member__", members);
+ rb_iv_set(rb_cENSURE, "__type__", INT2NUM(NODE_ENSURE));
+ rb_define_singleton_method(rb_cENSURE, "members", node_s_members, 0);
/* Document-method: head
- * a value to compare against, or a condition to be tested
+ * the expression to protect
*/
- rb_define_method(rb_cWHEN, "head", node_head, 0);
+ rb_define_method(rb_cENSURE, "head", node_head, 0);
rb_ary_push(members, rb_str_new2("head"));
- /* Document-method: body
- * an expression to evaluate if the condition evaluates to true
+ /* Document-method: ensr
+ * the expression to evaluate after the head is evaluated
*/
- 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"));
+ rb_define_method(rb_cENSURE, "ensr", node_ensr, 0);
+ rb_ary_push(members, rb_str_new2("ensr"));
}
- /* Document-class: Node::ARGSCAT
- * Represents the concatenation of a list of arguments and a splatted
- * value, e.g.:
- * a, b, *value
- * Evaluates head to create an array. Evaluates body and performs a
- * splat operation on the result to create another array (see SPLAT).
- * Concatenates the the second array onto the end of the first to
- * produce the result.
+ /* Document-class: Node::EVSTR
+ * Represents a single string interpolation.
+ *
+ * Evaluates the given expression and converts its result to a string
+ * with #to_s.
*/
{
- VALUE rb_cARGSCAT = rb_define_class_under(rb_cNode, "ARGSCAT", rb_cNode);
+ VALUE rb_cEVSTR = rb_define_class_under(rb_cNode, "EVSTR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_ARGSCAT] = rb_cARGSCAT;
- rb_iv_set(rb_cARGSCAT, "__member__", members);
- rb_iv_set(rb_cARGSCAT, "__type__", INT2NUM(NODE_ARGSCAT));
- rb_define_singleton_method(rb_cARGSCAT, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_EVSTR] = rb_cEVSTR;
+ rb_iv_set(rb_cEVSTR, "__member__", members);
+ rb_iv_set(rb_cEVSTR, "__type__", INT2NUM(NODE_EVSTR));
+ rb_define_singleton_method(rb_cEVSTR, "members", node_s_members, 0);
- /* Document-method: head
- * a list of fixed arguments
- */
- rb_define_method(rb_cARGSCAT, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
-
/* Document-method: body
- * the last argument, which will be splatted onto the end of the
- * fixed arguments
+ * an expression to evaluate
*/
- rb_define_method(rb_cARGSCAT, "body", node_body, 0);
+ rb_define_method(rb_cEVSTR, "body", node_body, 0);
rb_ary_push(members, rb_str_new2("body"));
}
- /* Document-class: Node::HASH
- * Represents a hash table. Evaluation of this node creates a new Hash
- * by evaluating the given expressions and placing them into the table.
+ /* Document-class: Node::FALSE
+ * Represents the keyword 'false'.
*/
{
- VALUE rb_cHASH = rb_define_class_under(rb_cNode, "HASH", rb_cNode);
+ VALUE rb_cFALSE = rb_define_class_under(rb_cNode, "FALSE", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_HASH] = rb_cHASH;
- rb_iv_set(rb_cHASH, "__member__", members);
- rb_iv_set(rb_cHASH, "__type__", INT2NUM(NODE_HASH));
- rb_define_singleton_method(rb_cHASH, "members", node_s_members, 0);
-
- /* Document-method: head
- * an array of successive keys and values
- */
- rb_define_method(rb_cHASH, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
+ rb_cNodeSubclass[NODE_FALSE] = rb_cFALSE;
+ 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::ALLOCA
- * A node used for temporary allocation of memory on platforms that do
- * not support alloca.
- *
- * It should never be evaluated as an expression.
+ /* 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
*/
-#ifdef HAVE_NODE_ALLOCA
{
- VALUE rb_cALLOCA = rb_define_class_under(rb_cNode, "ALLOCA", rb_cNode);
+ VALUE rb_cFBODY = rb_define_class_under(rb_cNode, "FBODY", rb_cNode);
members = rb_ary_new();
- 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);
+ 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: cfnc
- * a pointer to the allocated memory
+ /* Document-method: head
+ * the method body
*/
- rb_define_method(rb_cALLOCA, "cfnc", node_cfnc, 0);
- rb_ary_push(members, rb_str_new2("cfnc"));
+ rb_define_method(rb_cFBODY, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
- /* Document-method: value
- * a pointer to the previously allocated temporary node
+ /* Document-method: orig
+ * the origin class
*/
- rb_define_method(rb_cALLOCA, "value", node_value, 0);
- rb_ary_push(members, rb_str_new2("value"));
+ rb_define_method(rb_cFBODY, "orig", node_orig, 0);
+ rb_ary_push(members, rb_str_new2("orig"));
- /* Document-method: cnt
- * the number of bytes allocated
+ /* Document-method: mid
+ * the name of the method
*/
- rb_define_method(rb_cALLOCA, "cnt", node_cnt, 0);
- rb_ary_push(members, rb_str_new2("cnt"));
+ rb_define_method(rb_cFBODY, "mid", node_mid, 0);
+ rb_ary_push(members, rb_str_new2("mid"));
}
-#endif
- /* Document-class: Node::OP_ASGN1
- * Represents bracket assignment of the form:
- * recv[index] += value or
- * recv[index] ||= value or
- * recv[index] &&= value.
+ /* Document-class: Node::FCALL
+ * Represents a method call in the form:
+ * mid(args).
*
- * The index is obtained from args.body.
- *
- * The value is obtained from args.head.
- *
- * In the case of ||=, mid will be 0. The rhs will be equal to the
- * result of evaluating args.head if the lhs is false, otherwise the
- * rhs will be equal to lhs.
- *
- * In the case of &&=, mid will be 1. The rhs will be equal to the lhs
- * if lhs is false, otherwise the rhs will be equal to the result of
- * evaluating args.head. In all other cases, mid will be the name of
- * the method to call to calculate value, such that the expression is
- * equivalent to:
- * recv[args.body] = recv[args.body].mid(args.head)
- *
- * In no case does ruby short-circuit the assignment.
+ * This makes a method call on an object using self as the implicit
+ * receiver.
*/
{
- VALUE rb_cOP_ASGN1 = rb_define_class_under(rb_cNode, "OP_ASGN1", rb_cNode);
+ VALUE rb_cFCALL = rb_define_class_under(rb_cNode, "FCALL", rb_cNode);
members = rb_ary_new();
- 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);
+ 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 assigment
+ * the arguments to the method
*/
- rb_define_method(rb_cOP_ASGN1, "args", node_args, 0);
+ rb_define_method(rb_cFCALL, "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
+ * the method id
*/
- rb_define_method(rb_cOP_ASGN1, "mid", node_mid, 0);
+ rb_define_method(rb_cFCALL, "mid", node_mid, 0);
rb_ary_push(members, rb_str_new2("mid"));
-
- /* 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-class: Node::CASE
- * Represents the value portion of a case/end block, e.g.:
- * case head
- * body
+ /* Document-class: Node::FLIP2
+ * Represents part of an awk-like flip-flop expression of the form:
+ * if beg..end then
+ * body
* end
- * next
*/
{
- VALUE rb_cCASE = rb_define_class_under(rb_cNode, "CASE", rb_cNode);
+ VALUE rb_cFLIP2 = rb_define_class_under(rb_cNode, "FLIP2", rb_cNode);
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_cNodeSubclass[NODE_FLIP2] = rb_cFLIP2;
+ rb_iv_set(rb_cFLIP2, "__member__", members);
+ rb_iv_set(rb_cFLIP2, "__type__", INT2NUM(NODE_FLIP2));
+ rb_define_singleton_method(rb_cFLIP2, "members", node_s_members, 0);
- /* Document-method: head
- * the value to select on
+ /* Document-method: beg
+ * the beginning of the range
*/
- rb_define_method(rb_cCASE, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
+ rb_define_method(rb_cFLIP2, "beg", node_beg, 0);
+ rb_ary_push(members, rb_str_new2("beg"));
- /* Document-method: body
- * a linked list of nodes, each node representing a when
- * conditional
+ /* Document-method: end
+ * the end of the range
*/
- 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"));
- }
+ rb_define_method(rb_cFLIP2, "end", node_end, 0);
+ rb_ary_push(members, rb_str_new2("end"));
- /* 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-method: cnt
+ * the index into the local variable table of the special variable
+ * 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-class: Node::OP_ASGN2
- * Represents attribute assignment of the form:
- * recv.attr op value
- *
- * where recv is the receiver of the attr method, attr is the attribute
- * to which to assign, op is an assignment operation (e.g. +=), and
- * value is the value to assign to the attribute.
- *
- * The 'next' member of this class is also of type OP_ASGN2, though it
- * has different members than its parent. This child node is
- * documented under OP_ASGN2_ARG.
+ /* Document-class: Node::FLIP3
+ * Represents part of a sed-like flip-flop expression of the form:
+ * if beg..end then
+ * body
+ * end
*/
{
- VALUE rb_cOP_ASGN2 = rb_define_class_under(rb_cNode, "OP_ASGN2", rb_cNode);
+ VALUE rb_cFLIP3 = rb_define_class_under(rb_cNode, "FLIP3", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_FLIP3] = rb_cFLIP3;
+ rb_iv_set(rb_cFLIP3, "__member__", members);
+ rb_iv_set(rb_cFLIP3, "__type__", INT2NUM(NODE_FLIP3));
+ rb_define_singleton_method(rb_cFLIP3, "members", node_s_members, 0);
- /* Document-method: value
- * the value to assign to the attribute
+ /* Document-method: beg
+ * the beginning of the range
*/
- rb_define_method(rb_cOP_ASGN2, "value", node_value, 0);
- rb_ary_push(members, rb_str_new2("value"));
+ rb_define_method(rb_cFLIP3, "beg", node_beg, 0);
+ rb_ary_push(members, rb_str_new2("beg"));
- /* Document-method: next
- * another node of type OP_ASGN2 which contains more information
- * about the assignment operation than can fit in this node alone
+ /* Document-method: end
+ * the end of the range
*/
- rb_define_method(rb_cOP_ASGN2, "next", node_next, 0);
- rb_ary_push(members, rb_str_new2("next"));
+ rb_define_method(rb_cFLIP3, "end", node_end, 0);
+ rb_ary_push(members, rb_str_new2("end"));
- /* Document-method: recv
- * the receiver of the attribute
+ /* Document-method: cnt
+ * the index into the local variable table of the special variable
+ * to use in the flip-flop expression (usually 2 for $_)
*/
- rb_define_method(rb_cOP_ASGN2, "recv", node_recv, 0);
- rb_ary_push(members, rb_str_new2("recv"));
+ rb_define_method(rb_cFLIP3, "cnt", node_cnt, 0);
+ rb_ary_push(members, rb_str_new2("cnt"));
}
- /* Document-class: Node::DEFS
- * Represents a singleton method definition, e.g.:
- * def recv.mid
- * defn
+ /* Document-class: Node::FOR
+ * Represents a loop constructed with the 'for' keyword, e.g.:
+ * for var in iter do
+ * body
* end
+ *
+ * This is equivalent to:
+ * iter.each do |*args|
+ * assign args to var
+ * body
+ * end
+ *
+ * Except that a new block is not created.
*/
{
- VALUE rb_cDEFS = rb_define_class_under(rb_cNode, "DEFS", rb_cNode);
+ VALUE rb_cFOR = rb_define_class_under(rb_cNode, "FOR", rb_cNode);
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);
+ 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: mid
- * the name of the method* defn the body of the method
+ /* Document-method: body
+ * the body of the loop
*/
- 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"));
+ rb_define_method(rb_cFOR, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
- /* Document-method: recv
- * the object to whose singleton class the new method is to be added
+ /* Document-method: iter
+ * the sequence over which to iterate
*/
- rb_define_method(rb_cDEFS, "recv", node_recv, 0);
- rb_ary_push(members, rb_str_new2("recv"));
+ 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::LASGN
- * Represents local variable assignment.
+ /* Document-class: Node::GASGN
+ * Represents global variable assignment.
*/
{
- VALUE rb_cLASGN = rb_define_class_under(rb_cNode, "LASGN", rb_cNode);
+ VALUE rb_cGASGN = rb_define_class_under(rb_cNode, "GASGN", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_LASGN] = rb_cLASGN;
- rb_iv_set(rb_cLASGN, "__member__", members);
- rb_iv_set(rb_cLASGN, "__type__", INT2NUM(NODE_LASGN));
- rb_define_singleton_method(rb_cLASGN, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_GASGN] = rb_cGASGN;
+ rb_iv_set(rb_cGASGN, "__member__", members);
+ rb_iv_set(rb_cGASGN, "__type__", INT2NUM(NODE_GASGN));
+ rb_define_singleton_method(rb_cGASGN, "members", node_s_members, 0);
/* Document-method: value
- * the value to assign to the local variable
+ * an expression whose result is the new value of the global variable
*/
- rb_define_method(rb_cLASGN, "value", node_value, 0);
+ rb_define_method(rb_cGASGN, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
/* Document-method: vid
- * the name of the local variable
+ * the name of the global variable, with a leading '$' character.
*/
- rb_define_method(rb_cLASGN, "vid", node_vid, 0);
+ rb_define_method(rb_cGASGN, "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"));
+ rb_define_method(rb_cGASGN, "entry", node_entry, 0);
+ rb_ary_push(members, rb_str_new2("entry"));
}
- /* Document-class: Node::POSTEXE
- * Represents the END keyword, e.g.:
- * END { ... }
- *
- * Indicating that the enclosing ITER node is to be excecuted only
- * once, when the program terminates.
+ /* Document-class: Node::GVAR
+ * Represents global variable retrieval.
*/
{
- VALUE rb_cPOSTEXE = rb_define_class_under(rb_cNode, "POSTEXE", rb_cNode);
+ VALUE rb_cGVAR = rb_define_class_under(rb_cNode, "GVAR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_POSTEXE] = rb_cPOSTEXE;
- rb_iv_set(rb_cPOSTEXE, "__member__", members);
- rb_iv_set(rb_cPOSTEXE, "__type__", INT2NUM(NODE_POSTEXE));
- rb_define_singleton_method(rb_cPOSTEXE, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_GVAR] = rb_cGVAR;
+ rb_iv_set(rb_cGVAR, "__member__", members);
+ rb_iv_set(rb_cGVAR, "__type__", INT2NUM(NODE_GVAR));
+ rb_define_singleton_method(rb_cGVAR, "members", node_s_members, 0);
+
+ /* Document-method: vid
+ * the name of the global variable to retrieve, with a leading '$'
+ */
+ rb_define_method(rb_cGVAR, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
+ rb_define_method(rb_cGVAR, "entry", node_entry, 0);
+ rb_ary_push(members, rb_str_new2("entry"));
}
- /* Document-class: Node::STR
- * Represents a string object. Duplicates the string stored in the
- * node.
+ /* Document-class: Node::HASH
+ * Represents a hash table. Evaluation of this node creates a new Hash
+ * by evaluating the given expressions and placing them into the table.
*/
{
- VALUE rb_cSTR = rb_define_class_under(rb_cNode, "STR", rb_cNode);
+ VALUE rb_cHASH = rb_define_class_under(rb_cNode, "HASH", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_STR] = rb_cSTR;
- rb_iv_set(rb_cSTR, "__member__", members);
- rb_iv_set(rb_cSTR, "__type__", INT2NUM(NODE_STR));
- rb_define_singleton_method(rb_cSTR, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_HASH] = rb_cHASH;
+ rb_iv_set(rb_cHASH, "__member__", members);
+ rb_iv_set(rb_cHASH, "__type__", INT2NUM(NODE_HASH));
+ rb_define_singleton_method(rb_cHASH, "members", node_s_members, 0);
- /* Document-method: lit
- * the string to be duplicated
+ /* Document-method: head
+ * an array of successive keys and values
*/
- rb_define_method(rb_cSTR, "lit", node_lit, 0);
- rb_ary_push(members, rb_str_new2("lit"));
+ rb_define_method(rb_cHASH, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
}
- /* 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.
+ /* Document-class: Node::IASGN
+ * Represents instance variable assignment.
*/
{
- VALUE rb_cATTRSET = rb_define_class_under(rb_cNode, "ATTRSET", rb_cNode);
+ VALUE rb_cIASGN = rb_define_class_under(rb_cNode, "IASGN", 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);
+ rb_cNodeSubclass[NODE_IASGN] = rb_cIASGN;
+ rb_iv_set(rb_cIASGN, "__member__", members);
+ rb_iv_set(rb_cIASGN, "__type__", INT2NUM(NODE_IASGN));
+ rb_define_singleton_method(rb_cIASGN, "members", node_s_members, 0);
+ /* Document-method: value
+ * the value to assign to the instance variable
+ */
+ rb_define_method(rb_cIASGN, "value", node_value, 0);
+ rb_ary_push(members, rb_str_new2("value"));
+
/* Document-method: vid
- * the name of the attribute, with a leading '@' sign
+ * the name of the instance variable, with a leading '@' sign
*/
- rb_define_method(rb_cATTRSET, "vid", node_vid, 0);
+ rb_define_method(rb_cIASGN, "vid", node_vid, 0);
rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::MEMO
- * A node used for temporary storage.
+ /* Document-class: Node::IF
+ * Represents a conditional of the form:
+ * if cond then
+ * body
+ * end
*
- * It is used by the rb_protect function so that the cont_protect
- * variable can be restored when the function returns.
+ * or the form:
+ * if cond then
+ * body
+ * else
+ * else
+ * end
*
- * It is also used in the Enumerable module and by autoload as a
- * temporary placeholder.
+ * The condition is first evaluated. If it is true, then body is
+ * evaluated, otherwise else is evaluated. The result is the value of
+ * the expression evaluated, or nil if there was no expression
+ * present.
*
- * It should never be evaluated as an expression.
- *
- * It holds up to three nodes or ruby objects, depending on how it is
- * used.
+ * A conditional block using elsif has another IF node as the else
+ * expression.
*/
{
- VALUE rb_cMEMO = rb_define_class_under(rb_cNode, "MEMO", rb_cNode);
+ VALUE rb_cIF = rb_define_class_under(rb_cNode, "IF", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_MEMO] = rb_cMEMO;
- 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);
- }
+ 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-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.
- */
- {
- VALUE rb_cTO_ARY = rb_define_class_under(rb_cNode, "TO_ARY", rb_cNode);
- members = rb_ary_new();
- rb_cNodeSubclass[NODE_TO_ARY] = rb_cTO_ARY;
- rb_iv_set(rb_cTO_ARY, "__member__", members);
- rb_iv_set(rb_cTO_ARY, "__type__", INT2NUM(NODE_TO_ARY));
- rb_define_singleton_method(rb_cTO_ARY, "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: head
- * the object to convert to an array
+ /* Document-method: body
+ * the expression to evaluate if the expression is true, or false
+ * if the expression is empty
*/
- rb_define_method(rb_cTO_ARY, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
+ rb_define_method(rb_cIF, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
+
+ /* Document-method: else
+ * 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-class: Node::XSTR
- * Represents a string object inside backticks, e.g.:
- * `lit`
- * The given string is executed in a subshell and the output from its
- * stdout stored in a string.
+ /* Document-class: Node::IFUNC
+ * A temporary node used in iteration.
*/
{
- VALUE rb_cXSTR = rb_define_class_under(rb_cNode, "XSTR", rb_cNode);
+ VALUE rb_cIFUNC = rb_define_class_under(rb_cNode, "IFUNC", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_XSTR] = rb_cXSTR;
- rb_iv_set(rb_cXSTR, "__member__", members);
- rb_iv_set(rb_cXSTR, "__type__", INT2NUM(NODE_XSTR));
- rb_define_singleton_method(rb_cXSTR, "members", node_s_members, 0);
+ 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: lit
- * the string to be executed
+ /* Document-method: cfnc
+ * a pointer to the C function to which to yield
*/
- rb_define_method(rb_cXSTR, "lit", node_lit, 0);
- rb_ary_push(members, rb_str_new2("lit"));
+ rb_define_method(rb_cIFUNC, "cfnc", node_cfnc, 0);
+ rb_ary_push(members, rb_str_new2("cfnc"));
+
+ /* 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
+ */
+ rb_define_method(rb_cIFUNC, "state", node_state, 0);
+ rb_ary_push(members, rb_str_new2("state"));
}
- /* Document-class: Node::RESBODY
- * Represents the rescue portion of a rescue expression (see RESCUE for
- * examples).
+ /* Document-class: Node::ITER
+ * Represents an iteration loop, e.g.:
+ * iter do |*args|
+ * assign args to var
+ * body
+ * end
*
- * If the head node of the rescue expresion raises an exception, the
- * resq node is evaluated. The resq node is of type RESBDOY.
+ * A new block is created so that dynamic variables created inside the
+ * loop do not persist once the loop has terminated.
*
- * As it is evaluated, the type of the exception is tested against the
- * class(es) listed in the args node. If there is a match, the body
- * node is evaluated, otherwise the head node is evaluated. The head
- * node is either another RESBDOY node or false (0).
+ * If the iter node is a POSTEXE node, indicates that the expression
+ * should be evaluated when the program terminates.
*/
{
- VALUE rb_cRESBODY = rb_define_class_under(rb_cNode, "RESBODY", rb_cNode);
+ VALUE rb_cITER = rb_define_class_under(rb_cNode, "ITER", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_RESBODY] = rb_cRESBODY;
- rb_iv_set(rb_cRESBODY, "__member__", members);
- rb_iv_set(rb_cRESBODY, "__type__", INT2NUM(NODE_RESBODY));
- rb_define_singleton_method(rb_cRESBODY, "members", node_s_members, 0);
+ 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: head
- * the next rescue
+ /* Document-method: body
+ * the body of the loop
*/
- rb_define_method(rb_cRESBODY, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
+ rb_define_method(rb_cITER, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
- /* Document-method: args
- * the expression type to match against
+ /* Document-method: iter
+ * an expression which calls the desired iteration method, usually
+ * recv.each
*/
- rb_define_method(rb_cRESBODY, "args", node_args, 0);
- rb_ary_push(members, rb_str_new2("args"));
+ rb_define_method(rb_cITER, "iter", node_iter, 0);
+ rb_ary_push(members, rb_str_new2("iter"));
- /* Document-method: body
- * the expresion to evaluate if the exception type matches
+ /* 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_cRESBODY, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cITER, "var", node_var, 0);
+ rb_ary_push(members, rb_str_new2("var"));
}
- /* Document-class: Node::ALIAS
- * Represents an alias expression of the form:
- * alias 1st 2nd
- * where 2nd is the name of an existing method and 1st is the name of
- * its new alias.
+ /* Document-class: Node::IVAR
+ * A placeholder for an attribute reader method, which can added to a
+ * class by using attr_reader:
+ * attr_reader :attribute
+ * Its writer counterpart is ATTRSET.
*/
{
- VALUE rb_cALIAS = rb_define_class_under(rb_cNode, "ALIAS", rb_cNode);
+ VALUE rb_cIVAR = rb_define_class_under(rb_cNode, "IVAR", rb_cNode);
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_cNodeSubclass[NODE_IVAR] = rb_cIVAR;
+ rb_iv_set(rb_cIVAR, "__member__", members);
+ rb_iv_set(rb_cIVAR, "__type__", INT2NUM(NODE_IVAR));
+ rb_define_singleton_method(rb_cIVAR, "members", node_s_members, 0);
+
+ /* Document-method: vid
+ * the name of the attribute, with a leading '@' sign
+ */
+ rb_define_method(rb_cIVAR, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
}
- /* Document-class: Node::ARRAY
- * Represents an array of elements. Evaluation of this node creates a
- * new Array by evalating the given expressions and placing them into
- * the array.
+ /* Document-class: Node::LASGN
+ * Represents local variable assignment.
*/
{
- VALUE rb_cARRAY = rb_define_class_under(rb_cNode, "ARRAY", rb_cNode);
+ VALUE rb_cLASGN = rb_define_class_under(rb_cNode, "LASGN", rb_cNode);
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_cNodeSubclass[NODE_LASGN] = rb_cLASGN;
+ rb_iv_set(rb_cLASGN, "__member__", members);
+ rb_iv_set(rb_cLASGN, "__type__", INT2NUM(NODE_LASGN));
+ rb_define_singleton_method(rb_cLASGN, "members", node_s_members, 0);
- /* Document-method: head
- * the first element of the array
+ /* Document-method: value
+ * the value to assign to the local variable
*/
- 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"));
+ rb_define_method(rb_cLASGN, "value", node_value, 0);
+ rb_ary_push(members, rb_str_new2("value"));
- /* Document-method: next
- * the tail of the array
+ /* Document-method: vid
+ * the name of the local variable
*/
- rb_define_method(rb_cARRAY, "next", node_next, 0);
- rb_ary_push(members, rb_str_new2("next"));
+ 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::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.
+ /* Document-class: Node::LIT
+ * Represents a literal object. The result of the expression is the
+ * object contained in this node.
*/
{
- VALUE rb_cNEXT = rb_define_class_under(rb_cNode, "NEXT", rb_cNode);
+ VALUE rb_cLIT = rb_define_class_under(rb_cNode, "LIT", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_NEXT] = rb_cNEXT;
- rb_iv_set(rb_cNEXT, "__member__", members);
- rb_iv_set(rb_cNEXT, "__type__", INT2NUM(NODE_NEXT));
- rb_define_singleton_method(rb_cNEXT, "members", node_s_members, 0);
- rb_define_method(rb_cNEXT, "stts", node_stts, 0);
- rb_ary_push(members, rb_str_new2("stts"));
+ rb_cNodeSubclass[NODE_LIT] = rb_cLIT;
+ rb_iv_set(rb_cLIT, "__member__", members);
+ rb_iv_set(rb_cLIT, "__type__", INT2NUM(NODE_LIT));
+ rb_define_singleton_method(rb_cLIT, "members", node_s_members, 0);
+
+ /* Document-method: lit
+ * the object
+ */
+ rb_define_method(rb_cLIT, "lit", node_lit, 0);
+ rb_ary_push(members, rb_str_new2("lit"));
}
- /* Document-class: Node::GASGN
- * Represents global variable assignment.
+ /* Document-class: Node::LVAR
+ * Represents local variable retrieval.
*/
{
- VALUE rb_cGASGN = rb_define_class_under(rb_cNode, "GASGN", rb_cNode);
+ VALUE rb_cLVAR = rb_define_class_under(rb_cNode, "LVAR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_GASGN] = rb_cGASGN;
- rb_iv_set(rb_cGASGN, "__member__", members);
- rb_iv_set(rb_cGASGN, "__type__", INT2NUM(NODE_GASGN));
- rb_define_singleton_method(rb_cGASGN, "members", node_s_members, 0);
+ 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);
+ /* 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.
+ */
+ {
+ VALUE rb_cMASGN = rb_define_class_under(rb_cNode, "MASGN", rb_cNode);
+ members = rb_ary_new();
+ 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
+ * TODO
+ */
+ rb_define_method(rb_cMASGN, "args", node_args, 0);
+ rb_ary_push(members, rb_str_new2("args"));
+
+ /* Document-method: head
+ * TODO
+ */
+ rb_define_method(rb_cMASGN, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
+
/* Document-method: value
- * an expression whose result is the new value of the global variable
+ * TODO
*/
- rb_define_method(rb_cGASGN, "value", node_value, 0);
+ rb_define_method(rb_cMASGN, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
+ }
- /* Document-method: vid
- * the name of the global variable, with a leading '$' character.
+ /* Document-class: Node::MATCH
+ * Represents a regular expression match in a conditional, e.g.:
+ * if /lit/ then
+ * ...
+ * end
+ *
+ * This expression is equivalent to:
+ * if /lit/ =~ $_ then
+ * ...
+ * end
+ *
+ * On ruby 1.8 and newer, this type of expression causes ruby to emit a
+ * warning, unless script is running with -e.
+ */
+ {
+ VALUE rb_cMATCH = rb_define_class_under(rb_cNode, "MATCH", rb_cNode);
+ members = rb_ary_new();
+ 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_cGASGN, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
- rb_define_method(rb_cGASGN, "entry", node_entry, 0);
- rb_ary_push(members, rb_str_new2("entry"));
+ 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-class: Node::CVDECL
- * Represents class variable assignment in a class context.
+ /* Document-class: Node::MATCH2
+ * Represents a match in a conditional with a regular expression using
+ * interpolation, e.g.:
+ * if /#{recv}/ then
+ * ...
+ * end
*
- * A warning is emitted if the variable already exists.
+ * which is equivalent to:
+ * if /#{recv}/ =~ $_ then
+ * ...
+ * end
+ *
+ * or a match with a regular expression on the left hand side and an
+ * expression on the right hand side, e.g.:
+ *
+ * /recv/ =~ value
*/
{
- VALUE rb_cCVDECL = rb_define_class_under(rb_cNode, "CVDECL", rb_cNode);
+ VALUE rb_cMATCH2 = rb_define_class_under(rb_cNode, "MATCH2", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_CVDECL] = rb_cCVDECL;
- rb_iv_set(rb_cCVDECL, "__member__", members);
- rb_iv_set(rb_cCVDECL, "__type__", INT2NUM(NODE_CVDECL));
- rb_define_singleton_method(rb_cCVDECL, "members", node_s_members, 0);
+ 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: value
- * an expression whose result is the new value of the class
- * variable
+ * 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_cCVDECL, "value", node_value, 0);
+ rb_define_method(rb_cMATCH2, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
- /* Document-method: vid
- * the name of the class variable to assign
+ /* Document-method: recv
+ * the regular expression on the left hand side of the match
+ * operator
*/
- rb_define_method(rb_cCVDECL, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ rb_define_method(rb_cMATCH2, "recv", node_recv, 0);
+ rb_ary_push(members, rb_str_new2("recv"));
}
- /* Document-class: Node::ATTRASGN
- * Represents attribute assignment in the form:
- * recv.mid = args
- * or:
- * recv.mid=(args).
+ /* Document-class: Node::MATCH3
+ * Represents a regular expression match of the form:
+ * recv =~ /value/
+ *
+ * where recv is an expression that returns an object and value is a
+ * regular expression literal.
*/
{
- VALUE rb_cATTRASGN = rb_define_class_under(rb_cNode, "ATTRASGN", rb_cNode);
+ VALUE rb_cMATCH3 = rb_define_class_under(rb_cNode, "MATCH3", rb_cNode);
members = rb_ary_new();
- 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);
+ 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: args
- * the arguments to the method
+ /* Document-method: value
+ * the right hand side of the match
*/
- rb_define_method(rb_cATTRASGN, "args", node_args, 0);
- rb_ary_push(members, rb_str_new2("args"));
+ rb_define_method(rb_cMATCH3, "value", node_value, 0);
+ rb_ary_push(members, rb_str_new2("value"));
- /* 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
+ * the left hand side of the match
*/
- rb_define_method(rb_cATTRASGN, "recv", node_recv, 0);
+ rb_define_method(rb_cMATCH3, "recv", node_recv, 0);
rb_ary_push(members, rb_str_new2("recv"));
}
- /* Document-class: Node::UNDEF
- * Represents an expression using the undef keyword, e.g.:
- * undef :mid
+ /* Document-class: Node::MEMO
+ * A node used for temporary storage.
*
- * This causes the method identified by mid in the current class to be
- * undefined.
+ * It is used by the rb_protect function so that the cont_protect
+ * variable can be restored when the function returns.
+ *
+ * It is also used in the Enumerable module and by autoload as a
+ * temporary placeholder.
+ *
+ * It should never be evaluated as an expression.
+ *
+ * It holds up to three nodes or ruby objects, depending on how it is
+ * used.
*/
{
- VALUE rb_cUNDEF = rb_define_class_under(rb_cNode, "UNDEF", rb_cNode);
+ VALUE rb_cMEMO = rb_define_class_under(rb_cNode, "MEMO", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_UNDEF] = rb_cUNDEF;
- rb_iv_set(rb_cUNDEF, "__member__", members);
- rb_iv_set(rb_cUNDEF, "__type__", INT2NUM(NODE_UNDEF));
- rb_define_singleton_method(rb_cUNDEF, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_MEMO] = rb_cMEMO;
+ 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-method: mid
- * the id of the method to undefine
+ /* 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: body
+ * the body of the method
*/
- rb_define_method(rb_cUNDEF, "mid", node_mid, 0);
- rb_ary_push(members, rb_str_new2("mid"));
+ rb_define_method(rb_cMETHOD, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
+
+ /* 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-class: Node::BREAK
- * Represents the 'break' keyword. Causes control to be transferred
- * out of the current loop.
+ /* Document-class: Node::MODULE
+ * Represents a module definition, e.g.:
+ * module cpath
+ * body
+ * end
+ *
+ * The module definition is evaluated in a new lexical scope.
+ *
+ * The result of the expression is the last expression evaluated in the
+ * body.
*/
{
- VALUE rb_cBREAK = rb_define_class_under(rb_cNode, "BREAK", rb_cNode);
+ VALUE rb_cMODULE = rb_define_class_under(rb_cNode, "MODULE", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_BREAK] = rb_cBREAK;
- rb_iv_set(rb_cBREAK, "__member__", members);
- rb_iv_set(rb_cBREAK, "__type__", INT2NUM(NODE_BREAK));
- rb_define_singleton_method(rb_cBREAK, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_MODULE] = rb_cMODULE;
+ rb_iv_set(rb_cMODULE, "__member__", members);
+ rb_iv_set(rb_cMODULE, "__type__", INT2NUM(NODE_MODULE));
+ rb_define_singleton_method(rb_cMODULE, "members", node_s_members, 0);
- /* Document-method: stts
- * the value to be used as the "return" value of the loop, 0 if nil is to be used.
+ /* Document-method: cpath
+ * the name of the module to define
*/
- rb_define_method(rb_cBREAK, "stts", node_stts, 0);
- rb_ary_push(members, rb_str_new2("stts"));
+ rb_define_method(rb_cMODULE, "cpath", node_cpath, 0);
+ rb_ary_push(members, rb_str_new2("cpath"));
+
+ /* Document-method: body
+ * the body of the module definition
+ */
+ 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.
@@ -4938,10 +4804,56 @@
*/
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.
+ */
+ {
+ VALUE rb_cNEXT = rb_define_class_under(rb_cNode, "NEXT", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_NEXT] = rb_cNEXT;
+ rb_iv_set(rb_cNEXT, "__member__", members);
+ rb_iv_set(rb_cNEXT, "__type__", INT2NUM(NODE_NEXT));
+ rb_define_singleton_method(rb_cNEXT, "members", node_s_members, 0);
+ rb_define_method(rb_cNEXT, "stts", node_stts, 0);
+ rb_ary_push(members, rb_str_new2("stts"));
+ }
+
+ /* Document-class: Node::NIL
+ * Represents the keyword 'nil'.
+ */
+ {
+ VALUE rb_cNIL = rb_define_class_under(rb_cNode, "NIL", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_NIL] = rb_cNIL;
+ 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);
@@ -4962,314 +4874,371 @@
*/
rb_define_method(rb_cNTH_REF, "cnt", node_cnt, 0);
rb_ary_push(members, rb_str_new2("cnt"));
}
- /* Document-class: Node::DOT2
- * Represents a range created with the form:
- * beg..end
- * Creates a range which does not exclude the range end.
+ /* Document-class: Node::OPT_N
+ * Represents the top-level loop when the -n or -p options are used
+ * with the interpreter.
*/
{
- VALUE rb_cDOT2 = rb_define_class_under(rb_cNode, "DOT2", rb_cNode);
+ VALUE rb_cOPT_N = rb_define_class_under(rb_cNode, "OPT_N", rb_cNode);
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_cNodeSubclass[NODE_OPT_N] = rb_cOPT_N;
+ rb_iv_set(rb_cOPT_N, "__member__", members);
+ rb_iv_set(rb_cOPT_N, "__type__", INT2NUM(NODE_OPT_N));
+ rb_define_singleton_method(rb_cOPT_N, "members", node_s_members, 0);
- /* Document-method: beg
- * the beginning of the range
+ /* Document-method: body
+ * the body of the loop
*/
- 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"));
+ rb_define_method(rb_cOPT_N, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
}
- /* Document-class: Node::GVAR
- * Represents global variable retrieval.
+ /* Document-class: Node::OP_ASGN1
+ * Represents bracket assignment of the form:
+ * recv[index] += value or
+ * recv[index] ||= value or
+ * recv[index] &&= value.
+ *
+ * The index is obtained from args.body.
+ *
+ * The value is obtained from args.head.
+ *
+ * In the case of ||=, mid will be 0. The rhs will be equal to the
+ * result of evaluating args.head if the lhs is false, otherwise the
+ * rhs will be equal to lhs.
+ *
+ * In the case of &&=, mid will be 1. The rhs will be equal to the lhs
+ * if lhs is false, otherwise the rhs will be equal to the result of
+ * evaluating args.head. In all other cases, mid will be the name of
+ * the method to call to calculate value, such that the expression is
+ * equivalent to:
+ * recv[args.body] = recv[args.body].mid(args.head)
+ *
+ * In no case does ruby short-circuit the assignment.
*/
{
- VALUE rb_cGVAR = rb_define_class_under(rb_cNode, "GVAR", rb_cNode);
+ VALUE rb_cOP_ASGN1 = rb_define_class_under(rb_cNode, "OP_ASGN1", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_GVAR] = rb_cGVAR;
- rb_iv_set(rb_cGVAR, "__member__", members);
- rb_iv_set(rb_cGVAR, "__type__", INT2NUM(NODE_GVAR));
- rb_define_singleton_method(rb_cGVAR, "members", node_s_members, 0);
+ 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: vid
- * the name of the global variable to retrieve, with a leading '$'
+ /* Document-method: args
+ * the arguments to the assigment
*/
- rb_define_method(rb_cGVAR, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
- rb_define_method(rb_cGVAR, "entry", node_entry, 0);
- rb_ary_push(members, rb_str_new2("entry"));
- }
+ rb_define_method(rb_cOP_ASGN1, "args", node_args, 0);
+ rb_ary_push(members, rb_str_new2("args"));
- /* Document-class: Node::DOT3
- * Represents a range created with the form:
- * beg...end
- * Creates a range which excludes the range end.
- */
- {
- VALUE rb_cDOT3 = rb_define_class_under(rb_cNode, "DOT3", rb_cNode);
- 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);
-
- /* Document-method: beg
- * the beginning of the range
+ /* Document-method: mid
+ * 0, 1, or the name a method to call to calculate the value of the
+ * rhs
*/
- rb_define_method(rb_cDOT3, "beg", node_beg, 0);
- rb_ary_push(members, rb_str_new2("beg"));
+ rb_define_method(rb_cOP_ASGN1, "mid", node_mid, 0);
+ rb_ary_push(members, rb_str_new2("mid"));
- /* Document-method: end
- * the end of the range
+ /* Document-method: recv
+ * the receiver of the assignment
*/
- 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"));
+ rb_define_method(rb_cOP_ASGN1, "recv", node_recv, 0);
+ rb_ary_push(members, rb_str_new2("recv"));
}
- /* Document-class: Node::CVASGN
- * Represents class variable assignment in a method context.
+ /* Document-class: Node::OP_ASGN2
+ * Represents attribute assignment of the form:
+ * recv.attr op value
+ *
+ * where recv is the receiver of the attr method, attr is the attribute
+ * to which to assign, op is an assignment operation (e.g. +=), and
+ * value is the value to assign to the attribute.
+ *
+ * The 'next' member of this class is also of type OP_ASGN2, though it
+ * has different members than its parent. This child node is
+ * documented under OP_ASGN2_ARG.
*/
{
- VALUE rb_cCVASGN = rb_define_class_under(rb_cNode, "CVASGN", rb_cNode);
+ VALUE rb_cOP_ASGN2 = rb_define_class_under(rb_cNode, "OP_ASGN2", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_CVASGN] = rb_cCVASGN;
- rb_iv_set(rb_cCVASGN, "__member__", members);
- rb_iv_set(rb_cCVASGN, "__type__", INT2NUM(NODE_CVASGN));
- rb_define_singleton_method(rb_cCVASGN, "members", node_s_members, 0);
+ 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: value
- * an expression whose result is the new value of the class
- * variable
+ * the value to assign to the attribute
*/
- rb_define_method(rb_cCVASGN, "value", node_value, 0);
+ rb_define_method(rb_cOP_ASGN2, "value", node_value, 0);
rb_ary_push(members, rb_str_new2("value"));
- /* Document-method: vid
- * the name of the class variable to assign
+ /* 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_cCVASGN, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ rb_define_method(rb_cOP_ASGN2, "next", node_next, 0);
+ rb_ary_push(members, rb_str_new2("next"));
+
+ /* Document-method: recv
+ * the receiver of the attribute
+ */
+ rb_define_method(rb_cOP_ASGN2, "recv", node_recv, 0);
+ rb_ary_push(members, rb_str_new2("recv"));
}
- /* 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.
+ /* 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
+ * OP_ASGN2 node.
*/
{
- VALUE rb_cCREF = rb_define_class_under(rb_cNode, "CREF", rb_cNode);
+ VALUE rb_cOP_ASGN2_ARG = rb_define_class_under(rb_cNode, "OP_ASGN2_ARG", 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);
+ 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: body
- * always 0 (false)
+ /* Document-method: vid
+ * The method to call on the receiver to retrieve the attribute
*/
- rb_define_method(rb_cCREF, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cOP_ASGN2_ARG, "vid", node_vid, 0);
+ rb_ary_push(members, rb_str_new2("vid"));
- /* Document-method: next
- * the previous value of ruby_cref or ruby_top_cref
+ /* Document-method: aid
+ * The method to call on the receiver to set the attribute
*/
- rb_define_method(rb_cCREF, "next", node_next, 0);
- rb_ary_push(members, rb_str_new2("next"));
+ rb_define_method(rb_cOP_ASGN2_ARG, "aid", node_aid, 0);
+ rb_ary_push(members, rb_str_new2("aid"));
- /* Document-method: clss
- * the new class to use for the cbase.
+ /* Document-method: mid
+ * The operation to apply to the attribute before setting it. May
+ * be 0 (false) to indicate "logical or" or 1 (nil) to indicate
+ * "logical and".
*/
- rb_define_method(rb_cCREF, "clss", node_clss, 0);
- rb_ary_push(members, rb_str_new2("clss"));
+ rb_define_method(rb_cOP_ASGN2_ARG, "mid", node_mid, 0);
+ rb_ary_push(members, rb_str_new2("mid"));
}
- /* Document-class: Node::SPLAT
- * Represents the splat (*) operation as an rvalue, e.g.:
- * *head
- * If the argument is an array, returns self.
- * If the argument is nil, returns [nil].
- * If the argument is any other value, returns the result of calling #to_a on the
- * argument.
+ /* Document-class: Node::OP_ASGN_AND
+ * Represents an expression of the form:
+ * recv &&= value
+ * Ruby will evaluate the expression on the left hand side of the
+ * assignment; if it is true, then it will assign the result of the
+ * expression on the right hand side to the receiver on the left hand
+ * side.
*/
{
- VALUE rb_cSPLAT = rb_define_class_under(rb_cNode, "SPLAT", rb_cNode);
+ VALUE rb_cOP_ASGN_AND = rb_define_class_under(rb_cNode, "OP_ASGN_AND", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_SPLAT] = rb_cSPLAT;
- rb_iv_set(rb_cSPLAT, "__member__", members);
- rb_iv_set(rb_cSPLAT, "__type__", INT2NUM(NODE_SPLAT));
- rb_define_singleton_method(rb_cSPLAT, "members", node_s_members, 0);
+ 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: head
- * the argument to splat.
+ /* Document-method: value
+ * an expression representing the assignment that should be
+ * performed if the left hand side is true
*/
- rb_define_method(rb_cSPLAT, "head", node_head, 0);
- rb_ary_push(members, rb_str_new2("head"));
+ 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::MODULE
- * Represents a module definition, e.g.:
- * module cpath
- * body
- * end
- *
- * The module definition is evaluated in a new lexical scope.
- *
- * The result of the expression is the last expression evaluated in the
- * body.
+ /* Document-class: Node::OP_ASGN_OR
+ * Represents an expression of the form:
+ * recv ||= value
+ * Ruby will evaluate the expression on the left hand side. If it is
+ * undefined, nil, or false, then ruby will evaluate the expression on
+ * the right hand side and assign it to recv. The expression will
+ * short-circuit if recv is defined and true (non-false, non-nil).
*/
{
- VALUE rb_cMODULE = rb_define_class_under(rb_cNode, "MODULE", rb_cNode);
+ VALUE rb_cOP_ASGN_OR = rb_define_class_under(rb_cNode, "OP_ASGN_OR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_MODULE] = rb_cMODULE;
- rb_iv_set(rb_cMODULE, "__member__", members);
- rb_iv_set(rb_cMODULE, "__type__", INT2NUM(NODE_MODULE));
- rb_define_singleton_method(rb_cMODULE, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_OP_ASGN_OR] = rb_cOP_ASGN_OR;
+ rb_iv_set(rb_cOP_ASGN_OR, "__member__", members);
+ rb_iv_set(rb_cOP_ASGN_OR, "__type__", INT2NUM(NODE_OP_ASGN_OR));
+ rb_define_singleton_method(rb_cOP_ASGN_OR, "members", node_s_members, 0);
- /* Document-method: cpath
- * the name of the module to define
+ /* Document-method: aid
+ * if this indicator is nonzero, ruby will check to see if the
+ * provided expression is defined, otherwise it will assume that
+ * the provided expression is defined.
*/
- rb_define_method(rb_cMODULE, "cpath", node_cpath, 0);
- rb_ary_push(members, rb_str_new2("cpath"));
+ rb_define_method(rb_cOP_ASGN_OR, "aid", node_aid, 0);
+ rb_ary_push(members, rb_str_new2("aid"));
- /* Document-method: body
- * the body of the module definition
+ /* Document-method: value
+ * the right hand side of the assignment
*/
- rb_define_method(rb_cMODULE, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cOP_ASGN_OR, "value", node_value, 0);
+ rb_ary_push(members, rb_str_new2("value"));
+
+ /* Document-method: recv
+ * the receiver of the assignment
+ */
+ rb_define_method(rb_cOP_ASGN_OR, "recv", node_recv, 0);
+ rb_ary_push(members, rb_str_new2("recv"));
}
- /* Document-class: Node::FOR
- * Represents a loop constructed with the 'for' keyword, e.g.:
- * for var in iter do
- * body
- * end
- *
- * This is equivalent to:
- * iter.each do |*args|
- * assign args to var
- * body
- * end
- *
- * Except that a new block is not created.
+ /* Document-class: Node::OR
+ * Represents a logical 'or' of the form:
+ * first || second
+ * The expression will short-circuit and yield the result of the left
+ * hand side if it is true, else it will evaluate the right hand side
+ * and use it as the result of the expression.
*/
{
- VALUE rb_cFOR = rb_define_class_under(rb_cNode, "FOR", rb_cNode);
+ VALUE rb_cOR = rb_define_class_under(rb_cNode, "OR", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_OR] = rb_cOR;
+ rb_iv_set(rb_cOR, "__member__", members);
+ rb_iv_set(rb_cOR, "__type__", INT2NUM(NODE_OR));
+ rb_define_singleton_method(rb_cOR, "members", node_s_members, 0);
- /* Document-method: body
- * the body of the loop
+ /* Document-method: first
+ * the expression on the left hand side
*/
- rb_define_method(rb_cFOR, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_define_method(rb_cOR, "first", node_1st, 0);
+ rb_ary_push(members, rb_str_new2("first"));
- /* Document-method: iter
- * the sequence over which to iterate
+ /* Document-method: second
+ * the expression on the right hand side
*/
- 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"));
+ rb_define_method(rb_cOR, "second", node_2nd, 0);
+ rb_ary_push(members, rb_str_new2("second"));
}
- /* Document-class: Node::DVAR
- * Represents dynamic local variable retrieval. See also DASGN.
+ /* Document-class: Node::POSTEXE
+ * Represents the END keyword, e.g.:
+ * END { ... }
+ *
+ * Indicating that the enclosing ITER node is to be excecuted only
+ * once, when the program terminates.
*/
{
- VALUE rb_cDVAR = rb_define_class_under(rb_cNode, "DVAR", rb_cNode);
+ VALUE rb_cPOSTEXE = rb_define_class_under(rb_cNode, "POSTEXE", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_DVAR] = rb_cDVAR;
- rb_iv_set(rb_cDVAR, "__member__", members);
- rb_iv_set(rb_cDVAR, "__type__", INT2NUM(NODE_DVAR));
- rb_define_singleton_method(rb_cDVAR, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_POSTEXE] = rb_cPOSTEXE;
+ rb_iv_set(rb_cPOSTEXE, "__member__", members);
+ rb_iv_set(rb_cPOSTEXE, "__type__", INT2NUM(NODE_POSTEXE));
+ rb_define_singleton_method(rb_cPOSTEXE, "members", node_s_members, 0);
+ }
- /* Document-method: vid
- * the name of the local variable to retrieve.
- */
- rb_define_method(rb_cDVAR, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ /* Document-class: Node::REDO
+ * Represents the 'redo' keyword. Causes control to be transferred to
+ * the beginning of the loop. The loop assignment is not repeated.
+ */
+ {
+ VALUE rb_cREDO = rb_define_class_under(rb_cNode, "REDO", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_REDO] = rb_cREDO;
+ rb_iv_set(rb_cREDO, "__member__", members);
+ rb_iv_set(rb_cREDO, "__type__", INT2NUM(NODE_REDO));
+ rb_define_singleton_method(rb_cREDO, "members", node_s_members, 0);
}
- /* Document-class: Node::DSTR
- * Represents a string object with interpolation. The node is
- * evaluated by duplicating the string stored in the 'lit' element,
- * then iterating over the nodes stored in the 'next' element. Each
- * node found should evalate to a string, and each resulting string is
- * appended onto the regex. Interpolation is represented with the
- * EVSTR node.
+ /* Document-class: Node::RESBODY
+ * Represents the rescue portion of a rescue expression (see RESCUE for
+ * examples).
+ *
+ * If the head node of the rescue expresion raises an exception, the
+ * resq node is evaluated. The resq node is of type RESBDOY.
+ *
+ * As it is evaluated, the type of the exception is tested against the
+ * class(es) listed in the args node. If there is a match, the body
+ * node is evaluated, otherwise the head node is evaluated. The head
+ * node is either another RESBDOY node or false (0).
*/
{
- VALUE rb_cDSTR = rb_define_class_under(rb_cNode, "DSTR", rb_cNode);
+ VALUE rb_cRESBODY = rb_define_class_under(rb_cNode, "RESBODY", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_DSTR] = rb_cDSTR;
- rb_iv_set(rb_cDSTR, "__member__", members);
- rb_iv_set(rb_cDSTR, "__type__", INT2NUM(NODE_DSTR));
- rb_define_singleton_method(rb_cDSTR, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_RESBODY] = rb_cRESBODY;
+ rb_iv_set(rb_cRESBODY, "__member__", members);
+ rb_iv_set(rb_cRESBODY, "__type__", INT2NUM(NODE_RESBODY));
+ rb_define_singleton_method(rb_cRESBODY, "members", node_s_members, 0);
- /* Document-method: lit
- * a string
+ /* Document-method: head
+ * the next rescue
*/
- rb_define_method(rb_cDSTR, "lit", node_lit, 0);
- rb_ary_push(members, rb_str_new2("lit"));
+ rb_define_method(rb_cRESBODY, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
- /* Document-method: next
- * a list of expressions to be appended onto the string
+ /* Document-method: args
+ * the expression type to match against
*/
- rb_define_method(rb_cDSTR, "next", node_next, 0);
- rb_ary_push(members, rb_str_new2("next"));
+ rb_define_method(rb_cRESBODY, "args", node_args, 0);
+ rb_ary_push(members, rb_str_new2("args"));
+
+ /* Document-method: body
+ * the expresion to evaluate if the exception type matches
+ */
+ rb_define_method(rb_cRESBODY, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
}
- /* 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.
+ /* Document-class: Node::RESCUE
+ * Represents part of a rescue expression of the form:
+ * head rescue expr
+ *
+ * or the longer form:
+ * begin
+ * head
+ * rescue exception
+ * expr
+ * end
+ *
+ * or the form using the else keyword:
+ * begin
+ * head
+ * rescue exception
+ * expr
+ * else
+ * else_expr
+ * end
+ *
+ * The head expression is first evaluated, and if an exception is
+ * raised, evaluates the resq node. If no exception is raised, the
+ * else node is evaluated if it is not false (0).
+ *
+ * The resq node will be a RESBDOY node, which will test the exception
+ * to see if it matches one of the expected types. If it does it will
+ * handle the exception, otherwise it will allow the expression to pass
+ * to the outer scope.
*/
{
- VALUE rb_cSVALUE = rb_define_class_under(rb_cNode, "SVALUE", rb_cNode);
+ VALUE rb_cRESCUE = rb_define_class_under(rb_cNode, "RESCUE", 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);
+ 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
- * an expression which returns an Array.
+ * the body of the block to evaluate
*/
- rb_define_method(rb_cSVALUE, "head", node_head, 0);
+ 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"));
+
+ /* 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-class: Node::RETRY
* Represents the retry keyword.
*/
@@ -5280,413 +5249,429 @@
rb_iv_set(rb_cRETRY, "__member__", members);
rb_iv_set(rb_cRETRY, "__type__", INT2NUM(NODE_RETRY));
rb_define_singleton_method(rb_cRETRY, "members", node_s_members, 0);
}
- /* Document-class: Node::CLASS
- * Represents a class definition, e.g.:
- * class cpath
+ /* Document-class: Node::RETURN
+ * Represents the 'return' keyword. Evaluation of this node results in
+ * a return from the current method. If no argument is supplied,
+ * returns nil, otherwise returns the result of the supplied
+ * expression.
+ */
+ {
+ VALUE rb_cRETURN = rb_define_class_under(rb_cNode, "RETURN", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_RETURN] = rb_cRETURN;
+ rb_iv_set(rb_cRETURN, "__member__", members);
+ rb_iv_set(rb_cRETURN, "__type__", INT2NUM(NODE_RETURN));
+ rb_define_singleton_method(rb_cRETURN, "members", node_s_members, 0);
+
+ /* Document-method: stts
+ * an expression representing the value to return
+ */
+ rb_define_method(rb_cRETURN, "stts", node_stts, 0);
+ rb_ary_push(members, rb_str_new2("stts"));
+ }
+
+ /* Document-class: Node::SCLASS
+ * Represents the body of a singleton class definition, e.g.:
+ * class << recv
* body
* end
*
- * or:
- * class cpath < super
- * body
- * end
- *
* The class definition is evaluated in a new lexical scope.
*
* The result of the expression is the last expression evaluated in the
* body.
*/
{
- VALUE rb_cCLASS = rb_define_class_under(rb_cNode, "CLASS", rb_cNode);
+ VALUE rb_cSCLASS = rb_define_class_under(rb_cNode, "SCLASS", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_CLASS] = rb_cCLASS;
- rb_iv_set(rb_cCLASS, "__member__", members);
- rb_iv_set(rb_cCLASS, "__type__", INT2NUM(NODE_CLASS));
- rb_define_singleton_method(rb_cCLASS, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_SCLASS] = rb_cSCLASS;
+ rb_iv_set(rb_cSCLASS, "__member__", members);
+ rb_iv_set(rb_cSCLASS, "__type__", INT2NUM(NODE_SCLASS));
+ rb_define_singleton_method(rb_cSCLASS, "members", node_s_members, 0);
- /* Document-method: cpath
- * the name of the class to define
- */
- rb_define_method(rb_cCLASS, "cpath", node_cpath, 0);
- rb_ary_push(members, rb_str_new2("cpath"));
-
/* Document-method: body
* the body of the class definition
*/
- rb_define_method(rb_cCLASS, "body", node_body, 0);
+ rb_define_method(rb_cSCLASS, "body", node_body, 0);
rb_ary_push(members, rb_str_new2("body"));
- /* Document-method: super
- * an expression returning the base class, or false if there is no
- * base class specified
+ /* Document-method: recv
+ * the object whose singleton class is to be modified
*/
- rb_define_method(rb_cCLASS, "super", node_super, 0);
- rb_ary_push(members, rb_str_new2("super"));
+ rb_define_method(rb_cSCLASS, "recv", node_recv, 0);
+ rb_ary_push(members, rb_str_new2("recv"));
}
- /* Document-class: Node::DASGN
- * Represents dynamic local variable assignment. Dynamic assignment
- * differs from static assignment in that the slots for static local
- * variables are allocated when the method is called, wereas slots for
- * dynamic variables are allocated when the variable is first assigned
- * to. When searching for the variable, dynamic assignment searches
- * backward up the stack to see if the variable exists in any previous
- * block in the current frame; if it does, it assigns to the slot found
- * in that block, otherwise it creates a new variable slot. As a
- * result, dynamic assignment is typically much slower than static
- * assignment.
+ /* Document-class: Node::SCOPE
+ * Represents a lexical scope.
+ *
+ * A new scope is created when a method is invoked. The scope node
+ * holds information about local variables and arguments to the method.
+ * The first two variables in the local variable table are the implicit
+ * variables $_ and $~.
+ *
+ * The next variables listed in the local variable table are the
+ * arguments to the method. More information about the arguments to
+ * the method are stored in the ARGS node, which will either be the
+ * first node in the scope or the first node in the BLOCK held by the
+ * scope.
*/
{
- VALUE rb_cDASGN = rb_define_class_under(rb_cNode, "DASGN", rb_cNode);
+ VALUE rb_cSCOPE = rb_define_class_under(rb_cNode, "SCOPE", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_DASGN] = rb_cDASGN;
- rb_iv_set(rb_cDASGN, "__member__", members);
- rb_iv_set(rb_cDASGN, "__type__", INT2NUM(NODE_DASGN));
- rb_define_singleton_method(rb_cDASGN, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_SCOPE] = rb_cSCOPE;
+ rb_iv_set(rb_cSCOPE, "__member__", members);
+ rb_iv_set(rb_cSCOPE, "__type__", INT2NUM(NODE_SCOPE));
+ rb_define_singleton_method(rb_cSCOPE, "members", node_s_members, 0);
- /* Document-method: value
- * the value to assign to the local variable
+ /* Document-method: tbl
+ * the names of the local variables* next the first expression in
+ * the scope
*/
- rb_define_method(rb_cDASGN, "value", node_value, 0);
- rb_ary_push(members, rb_str_new2("value"));
+ rb_define_method(rb_cSCOPE, "tbl", node_tbl, 0);
+ rb_ary_push(members, rb_str_new2("tbl"));
- /* Document-method: vid
- * the name of the local variable
+ /* Document-method: rval
+ * holds information about which class(es) to search for constants
+ * in this scope
*/
- rb_define_method(rb_cDASGN, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ 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::NIL
- * Represents the keyword 'nil'.
+ /* Document-class: Node::SELF
+ * Represents the keyword 'self'.
*/
{
- VALUE rb_cNIL = rb_define_class_under(rb_cNode, "NIL", rb_cNode);
+ VALUE rb_cSELF = rb_define_class_under(rb_cNode, "SELF", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_NIL] = rb_cNIL;
- 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);
+ rb_cNodeSubclass[NODE_SELF] = rb_cSELF;
+ rb_iv_set(rb_cSELF, "__member__", members);
+ rb_iv_set(rb_cSELF, "__type__", INT2NUM(NODE_SELF));
+ rb_define_singleton_method(rb_cSELF, "members", node_s_members, 0);
}
- /* Document-class: Node::IVAR
- * A placeholder for an attribute reader method, which can added to a
- * class by using attr_reader:
- * attr_reader :attribute
- * Its writer counterpart is ATTRSET.
+ /* Document-class: Node::SPLAT
+ * Represents the splat (*) operation as an rvalue, e.g.:
+ * *head
+ * If the argument is an array, returns self.
+ * If the argument is nil, returns [nil].
+ * If the argument is any other value, returns the result of calling #to_a on the
+ * argument.
*/
{
- VALUE rb_cIVAR = rb_define_class_under(rb_cNode, "IVAR", rb_cNode);
+ VALUE rb_cSPLAT = rb_define_class_under(rb_cNode, "SPLAT", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_IVAR] = rb_cIVAR;
- rb_iv_set(rb_cIVAR, "__member__", members);
- rb_iv_set(rb_cIVAR, "__type__", INT2NUM(NODE_IVAR));
- rb_define_singleton_method(rb_cIVAR, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_SPLAT] = rb_cSPLAT;
+ rb_iv_set(rb_cSPLAT, "__member__", members);
+ rb_iv_set(rb_cSPLAT, "__type__", INT2NUM(NODE_SPLAT));
+ rb_define_singleton_method(rb_cSPLAT, "members", node_s_members, 0);
- /* Document-method: vid
- * the name of the attribute, with a leading '@' sign
+ /* Document-method: head
+ * the argument to splat.
*/
- rb_define_method(rb_cIVAR, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ rb_define_method(rb_cSPLAT, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
}
- /* Document-class: Node::LVAR
- * Represents local variable retrieval.
+ /* Document-class: Node::STR
+ * Represents a string object. Duplicates the string stored in the
+ * node.
*/
{
- VALUE rb_cLVAR = rb_define_class_under(rb_cNode, "LVAR", rb_cNode);
+ VALUE rb_cSTR = rb_define_class_under(rb_cNode, "STR", rb_cNode);
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_cNodeSubclass[NODE_STR] = rb_cSTR;
+ rb_iv_set(rb_cSTR, "__member__", members);
+ rb_iv_set(rb_cSTR, "__type__", INT2NUM(NODE_STR));
+ rb_define_singleton_method(rb_cSTR, "members", node_s_members, 0);
- /* Document-method: vid
- * the name of the local variable to retrieve.
+ /* Document-method: lit
+ * the string to be duplicated
*/
- 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"));
+ rb_define_method(rb_cSTR, "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.:
- * if /#{recv}/ then
- * ...
- * end
- *
- * which is equivalent to:
- * if /#{recv}/ =~ $_ then
- * ...
- * end
- *
- * or a match with a regular expression on the left hand side and an
- * expression on the right hand side, e.g.:
- *
- * /recv/ =~ value
+ /* Document-class: Node::SUPER
+ * Represents the keyword 'super' when used with parens or with arguments.
*/
{
- VALUE rb_cMATCH2 = rb_define_class_under(rb_cNode, "MATCH2", rb_cNode);
+ VALUE rb_cSUPER = rb_define_class_under(rb_cNode, "SUPER", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_SUPER] = rb_cSUPER;
+ rb_iv_set(rb_cSUPER, "__member__", members);
+ rb_iv_set(rb_cSUPER, "__type__", INT2NUM(NODE_SUPER));
+ rb_define_singleton_method(rb_cSUPER, "members", node_s_members, 0);
- /* 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
+ /* Document-method: args
+ * the arguments to be passed to the base class
*/
- 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"));
+ rb_define_method(rb_cSUPER, "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
- * body
- * end
+ /* 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_cFLIP2 = rb_define_class_under(rb_cNode, "FLIP2", rb_cNode);
+ VALUE rb_cSVALUE = rb_define_class_under(rb_cNode, "SVALUE", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_FLIP2] = rb_cFLIP2;
- rb_iv_set(rb_cFLIP2, "__member__", members);
- rb_iv_set(rb_cFLIP2, "__type__", INT2NUM(NODE_FLIP2));
- rb_define_singleton_method(rb_cFLIP2, "members", node_s_members, 0);
+ 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: beg
- * the beginning of the range
+ /* Document-method: head
+ * an expression which returns an Array.
*/
- 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: cnt
- * the index into the local variable table of the special variable
- * 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"));
+ rb_define_method(rb_cSVALUE, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
}
- /* Document-class: Node::CONST
- * Represents a constant lookup in the current class. The current
- * class is the class in which the containing scope was defined. The
- * result of the expression is the value of the constant.
+ /* 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.
*/
{
- VALUE rb_cCONST = rb_define_class_under(rb_cNode, "CONST", rb_cNode);
+ VALUE rb_cTO_ARY = rb_define_class_under(rb_cNode, "TO_ARY", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_CONST] = rb_cCONST;
- rb_iv_set(rb_cCONST, "__member__", members);
- rb_iv_set(rb_cCONST, "__type__", INT2NUM(NODE_CONST));
- rb_define_singleton_method(rb_cCONST, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_TO_ARY] = rb_cTO_ARY;
+ rb_iv_set(rb_cTO_ARY, "__member__", members);
+ rb_iv_set(rb_cTO_ARY, "__type__", INT2NUM(NODE_TO_ARY));
+ rb_define_singleton_method(rb_cTO_ARY, "members", node_s_members, 0);
- /* Document-method: vid
- * the name of the constant to look up
+ /* Document-method: head
+ * the object to convert to an array
*/
- rb_define_method(rb_cCONST, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ rb_define_method(rb_cTO_ARY, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
}
- /* Document-class: Node::METHOD
- * A placeholder for a method entry in a class's method table.
+ /* Document-class: Node::TRUE
+ * Represents the keyword 'true'.
*/
{
- VALUE rb_cMETHOD = rb_define_class_under(rb_cNode, "METHOD", rb_cNode);
+ VALUE rb_cTRUE = rb_define_class_under(rb_cNode, "TRUE", 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: body
- * the body of the method
- */
- rb_define_method(rb_cMETHOD, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
-
- /* Document-method: noex
- * the method's flags
- */
- rb_define_method(rb_cMETHOD, "noex", node_noex, 0);
- rb_ary_push(members, rb_str_new2("noex"));
+ rb_cNodeSubclass[NODE_TRUE] = rb_cTRUE;
+ rb_iv_set(rb_cTRUE, "__member__", members);
+ rb_iv_set(rb_cTRUE, "__type__", INT2NUM(NODE_TRUE));
+ rb_define_singleton_method(rb_cTRUE, "members", node_s_members, 0);
}
- /* Document-class: Node::MATCH3
- * Represents a regular expression match of the form:
- * recv =~ /value/
+ /* Document-class: Node::UNDEF
+ * Represents an expression using the undef keyword, e.g.:
+ * undef :mid
*
- * where recv is an expression that returns an object and value is a
- * regular expression literal.
+ * This causes the method identified by mid in the current class to be
+ * undefined.
*/
{
- VALUE rb_cMATCH3 = rb_define_class_under(rb_cNode, "MATCH3", rb_cNode);
+ VALUE rb_cUNDEF = rb_define_class_under(rb_cNode, "UNDEF", rb_cNode);
members = rb_ary_new();
- 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);
+ rb_cNodeSubclass[NODE_UNDEF] = rb_cUNDEF;
+ rb_iv_set(rb_cUNDEF, "__member__", members);
+ rb_iv_set(rb_cUNDEF, "__type__", INT2NUM(NODE_UNDEF));
+ rb_define_singleton_method(rb_cUNDEF, "members", node_s_members, 0);
- /* Document-method: value
- * the right hand side of the match
+ /* Document-method: mid
+ * the id of the method to undefine
*/
- 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"));
+ rb_define_method(rb_cUNDEF, "mid", node_mid, 0);
+ rb_ary_push(members, rb_str_new2("mid"));
}
- /* Document-class: Node::IASGN
- * Represents instance variable assignment.
+ /* Document-class: Node::UNTIL
+ * Represents a loop constructed with the 'until' keyword, e.g.:
+ * until cond do
+ * body
+ * end
*/
{
- VALUE rb_cIASGN = rb_define_class_under(rb_cNode, "IASGN", rb_cNode);
+ VALUE rb_cUNTIL = rb_define_class_under(rb_cNode, "UNTIL", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_IASGN] = rb_cIASGN;
- rb_iv_set(rb_cIASGN, "__member__", members);
- rb_iv_set(rb_cIASGN, "__type__", INT2NUM(NODE_IASGN));
- rb_define_singleton_method(rb_cIASGN, "members", node_s_members, 0);
+ 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);
- /* Document-method: value
- * the value to assign to the instance variable
+ /* Document-method: body
+ * the body of the loop
*/
- rb_define_method(rb_cIASGN, "value", node_value, 0);
- rb_ary_push(members, rb_str_new2("value"));
+ rb_define_method(rb_cUNTIL, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
- /* Document-method: vid
- * the name of the instance variable, with a leading '@' sign
+ /* Document-method: cond
+ * a condition to terminate the loop when it becomes true
*/
- rb_define_method(rb_cIASGN, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ 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::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.
+ /* Document-class: Node::VALIAS
+ * Represents an alias expression of the form:
+ * alias 1st 2nd
+ * where 2nd is the name of a variable and 1st is the name of its new
+ * alias.
*/
{
- VALUE rb_cDMETHOD = rb_define_class_under(rb_cNode, "DMETHOD", rb_cNode);
+ VALUE rb_cVALIAS = rb_define_class_under(rb_cNode, "VALIAS", 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);
+ 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"));
+ }
- /* Document-method: cval
- * the Method object passed to define_method, which contains the
- * body of the method
+ /* Document-class: Node::VCALL
+ * Represents a local variable or a method call without an explicit
+ * receiver, to be determined at run-time.
+ */
+ {
+ VALUE rb_cVCALL = rb_define_class_under(rb_cNode, "VCALL", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_VCALL] = rb_cVCALL;
+ rb_iv_set(rb_cVCALL, "__member__", members);
+ rb_iv_set(rb_cVCALL, "__type__", INT2NUM(NODE_VCALL));
+ rb_define_singleton_method(rb_cVCALL, "members", node_s_members, 0);
+
+ /* Document-method: mid
+ * the name of the variable or method
*/
- rb_define_method(rb_cDMETHOD, "cval", node_cval, 0);
- rb_ary_push(members, rb_str_new2("cval"));
+ rb_define_method(rb_cVCALL, "mid", node_mid, 0);
+ rb_ary_push(members, rb_str_new2("mid"));
}
- /* Document-class: Node::FLIP3
- * Represents part of a sed-like flip-flop expression of the form:
- * if beg..end then
+ /* Document-class: Node::WHEN
+ * Represents either a conditional in a case/end block:
+ * case value
+ * when head
* body
+ * next
* end
+ *
+ * or the first element of a a case/end block with no conditional:
+ * case
+ * when head
+ * body
+ * next
+ * end
+ *
+ * In the first case, value is evaluated and head is evaluated, and
+ * they are compared using head === value. If the result is true, then
+ * body is evaluated and no more when conditions are tried, otherwise
+ * the interpreter evaluates the next node.
+ *
+ * In the second case, head is tested using rtest(value). If the
+ * result is true, then body is evaluated and no more when conditions
+ * are tried, otherwise the interpreter evaluates the next node.
+ *
+ * If the condition evaluates to false and there are no more when
+ * conditions to try, the result of the expression is nil.
+ *
+ * If the next expression to try is not a WHEN node, then it represents
+ * an else element and is evaluated unconditionally.
*/
{
- VALUE rb_cFLIP3 = rb_define_class_under(rb_cNode, "FLIP3", rb_cNode);
+ VALUE rb_cWHEN = rb_define_class_under(rb_cNode, "WHEN", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_FLIP3] = rb_cFLIP3;
- rb_iv_set(rb_cFLIP3, "__member__", members);
- rb_iv_set(rb_cFLIP3, "__type__", INT2NUM(NODE_FLIP3));
- rb_define_singleton_method(rb_cFLIP3, "members", node_s_members, 0);
+ 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: beg
- * the beginning of the range
+ /* Document-method: head
+ * a value to compare against, or a condition to be tested
*/
- rb_define_method(rb_cFLIP3, "beg", node_beg, 0);
- rb_ary_push(members, rb_str_new2("beg"));
+ rb_define_method(rb_cWHEN, "head", node_head, 0);
+ rb_ary_push(members, rb_str_new2("head"));
- /* Document-method: end
- * the end of the range
+ /* Document-method: body
+ * an expression to evaluate if the condition evaluates to true
*/
- rb_define_method(rb_cFLIP3, "end", node_end, 0);
- rb_ary_push(members, rb_str_new2("end"));
+ rb_define_method(rb_cWHEN, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
- /* Document-method: cnt
- * the index into the local variable table of the special variable
- * to use in the flip-flop expression (usually 2 for $_)
+ /* Document-method: next
+ * the next expression to be evaluated if the condition is false
*/
- rb_define_method(rb_cFLIP3, "cnt", node_cnt, 0);
- rb_ary_push(members, rb_str_new2("cnt"));
+ rb_define_method(rb_cWHEN, "next", node_next, 0);
+ rb_ary_push(members, rb_str_new2("next"));
}
- /* Document-class: Node::OR
- * Represents a logical 'or' of the form:
- * first || second
- * The expression will short-circuit and yield the result of the left
- * hand side if it is true, else it will evaluate the right hand side
- * and use it as the result of the expression.
+ /* Document-class: Node::WHILE
+ * Represents a loop constructed with the 'while' keyword, e.g.:
+ * while cond do
+ * body
+ * end
*/
{
- VALUE rb_cOR = rb_define_class_under(rb_cNode, "OR", rb_cNode);
+ VALUE rb_cWHILE = rb_define_class_under(rb_cNode, "WHILE", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_OR] = rb_cOR;
- rb_iv_set(rb_cOR, "__member__", members);
- rb_iv_set(rb_cOR, "__type__", INT2NUM(NODE_OR));
- rb_define_singleton_method(rb_cOR, "members", node_s_members, 0);
+ 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);
- /* Document-method: first
- * the expression on the left hand side
+ /* Document-method: body
+ * the body of the loop
*/
- rb_define_method(rb_cOR, "first", node_1st, 0);
- rb_ary_push(members, rb_str_new2("first"));
+ rb_define_method(rb_cWHILE, "body", node_body, 0);
+ rb_ary_push(members, rb_str_new2("body"));
- /* Document-method: second
- * the expression on the right hand side
+ /* Document-method: cond
+ * a condition to terminate the loop when it becomes false
*/
- rb_define_method(rb_cOR, "second", node_2nd, 0);
- rb_ary_push(members, rb_str_new2("second"));
+ 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::CVAR
- * Represents a class variable retrieval. The result of the expression
- * is the value of the class variable.
+ /* Document-class: Node::XSTR
+ * Represents a string object inside backticks, e.g.:
+ * `lit`
+ * The given string is executed in a subshell and the output from its
+ * stdout stored in a string.
*/
{
- VALUE rb_cCVAR = rb_define_class_under(rb_cNode, "CVAR", rb_cNode);
+ VALUE rb_cXSTR = rb_define_class_under(rb_cNode, "XSTR", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_CVAR] = rb_cCVAR;
- rb_iv_set(rb_cCVAR, "__member__", members);
- rb_iv_set(rb_cCVAR, "__type__", INT2NUM(NODE_CVAR));
- rb_define_singleton_method(rb_cCVAR, "members", node_s_members, 0);
+ rb_cNodeSubclass[NODE_XSTR] = rb_cXSTR;
+ rb_iv_set(rb_cXSTR, "__member__", members);
+ rb_iv_set(rb_cXSTR, "__type__", INT2NUM(NODE_XSTR));
+ rb_define_singleton_method(rb_cXSTR, "members", node_s_members, 0);
- /* Document-method: vid
- * the name of the class variable, with two leading '@' characters.
+ /* Document-method: lit
+ * the string to be executed
*/
- rb_define_method(rb_cCVAR, "vid", node_vid, 0);
- rb_ary_push(members, rb_str_new2("vid"));
+ rb_define_method(rb_cXSTR, "lit", node_lit, 0);
+ rb_ary_push(members, rb_str_new2("lit"));
}
/* Document-class: Node::YIELD
* Represents the 'yield' keyword. When evaluated, causes control of
* the program to be transferred to the block passed by the calling
@@ -5711,23 +5696,38 @@
*/
rb_define_method(rb_cYIELD, "state", node_state, 0);
rb_ary_push(members, rb_str_new2("state"));
}
- /* Document-class: Node::BEGIN
- * Represents a begin/end block.
+ /* Document-class: Node::ZARRAY
+ * Represents an array of zero elements. Evalation of this node
+ * creates a new array of length zero.
+ */
+ {
+ VALUE rb_cZARRAY = rb_define_class_under(rb_cNode, "ZARRAY", rb_cNode);
+ members = rb_ary_new();
+ rb_cNodeSubclass[NODE_ZARRAY] = rb_cZARRAY;
+ rb_iv_set(rb_cZARRAY, "__member__", members);
+ rb_iv_set(rb_cZARRAY, "__type__", INT2NUM(NODE_ZARRAY));
+ rb_define_singleton_method(rb_cZARRAY, "members", node_s_members, 0);
+ }
+
+ /* Document-class: Node::ZSUPER
+ * Represents the keyword 'super' when used without parens nor
+ * arguments. The arguments to the base class method are obtained from
+ * the arguments passed to the current method, which are store in the
+ * current frame.
*
- * TODO: Need an example
+ * Can also be a placeholder for a method when its implementation is
+ * deferred to the base class.
*/
{
- VALUE rb_cBEGIN = rb_define_class_under(rb_cNode, "BEGIN", rb_cNode);
+ VALUE rb_cZSUPER = rb_define_class_under(rb_cNode, "ZSUPER", rb_cNode);
members = rb_ary_new();
- rb_cNodeSubclass[NODE_BEGIN] = rb_cBEGIN;
- rb_iv_set(rb_cBEGIN, "__member__", members);
- rb_iv_set(rb_cBEGIN, "__type__", INT2NUM(NODE_BEGIN));
- rb_define_singleton_method(rb_cBEGIN, "members", node_s_members, 0);
- rb_define_method(rb_cBEGIN, "body", node_body, 0);
- rb_ary_push(members, rb_str_new2("body"));
+ rb_cNodeSubclass[NODE_ZSUPER] = rb_cZSUPER;
+ rb_iv_set(rb_cZSUPER, "__member__", members);
+ rb_iv_set(rb_cZSUPER, "__type__", INT2NUM(NODE_ZSUPER));
+ rb_define_singleton_method(rb_cZSUPER, "members", node_s_members, 0);
}
}