From: Simon Cozens Date: 2002-10-24T03:01:10+09:00 Subject: Re: NODE tree introspection ptkwt@shell1.aracnet.com (Phil Tomson) writes: > Hmmmm.... interesting idea. So basically what you're proposing would be > able to walk the AST of the currently running program (or any arbitrary > snippet that you send off to eval?)? Yes. That's what Perl's B.pm does. % perl -MB -le '$x= B::main_start; print $x->name while $x=$x->next' nextstate pushmark gv entersub gvsv sassign .... (New statement, add a mark to the stack, add a symbol table entry [B::main_start] to the stack, call it, put a variable on the stack, assign the result of the call to the variable...) > I don't think anyone has approached the problem in the way you propose. > Can you give some more details of how you're thinking of doing it? I can even give you some sample code, because I've already got a fair bit of it working. :) It says a lot for Ruby's ease of use, clarity of code and well-developed extensions system that I've only been *using* the bloody language for three days and I've already got most of a bytecode walker constructed. Here's the core of it: static VALUE bytecode_get_root(VALUE class) { return Data_Wrap_Struct(class, 0, 0, ruby_eval_tree); } void Init_Bytecode () { cByteNode = rb_define_class("ByteNode", rb_cObject); rb_define_singleton_method(cByteNode, "root", bytecode_get_root, 0); rb_define_method(cByteNode, "type", bytecode_nd_type, 0); rb_define_method(cByteNode, "line", bytecode_nd_line, 0); rb_define_method(cByteNode, "head", bytecode_nd_head, 0); rb_define_method(cByteNode, "next", bytecode_nd_next, 0); ... } The bytecode_nd_* functions just do a Data_Get_Struct, call the relevant nd_* macro, and wrap the result. Now I can say: % ruby -e 'require "Bytecode"; p ByteNode.root; p ByteNode.root.next.type' # 4 Is this making more sense now? Of course, it'll make even more sense when I write something which converts type back into a string rather than an enum, etc. :) -- Darn it, who spiked my coffee with water?! -- Larry Wall in <200002141819.KAA18235@kiev.wall.org>