Folks,

 This is from the BeanShell Users Guide. Has anyone wrote there own BeanShell interpreter that parses a script and creates AST's? By doing so i suspect we could get the ability to single step thru a script. This would be awesome for debugging purposes.....

 Any knowledge out there on this??


thx,

mp
=====================================================================================

It is useful to have a high level understanding how BeanShell works with scripts to understand performance issues.

The first time a script is read or sourced into an interpreter, BeanShell uses the parser to parse the script internally to an AST. The AST consists of Java object representations of all of the language structures and objects. The AST consists of Java classes, but is not the same as compiled Java code. When the script is "executed" BeanShell steps through each element of the AST and tells it to perform whatever it does (e.g. a variable assignment, for-loop, etc.). This execution of the ASTs is generally much faster than the original parsing of the text of the method. It is really only limited by the speed of the application calls that it is making, the speed of the Java reflection API, and the efficiency of the implementation of the structures in BeanShell.

When parsing "line by line" through a BeanShell script the ASTs are routinely executed and then thrown away. However the case of a BeanShell method declaration is different. A BeanShell method is parsed only once: when it is declared in the script. It is then stored in the namespace like any variable. Successive invocations of the method execute the ASTs again, but do not re-parse the original text.

This means that successive calls to the same scripted method are as fast as possible - much faster than re-parsing the script each time. You can use this to your advantage when running the same script many times simply by wrapping your code in the form of a BeanShell scripted method and executing the method repeatedly, rather than sourcing the script repeatedly. For example:

// From Java
import bsh.Interpreter;
i=new Interpreter();

// Declare method or source from file
i.eval("foo( args ) { ... }");

i.eval("foo(args)"); // repeatedly invoke the method
i.eval("foo(args)");
...

In the above example we defined a method called foo() which holds our script. Then we executed the method repeatedly. The foo() method was parsed only once: when its declaration was evaluated. Subsequent invocations simply execute the AST.

If you are willing to learn about the BeanShell abstract syntax tree classes you can use the Parser to parse a BeanShell script into its ASTs like this:

in=new FileReader("somefile.bsh");
Parser parser = new Parser(in);
while( !(eof=parser.Line()) ) {
   SimpleNode node = parser.popNode();
   // Use the node, etc. (See the bsh.BSH* classes)
   ...
}

To learn more about the abstract syntax tree please download the source distribution and consult the source documentation.