#include "immutable_node.h" static VALUE cNode; static void deallocate(ImmutableNodeContext* context) { if (context->pc) { js_FinishParseContext(context->js, context->pc); free(context->pc); } JS_DestroyContext(context->js); JS_DestroyRuntime(context->runtime); free(context); } static VALUE allocate(VALUE klass) { ImmutableNodeContext * context = calloc(1L, sizeof(ImmutableNodeContext)); VALUE self = Data_Wrap_Struct(klass, 0, deallocate, context); assert(context->runtime = JS_NewRuntime(0x100000)); assert(context->js = JS_NewContext(context->runtime, 8192L)); return self; } /* * call-seq: * parse_io(stream, filename=nil, line_number=0) * * Parses an IO object, returning a native spidermonkey parse tree. */ static VALUE parse_io(int argc, VALUE *argv, VALUE klass) { VALUE self = allocate(klass); VALUE stream, filename, linenum; ImmutableNodeContext* context; Data_Get_Struct(self, ImmutableNodeContext, context); assert(context->pc = calloc(1L, sizeof(JSParseContext))); rb_scan_args( argc, argv, "12", &stream, &filename, &linenum ); VALUE file_contents = rb_funcall(stream, rb_intern("read"), 0); size_t length = NUM2INT(rb_funcall(file_contents, rb_intern("length"), 0)); jschar* chars; assert(chars = js_InflateString(context->js, StringValuePtr(file_contents), &length)); if(!filename && rb_respond_to(stream, rb_intern("path"))) { filename = rb_funcall(stream, rb_intern("path"), 0); } char* filenamez = RTEST(filename) ? StringValueCStr(filename) : NULL; int linenumi = RTEST(linenum) ? NUM2INT(linenum) : 1; assert(js_InitParseContext(context->js, context->pc, NULL, chars, length, NULL, filenamez, (unsigned)linenumi)); JS_SetVersion(context->js, JSVERSION_LATEST); context->node = js_ParseScript(context->js, JS_NewObject(context->js, NULL, NULL, NULL), context->pc); if(JS_IsExceptionPending(context->js)) { jsval exception, message, file_name, line_number; JS_GetPendingException(context->js, &exception); JS_GetProperty(context->js, JSVAL_TO_OBJECT(exception), "message",&message); JS_GetProperty(context->js, JSVAL_TO_OBJECT(exception), "fileName",&file_name); JS_GetProperty(context->js, JSVAL_TO_OBJECT(exception), "lineNumber",&line_number); JS_ClearPendingException(context->js); rb_funcall( self, rb_intern("raise_parse_error"), 3, message == JSVAL_NULL ? Qnil : rb_str_new2(JS_GetStringBytes(JSVAL_TO_STRING(message))), rb_str_new2(JS_GetStringBytes(JSVAL_TO_STRING(file_name))), INT2NUM((long)JSVAL_TO_INT(line_number)) ); } return self; } /* * call-seq: * line * * Returns the line number of the node. */ static VALUE line(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); return INT2NUM((long)(ctx->node->pn_pos.begin.lineno)); } /* * call-seq: * index * * Returns the column number of the node. */ static VALUE begin_index(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); return INT2NUM((long)(ctx->node->pn_pos.begin.index)); } /* * call-seq: * pn_arity * * Returns the arity of the node as a symbol. */ static VALUE pn_arity(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); switch(ctx->node->pn_arity) { case PN_FUNC: return ID2SYM(rb_intern("pn_func")); case PN_LIST: return ID2SYM(rb_intern("pn_list")); case PN_TERNARY: return ID2SYM(rb_intern("pn_ternary")); case PN_BINARY: return ID2SYM(rb_intern("pn_binary")); case PN_UNARY: return ID2SYM(rb_intern("pn_unary")); case PN_NAME: return ID2SYM(rb_intern("pn_name")); case PN_NULLARY: return ID2SYM(rb_intern("pn_nullary")); } return Qnil; } /* * call-seq: * pn_type * * Returns the type of the node as a symbol. */ static VALUE pn_type(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); switch(ctx->node->pn_type) { case TOK_EOF: return ID2SYM(rb_intern("tok_eof")); case TOK_EOL: return ID2SYM(rb_intern("tok_eol")); case TOK_SEMI: return ID2SYM(rb_intern("tok_semi")); case TOK_COMMA: return ID2SYM(rb_intern("tok_comma")); case TOK_ASSIGN: return ID2SYM(rb_intern("tok_assign")); case TOK_HOOK: return ID2SYM(rb_intern("tok_hook")); case TOK_COLON: return ID2SYM(rb_intern("tok_colon")); case TOK_OR: return ID2SYM(rb_intern("tok_or")); case TOK_AND: return ID2SYM(rb_intern("tok_and")); case TOK_BITOR: return ID2SYM(rb_intern("tok_bitor")); case TOK_BITXOR: return ID2SYM(rb_intern("tok_bitxor")); case TOK_BITAND: return ID2SYM(rb_intern("tok_bitand")); case TOK_EQOP: return ID2SYM(rb_intern("tok_eqop")); case TOK_RELOP: return ID2SYM(rb_intern("tok_relop")); case TOK_SHOP: return ID2SYM(rb_intern("tok_shop")); case TOK_PLUS: return ID2SYM(rb_intern("tok_plus")); case TOK_MINUS: return ID2SYM(rb_intern("tok_minus")); case TOK_STAR: return ID2SYM(rb_intern("tok_star")); case TOK_DIVOP: return ID2SYM(rb_intern("tok_divop")); case TOK_UNARYOP: return ID2SYM(rb_intern("tok_unaryop")); case TOK_INC: return ID2SYM(rb_intern("tok_inc")); case TOK_DEC: return ID2SYM(rb_intern("tok_dec")); case TOK_DOT: return ID2SYM(rb_intern("tok_dot")); case TOK_LB: return ID2SYM(rb_intern("tok_lb")); case TOK_RB: return ID2SYM(rb_intern("tok_rb")); case TOK_LC: return ID2SYM(rb_intern("tok_lc")); case TOK_RC: return ID2SYM(rb_intern("tok_rc")); case TOK_LP: return ID2SYM(rb_intern("tok_lp")); case TOK_RP: return ID2SYM(rb_intern("tok_rp")); case TOK_NAME: return ID2SYM(rb_intern("tok_name")); case TOK_NUMBER: return ID2SYM(rb_intern("tok_number")); case TOK_STRING: return ID2SYM(rb_intern("tok_string")); case TOK_REGEXP: return ID2SYM(rb_intern("tok_regexp")); case TOK_PRIMARY: return ID2SYM(rb_intern("tok_primary")); case TOK_FUNCTION: return ID2SYM(rb_intern("tok_function")); case TOK_EXPORT: return ID2SYM(rb_intern("tok_export")); case TOK_IMPORT: return ID2SYM(rb_intern("tok_import")); case TOK_IF: return ID2SYM(rb_intern("tok_if")); case TOK_ELSE: return ID2SYM(rb_intern("tok_else")); case TOK_SWITCH: return ID2SYM(rb_intern("tok_switch")); case TOK_CASE: return ID2SYM(rb_intern("tok_case")); case TOK_DEFAULT: return ID2SYM(rb_intern("tok_default")); case TOK_WHILE: return ID2SYM(rb_intern("tok_while")); case TOK_DO: return ID2SYM(rb_intern("tok_do")); case TOK_FOR: return ID2SYM(rb_intern("tok_for")); case TOK_BREAK: return ID2SYM(rb_intern("tok_break")); case TOK_CONTINUE: return ID2SYM(rb_intern("tok_continue")); case TOK_IN: return ID2SYM(rb_intern("tok_in")); case TOK_VAR: return ID2SYM(rb_intern("tok_var")); case TOK_WITH: return ID2SYM(rb_intern("tok_with")); case TOK_RETURN: return ID2SYM(rb_intern("tok_return")); case TOK_NEW: return ID2SYM(rb_intern("tok_new")); case TOK_DELETE: return ID2SYM(rb_intern("tok_delete")); case TOK_DEFSHARP: return ID2SYM(rb_intern("tok_defsharp")); case TOK_USESHARP: return ID2SYM(rb_intern("tok_usesharp")); case TOK_TRY: return ID2SYM(rb_intern("tok_try")); case TOK_CATCH: return ID2SYM(rb_intern("tok_catch")); case TOK_FINALLY: return ID2SYM(rb_intern("tok_finally")); case TOK_THROW: return ID2SYM(rb_intern("tok_throw")); case TOK_INSTANCEOF: return ID2SYM(rb_intern("tok_instanceof")); case TOK_DEBUGGER: return ID2SYM(rb_intern("tok_debugger")); case TOK_XMLSTAGO: return ID2SYM(rb_intern("tok_xmlstago")); case TOK_XMLETAGO: return ID2SYM(rb_intern("tok_xmletago")); case TOK_XMLPTAGC: return ID2SYM(rb_intern("tok_xmlptagc")); case TOK_XMLTAGC: return ID2SYM(rb_intern("tok_xmltagc")); case TOK_XMLNAME: return ID2SYM(rb_intern("tok_xmlname")); case TOK_XMLATTR: return ID2SYM(rb_intern("tok_xmlattr")); case TOK_XMLSPACE: return ID2SYM(rb_intern("tok_xmlspace")); case TOK_XMLTEXT: return ID2SYM(rb_intern("tok_xmltext")); case TOK_XMLCOMMENT: return ID2SYM(rb_intern("tok_xmlcomment")); case TOK_XMLCDATA: return ID2SYM(rb_intern("tok_xmlcdata")); case TOK_XMLPI: return ID2SYM(rb_intern("tok_xmlpi")); case TOK_AT: return ID2SYM(rb_intern("tok_at")); case TOK_DBLCOLON: return ID2SYM(rb_intern("tok_dblcolon")); case TOK_ANYNAME: return ID2SYM(rb_intern("tok_anyname")); case TOK_DBLDOT: return ID2SYM(rb_intern("tok_dbldot")); case TOK_FILTER: return ID2SYM(rb_intern("tok_filter")); case TOK_XMLELEM: return ID2SYM(rb_intern("tok_xmlelem")); case TOK_XMLLIST: return ID2SYM(rb_intern("tok_xmllist")); case TOK_YIELD: return ID2SYM(rb_intern("tok_yield")); case TOK_ARRAYCOMP: return ID2SYM(rb_intern("tok_arraycomp")); case TOK_ARRAYPUSH: return ID2SYM(rb_intern("tok_arraypush")); case TOK_LEXICALSCOPE: return ID2SYM(rb_intern("tok_lexicalscope")); case TOK_LET: return ID2SYM(rb_intern("tok_let")); case TOK_BODY: return ID2SYM(rb_intern("tok_body")); case TOK_RESERVED: return ID2SYM(rb_intern("tok_reserved")); case TOK_LIMIT: return ID2SYM(rb_intern("tok_limit")); } return INT2NUM((long)(ctx->node->pn_type)); } /* * call-seq: * pn_expr * * Returns the parse node expression as an ImmutableNode. */ static VALUE data_pn_expr(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(ctx->node->pn_expr) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_expr; return node; } return Qnil; } /* * call-seq: * pn_kid * * Returns the child ImmutableNode. */ static VALUE data_pn_kid(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(ctx->node->pn_kid) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_kid; return node; } return Qnil; } /* * call-seq: * pn_kid1 * * Returns the first child ImmutableNode. */ static VALUE data_pn_kid1(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(ctx->node->pn_kid1) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_kid1; return node; } return Qnil; } /* * call-seq: * pn_kid2 * * Returns the second child ImmutableNode. */ static VALUE data_pn_kid2(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(ctx->node->pn_kid2) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_kid2; return node; } return Qnil; } /* * call-seq: * pn_kid3 * * Returns the third child ImmutableNode. */ static VALUE data_pn_kid3(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(ctx->node->pn_kid3) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_kid3; return node; } return Qnil; } /* * call-seq: * pn_dval * * Returns the numeric value of the node. */ static VALUE data_pn_dval(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(JSVAL_IS_NUMBER(ATOM_KEY(ctx->node->pn_atom))) { return rb_float_new(ctx->node->pn_dval); } else { return INT2NUM((long)(ctx->node->pn_dval)); } } /* * call-seq: * pn_op * * Returns the op code for the node as a symbol. */ static VALUE data_pn_op(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); return jsop_to_symbol(ctx->node->pn_op); } /* * call-seq: * pn_left * * Returns the left side ImmutableNode. */ static VALUE data_pn_left(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(ctx->node->pn_left) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_left; return node; } return Qnil; } /* * call-seq: * pn_extra * * Returns extra informaton about the node as an Integer. */ static VALUE data_pn_extra(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); return UINT2NUM((unsigned long)(ctx->node->pn_extra)); } /* * call-seq: * name * * Returns the name of the node. */ static VALUE name(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); return rb_str_new2(JS_GetStringBytes(ATOM_TO_STRING(ctx->node->pn_atom))); } /* * call-seq: * regexp * * Returns the regexp value as a String. */ static VALUE regexp(VALUE self) { ImmutableNodeContext * ctx; jsval result; Data_Get_Struct(self, ImmutableNodeContext, ctx); js_regexp_toString(ctx->js, ctx->node->pn_pob->object, &result); return rb_str_new2(JS_GetStringBytes(JSVAL_TO_STRING(result))); } /* * call-seq: * function_name * * Returns the function name as a String. */ static VALUE function_name(VALUE self) { ImmutableNodeContext * ctx; JSFunction * f; JSObject * object; Data_Get_Struct(self, ImmutableNodeContext, ctx); object = ctx->node->pn_funpob->object; f = (JSFunction *)JS_GetPrivate(ctx->js, ctx->node->pn_funpob->object); if(f->atom) { return rb_str_new2(JS_GetStringBytes(ATOM_TO_STRING(f->atom))); } else { return Qnil; } } /* * call-seq: * function_args * * Returns the function argument names as an Array of String. */ static VALUE function_args(VALUE self) { ImmutableNodeContext * ctx; JSFunction * f; JSObject * object; jsuword* names; VALUE func_args; int i; Data_Get_Struct(self, ImmutableNodeContext, ctx); object = ctx->node->pn_funpob->object; f = (JSFunction *)JS_GetPrivate(ctx->js, ctx->node->pn_funpob->object); func_args = rb_ary_new2((long)f->nargs); if(f->nargs > 0) { names = js_GetLocalNameArray(ctx->js, f, &ctx->js->tempPool); for(i = 0; i < f->nargs; i++) { rb_ary_push(func_args, rb_str_new2(JS_GetStringBytes(ATOM_TO_STRING(names[i]))) ); } } return func_args; } /* * call-seq: * function_body * * Returns the function body as an ImmutableNode. */ static VALUE function_body(VALUE self) { ImmutableNodeContext * ctx; JSFunction * f; JSObject * object; Data_Get_Struct(self, ImmutableNodeContext, ctx); object = ctx->node->pn_funpob->object; f = (JSFunction *)JS_GetPrivate(ctx->js, ctx->node->pn_funpob->object); if(ctx->node->pn_body) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_body; return node; } return Qnil; } /* * call-seq: * pn_right * * Returns right side as an ImmutableNode. */ static VALUE data_pn_right(VALUE self) { ImmutableNodeContext * ctx; Data_Get_Struct(self, ImmutableNodeContext, ctx); if(ctx->node->pn_right) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = ctx->node->pn_right; return node; } return Qnil; } /* * call-seq: * children * * Returns children as an Array of ImmutableNode. */ static VALUE children(VALUE self) { ImmutableNodeContext * ctx; JSParseNode * p; VALUE children; Data_Get_Struct(self, ImmutableNodeContext, ctx); children = rb_ary_new(); for(p = ctx->node->pn_head; p != NULL; p = p->pn_next) { ImmutableNodeContext *roc; VALUE node = Data_Make_Struct(cNode, ImmutableNodeContext, NULL, NULL, roc); roc->js = ctx->js; roc->node = p; rb_ary_push(children, node); } return children; } VALUE jsop_to_symbol(JSUint32 jsop) { switch(jsop) { case JSOP_NOP: return ID2SYM(rb_intern("jsop_nop")); case JSOP_PUSH: return ID2SYM(rb_intern("jsop_push")); case JSOP_POPV: return ID2SYM(rb_intern("jsop_popv")); case JSOP_ENTERWITH: return ID2SYM(rb_intern("jsop_enterwith")); case JSOP_LEAVEWITH: return ID2SYM(rb_intern("jsop_leavewith")); case JSOP_RETURN: return ID2SYM(rb_intern("jsop_return")); case JSOP_GOTO: return ID2SYM(rb_intern("jsop_goto")); case JSOP_IFEQ: return ID2SYM(rb_intern("jsop_ifeq")); case JSOP_IFNE: return ID2SYM(rb_intern("jsop_ifne")); case JSOP_ARGUMENTS: return ID2SYM(rb_intern("jsop_arguments")); case JSOP_FORARG: return ID2SYM(rb_intern("jsop_forarg")); case JSOP_FORVAR: return ID2SYM(rb_intern("jsop_forvar")); case JSOP_DUP: return ID2SYM(rb_intern("jsop_dup")); case JSOP_DUP2: return ID2SYM(rb_intern("jsop_dup2")); case JSOP_SETCONST: return ID2SYM(rb_intern("jsop_setconst")); case JSOP_BITOR: return ID2SYM(rb_intern("jsop_bitor")); case JSOP_BITXOR: return ID2SYM(rb_intern("jsop_bitxor")); case JSOP_BITAND: return ID2SYM(rb_intern("jsop_bitand")); case JSOP_EQ: return ID2SYM(rb_intern("jsop_eq")); case JSOP_NE: return ID2SYM(rb_intern("jsop_ne")); case JSOP_LT: return ID2SYM(rb_intern("jsop_lt")); case JSOP_LE: return ID2SYM(rb_intern("jsop_le")); case JSOP_GT: return ID2SYM(rb_intern("jsop_gt")); case JSOP_GE: return ID2SYM(rb_intern("jsop_ge")); case JSOP_LSH: return ID2SYM(rb_intern("jsop_lsh")); case JSOP_RSH: return ID2SYM(rb_intern("jsop_rsh")); case JSOP_URSH: return ID2SYM(rb_intern("jsop_ursh")); case JSOP_ADD: return ID2SYM(rb_intern("jsop_add")); case JSOP_SUB: return ID2SYM(rb_intern("jsop_sub")); case JSOP_MUL: return ID2SYM(rb_intern("jsop_mul")); case JSOP_DIV: return ID2SYM(rb_intern("jsop_div")); case JSOP_MOD: return ID2SYM(rb_intern("jsop_mod")); case JSOP_NOT: return ID2SYM(rb_intern("jsop_not")); case JSOP_BITNOT: return ID2SYM(rb_intern("jsop_bitnot")); case JSOP_NEG: return ID2SYM(rb_intern("jsop_neg")); case JSOP_NEW: return ID2SYM(rb_intern("jsop_new")); case JSOP_DELNAME: return ID2SYM(rb_intern("jsop_delname")); case JSOP_DELPROP: return ID2SYM(rb_intern("jsop_delprop")); case JSOP_DELELEM: return ID2SYM(rb_intern("jsop_delelem")); case JSOP_TYPEOF: return ID2SYM(rb_intern("jsop_typeof")); case JSOP_VOID: return ID2SYM(rb_intern("jsop_void")); case JSOP_INCNAME: return ID2SYM(rb_intern("jsop_incname")); case JSOP_INCPROP: return ID2SYM(rb_intern("jsop_incprop")); case JSOP_INCELEM: return ID2SYM(rb_intern("jsop_incelem")); case JSOP_DECNAME: return ID2SYM(rb_intern("jsop_decname")); case JSOP_DECPROP: return ID2SYM(rb_intern("jsop_decprop")); case JSOP_DECELEM: return ID2SYM(rb_intern("jsop_decelem")); case JSOP_NAMEINC: return ID2SYM(rb_intern("jsop_nameinc")); case JSOP_PROPINC: return ID2SYM(rb_intern("jsop_propinc")); case JSOP_ELEMINC: return ID2SYM(rb_intern("jsop_eleminc")); case JSOP_NAMEDEC: return ID2SYM(rb_intern("jsop_namedec")); case JSOP_PROPDEC: return ID2SYM(rb_intern("jsop_propdec")); case JSOP_ELEMDEC: return ID2SYM(rb_intern("jsop_elemdec")); case JSOP_GETPROP: return ID2SYM(rb_intern("jsop_getprop")); case JSOP_SETPROP: return ID2SYM(rb_intern("jsop_setprop")); case JSOP_GETELEM: return ID2SYM(rb_intern("jsop_getelem")); case JSOP_SETELEM: return ID2SYM(rb_intern("jsop_setelem")); case JSOP_CALLNAME: return ID2SYM(rb_intern("jsop_callname")); case JSOP_CALL: return ID2SYM(rb_intern("jsop_call")); case JSOP_NAME: return ID2SYM(rb_intern("jsop_name")); case JSOP_DOUBLE: return ID2SYM(rb_intern("jsop_double")); case JSOP_STRING: return ID2SYM(rb_intern("jsop_string")); case JSOP_ZERO: return ID2SYM(rb_intern("jsop_zero")); case JSOP_ONE: return ID2SYM(rb_intern("jsop_one")); case JSOP_NULL: return ID2SYM(rb_intern("jsop_null")); case JSOP_THIS: return ID2SYM(rb_intern("jsop_this")); case JSOP_FALSE: return ID2SYM(rb_intern("jsop_false")); case JSOP_TRUE: return ID2SYM(rb_intern("jsop_true")); case JSOP_OR: return ID2SYM(rb_intern("jsop_or")); case JSOP_AND: return ID2SYM(rb_intern("jsop_and")); case JSOP_TABLESWITCH: return ID2SYM(rb_intern("jsop_tableswitch")); case JSOP_LOOKUPSWITCH: return ID2SYM(rb_intern("jsop_lookupswitch")); case JSOP_STRICTEQ: return ID2SYM(rb_intern("jsop_stricteq")); case JSOP_STRICTNE: return ID2SYM(rb_intern("jsop_strictne")); case JSOP_CLOSURE: return ID2SYM(rb_intern("jsop_closure")); case JSOP_EXPORTALL: return ID2SYM(rb_intern("jsop_exportall")); case JSOP_EXPORTNAME: return ID2SYM(rb_intern("jsop_exportname")); case JSOP_IMPORTALL: return ID2SYM(rb_intern("jsop_importall")); case JSOP_IMPORTPROP: return ID2SYM(rb_intern("jsop_importprop")); case JSOP_IMPORTELEM: return ID2SYM(rb_intern("jsop_importelem")); case JSOP_OBJECT: return ID2SYM(rb_intern("jsop_object")); case JSOP_POP: return ID2SYM(rb_intern("jsop_pop")); case JSOP_POS: return ID2SYM(rb_intern("jsop_pos")); case JSOP_TRAP: return ID2SYM(rb_intern("jsop_trap")); case JSOP_GETARG: return ID2SYM(rb_intern("jsop_getarg")); case JSOP_SETARG: return ID2SYM(rb_intern("jsop_setarg")); case JSOP_GETVAR: return ID2SYM(rb_intern("jsop_getvar")); case JSOP_SETVAR: return ID2SYM(rb_intern("jsop_setvar")); case JSOP_UINT16: return ID2SYM(rb_intern("jsop_uint16")); case JSOP_NEWINIT: return ID2SYM(rb_intern("jsop_newinit")); case JSOP_ENDINIT: return ID2SYM(rb_intern("jsop_endinit")); case JSOP_INITPROP: return ID2SYM(rb_intern("jsop_initprop")); case JSOP_INITELEM: return ID2SYM(rb_intern("jsop_initelem")); case JSOP_DEFSHARP: return ID2SYM(rb_intern("jsop_defsharp")); case JSOP_USESHARP: return ID2SYM(rb_intern("jsop_usesharp")); case JSOP_INCARG: return ID2SYM(rb_intern("jsop_incarg")); case JSOP_INCVAR: return ID2SYM(rb_intern("jsop_incvar")); case JSOP_DECARG: return ID2SYM(rb_intern("jsop_decarg")); case JSOP_DECVAR: return ID2SYM(rb_intern("jsop_decvar")); case JSOP_ARGINC: return ID2SYM(rb_intern("jsop_arginc")); case JSOP_VARINC: return ID2SYM(rb_intern("jsop_varinc")); case JSOP_ARGDEC: return ID2SYM(rb_intern("jsop_argdec")); case JSOP_VARDEC: return ID2SYM(rb_intern("jsop_vardec")); case JSOP_FORIN: return ID2SYM(rb_intern("jsop_forin")); case JSOP_FORNAME: return ID2SYM(rb_intern("jsop_forname")); case JSOP_FORPROP: return ID2SYM(rb_intern("jsop_forprop")); case JSOP_FORELEM: return ID2SYM(rb_intern("jsop_forelem")); case JSOP_POPN: return ID2SYM(rb_intern("jsop_popn")); case JSOP_BINDNAME: return ID2SYM(rb_intern("jsop_bindname")); case JSOP_SETNAME: return ID2SYM(rb_intern("jsop_setname")); case JSOP_THROW: return ID2SYM(rb_intern("jsop_throw")); case JSOP_IN: return ID2SYM(rb_intern("jsop_in")); case JSOP_INSTANCEOF: return ID2SYM(rb_intern("jsop_instanceof")); case JSOP_DEBUGGER: return ID2SYM(rb_intern("jsop_debugger")); case JSOP_GOSUB: return ID2SYM(rb_intern("jsop_gosub")); case JSOP_RETSUB: return ID2SYM(rb_intern("jsop_retsub")); case JSOP_EXCEPTION: return ID2SYM(rb_intern("jsop_exception")); case JSOP_LINENO: return ID2SYM(rb_intern("jsop_lineno")); case JSOP_CONDSWITCH: return ID2SYM(rb_intern("jsop_condswitch")); case JSOP_CASE: return ID2SYM(rb_intern("jsop_case")); case JSOP_DEFAULT: return ID2SYM(rb_intern("jsop_default")); case JSOP_EVAL: return ID2SYM(rb_intern("jsop_eval")); case JSOP_ENUMELEM: return ID2SYM(rb_intern("jsop_enumelem")); case JSOP_GETTER: return ID2SYM(rb_intern("jsop_getter")); case JSOP_SETTER: return ID2SYM(rb_intern("jsop_setter")); case JSOP_DEFFUN: return ID2SYM(rb_intern("jsop_deffun")); case JSOP_DEFCONST: return ID2SYM(rb_intern("jsop_defconst")); case JSOP_DEFVAR: return ID2SYM(rb_intern("jsop_defvar")); case JSOP_ANONFUNOBJ: return ID2SYM(rb_intern("jsop_anonfunobj")); case JSOP_NAMEDFUNOBJ: return ID2SYM(rb_intern("jsop_namedfunobj")); case JSOP_SETLOCALPOP: return ID2SYM(rb_intern("jsop_setlocalpop")); case JSOP_GROUP: return ID2SYM(rb_intern("jsop_group")); case JSOP_SETCALL: return ID2SYM(rb_intern("jsop_setcall")); case JSOP_TRY: return ID2SYM(rb_intern("jsop_try")); case JSOP_FINALLY: return ID2SYM(rb_intern("jsop_finally")); case JSOP_SWAP: return ID2SYM(rb_intern("jsop_swap")); case JSOP_ARGSUB: return ID2SYM(rb_intern("jsop_argsub")); case JSOP_ARGCNT: return ID2SYM(rb_intern("jsop_argcnt")); case JSOP_DEFLOCALFUN: return ID2SYM(rb_intern("jsop_deflocalfun")); case JSOP_GOTOX: return ID2SYM(rb_intern("jsop_gotox")); case JSOP_IFEQX: return ID2SYM(rb_intern("jsop_ifeqx")); case JSOP_IFNEX: return ID2SYM(rb_intern("jsop_ifnex")); case JSOP_ORX: return ID2SYM(rb_intern("jsop_orx")); case JSOP_ANDX: return ID2SYM(rb_intern("jsop_andx")); case JSOP_GOSUBX: return ID2SYM(rb_intern("jsop_gosubx")); case JSOP_CASEX: return ID2SYM(rb_intern("jsop_casex")); case JSOP_DEFAULTX: return ID2SYM(rb_intern("jsop_defaultx")); case JSOP_TABLESWITCHX: return ID2SYM(rb_intern("jsop_tableswitchx")); case JSOP_LOOKUPSWITCHX: return ID2SYM(rb_intern("jsop_lookupswitchx")); case JSOP_BACKPATCH: return ID2SYM(rb_intern("jsop_backpatch")); case JSOP_BACKPATCH_POP: return ID2SYM(rb_intern("jsop_backpatch_pop")); case JSOP_THROWING: return ID2SYM(rb_intern("jsop_throwing")); case JSOP_SETRVAL: return ID2SYM(rb_intern("jsop_setrval")); case JSOP_RETRVAL: return ID2SYM(rb_intern("jsop_retrval")); case JSOP_GETGVAR: return ID2SYM(rb_intern("jsop_getgvar")); case JSOP_SETGVAR: return ID2SYM(rb_intern("jsop_setgvar")); case JSOP_INCGVAR: return ID2SYM(rb_intern("jsop_incgvar")); case JSOP_DECGVAR: return ID2SYM(rb_intern("jsop_decgvar")); case JSOP_GVARINC: return ID2SYM(rb_intern("jsop_gvarinc")); case JSOP_GVARDEC: return ID2SYM(rb_intern("jsop_gvardec")); case JSOP_REGEXP: return ID2SYM(rb_intern("jsop_regexp")); case JSOP_DEFXMLNS: return ID2SYM(rb_intern("jsop_defxmlns")); case JSOP_ANYNAME: return ID2SYM(rb_intern("jsop_anyname")); case JSOP_QNAMEPART: return ID2SYM(rb_intern("jsop_qnamepart")); case JSOP_QNAMECONST: return ID2SYM(rb_intern("jsop_qnameconst")); case JSOP_QNAME: return ID2SYM(rb_intern("jsop_qname")); case JSOP_TOATTRNAME: return ID2SYM(rb_intern("jsop_toattrname")); case JSOP_TOATTRVAL: return ID2SYM(rb_intern("jsop_toattrval")); case JSOP_ADDATTRNAME: return ID2SYM(rb_intern("jsop_addattrname")); case JSOP_ADDATTRVAL: return ID2SYM(rb_intern("jsop_addattrval")); case JSOP_BINDXMLNAME: return ID2SYM(rb_intern("jsop_bindxmlname")); case JSOP_SETXMLNAME: return ID2SYM(rb_intern("jsop_setxmlname")); case JSOP_XMLNAME: return ID2SYM(rb_intern("jsop_xmlname")); case JSOP_DESCENDANTS: return ID2SYM(rb_intern("jsop_descendants")); case JSOP_FILTER: return ID2SYM(rb_intern("jsop_filter")); case JSOP_ENDFILTER: return ID2SYM(rb_intern("jsop_endfilter")); case JSOP_TOXML: return ID2SYM(rb_intern("jsop_toxml")); case JSOP_TOXMLLIST: return ID2SYM(rb_intern("jsop_toxmllist")); case JSOP_XMLTAGEXPR: return ID2SYM(rb_intern("jsop_xmltagexpr")); case JSOP_XMLELTEXPR: return ID2SYM(rb_intern("jsop_xmleltexpr")); case JSOP_XMLOBJECT: return ID2SYM(rb_intern("jsop_xmlobject")); case JSOP_XMLCDATA: return ID2SYM(rb_intern("jsop_xmlcdata")); case JSOP_XMLCOMMENT: return ID2SYM(rb_intern("jsop_xmlcomment")); case JSOP_XMLPI: return ID2SYM(rb_intern("jsop_xmlpi")); case JSOP_CALLPROP: return ID2SYM(rb_intern("jsop_callprop")); case JSOP_GETFUNNS: return ID2SYM(rb_intern("jsop_getfunns")); case JSOP_FOREACH: return ID2SYM(rb_intern("jsop_foreach")); case JSOP_DELDESC: return ID2SYM(rb_intern("jsop_deldesc")); case JSOP_UINT24: return ID2SYM(rb_intern("jsop_uint24")); case JSOP_INDEXBASE: return ID2SYM(rb_intern("jsop_indexbase")); case JSOP_RESETBASE: return ID2SYM(rb_intern("jsop_resetbase")); case JSOP_RESETBASE0: return ID2SYM(rb_intern("jsop_resetbase0")); case JSOP_STARTXML: return ID2SYM(rb_intern("jsop_startxml")); case JSOP_STARTXMLEXPR: return ID2SYM(rb_intern("jsop_startxmlexpr")); case JSOP_CALLELEM: return ID2SYM(rb_intern("jsop_callelem")); case JSOP_STOP: return ID2SYM(rb_intern("jsop_stop")); case JSOP_GETXPROP: return ID2SYM(rb_intern("jsop_getxprop")); case JSOP_CALLXMLNAME: return ID2SYM(rb_intern("jsop_callxmlname")); case JSOP_TYPEOFEXPR: return ID2SYM(rb_intern("jsop_typeofexpr")); case JSOP_ENTERBLOCK: return ID2SYM(rb_intern("jsop_enterblock")); case JSOP_LEAVEBLOCK: return ID2SYM(rb_intern("jsop_leaveblock")); case JSOP_GETLOCAL: return ID2SYM(rb_intern("jsop_getlocal")); case JSOP_SETLOCAL: return ID2SYM(rb_intern("jsop_setlocal")); case JSOP_INCLOCAL: return ID2SYM(rb_intern("jsop_inclocal")); case JSOP_DECLOCAL: return ID2SYM(rb_intern("jsop_declocal")); case JSOP_LOCALINC: return ID2SYM(rb_intern("jsop_localinc")); case JSOP_LOCALDEC: return ID2SYM(rb_intern("jsop_localdec")); case JSOP_FORLOCAL: return ID2SYM(rb_intern("jsop_forlocal")); case JSOP_FORCONST: return ID2SYM(rb_intern("jsop_forconst")); case JSOP_ENDITER: return ID2SYM(rb_intern("jsop_enditer")); case JSOP_GENERATOR: return ID2SYM(rb_intern("jsop_generator")); case JSOP_YIELD: return ID2SYM(rb_intern("jsop_yield")); case JSOP_ARRAYPUSH: return ID2SYM(rb_intern("jsop_arraypush")); case JSOP_FOREACHKEYVAL: return ID2SYM(rb_intern("jsop_foreachkeyval")); case JSOP_ENUMCONSTELEM: return ID2SYM(rb_intern("jsop_enumconstelem")); case JSOP_LEAVEBLOCKEXPR: return ID2SYM(rb_intern("jsop_leaveblockexpr")); case JSOP_GETTHISPROP: return ID2SYM(rb_intern("jsop_getthisprop")); case JSOP_GETARGPROP: return ID2SYM(rb_intern("jsop_getargprop")); case JSOP_GETVARPROP: return ID2SYM(rb_intern("jsop_getvarprop")); case JSOP_GETLOCALPROP: return ID2SYM(rb_intern("jsop_getlocalprop")); case JSOP_INDEXBASE1: return ID2SYM(rb_intern("jsop_indexbase1")); case JSOP_INDEXBASE2: return ID2SYM(rb_intern("jsop_indexbase2")); case JSOP_INDEXBASE3: return ID2SYM(rb_intern("jsop_indexbase3")); case JSOP_CALLGVAR: return ID2SYM(rb_intern("jsop_callgvar")); case JSOP_CALLVAR: return ID2SYM(rb_intern("jsop_callvar")); case JSOP_CALLARG: return ID2SYM(rb_intern("jsop_callarg")); case JSOP_CALLLOCAL: return ID2SYM(rb_intern("jsop_calllocal")); case JSOP_INT8: return ID2SYM(rb_intern("jsop_int8")); case JSOP_INT32: return ID2SYM(rb_intern("jsop_int32")); case JSOP_LENGTH: return ID2SYM(rb_intern("jsop_length")); } return UINT2NUM((unsigned long)(jsop)); } void init_Johnson_SpiderMonkey_Immutable_Node(VALUE spidermonkey) { /* HACK: These comments are *only* to make RDoc happy. VALUE johnson = rb_define_module("Johnson"); VALUE spidermonkey = rb_define_module_under(johnson, "SpiderMonkey"); */ /* ImmutableNode class. */ cNode = rb_define_class_under(spidermonkey, "ImmutableNode", rb_cObject); rb_define_alloc_func(cNode, allocate); rb_define_singleton_method(cNode, "parse_io", parse_io, -1); rb_define_method(cNode, "line", line, 0); rb_define_method(cNode, "index", begin_index, 0); rb_define_method(cNode, "pn_arity", pn_arity, 0); rb_define_method(cNode, "pn_type", pn_type, 0); rb_define_method(cNode, "pn_expr", data_pn_expr, 0); rb_define_method(cNode, "pn_kid", data_pn_kid, 0); rb_define_method(cNode, "pn_kid1", data_pn_kid1, 0); rb_define_method(cNode, "pn_kid2", data_pn_kid2, 0); rb_define_method(cNode, "pn_kid3", data_pn_kid3, 0); rb_define_method(cNode, "pn_dval", data_pn_dval, 0); rb_define_method(cNode, "pn_op", data_pn_op, 0); rb_define_method(cNode, "pn_left", data_pn_left, 0); rb_define_method(cNode, "pn_extra", data_pn_extra, 0); rb_define_method(cNode, "name", name, 0); rb_define_method(cNode, "regexp", regexp, 0); rb_define_method(cNode, "function_name", function_name, 0); rb_define_method(cNode, "function_args", function_args, 0); rb_define_method(cNode, "function_body", function_body, 0); rb_define_method(cNode, "pn_right", data_pn_right, 0); rb_define_method(cNode, "children", children, 0); }