From: ptkwt@...1.aracnet.com (Phil Tomson) Date: 2002-10-29T07:10:20+09:00 Subject: Re: NODE tree introspection In article <86bs5luk1m.fsf@squash.oucs.ox.ac.uk>, Simon Cozens wrote: >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 > I wonder if we could do this a lot faster by using swig to wrap the Ruby C parser? Swig Ruby itself to make an extension for Ruby. ....just a thought. Phil