From: ptkwt@...1.aracnet.com (Phil Tomson) Date: 2002-10-24T04:41:21+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 > >Is this making more sense now? Yes and no. Since Ruby doesn't use a bytecode interpretting virtual machine (instead it walks an AST) what exactly do you mean by bytecode here (or are you defining a bytecode for Ruby). > >Of course, it'll make even more sense when I write something which converts >type back into a string rather than an enum, etc. :) I think what you're working on is very important and would be useful for a variety of projects (Like Cardinal for example). Please if possible can you start up a sourceforge or savannah project for this? After the Ruby conference I think I might have some time to help out with this. Phil