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'
#<ByteNode:0x401a6550>
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>