Welcome at » Quick start for bmScript

Quick start for bmScript

I was writing an email for Richard Hull, explaining some of the basics of bmScript and how to use it, but after writing it, I thought that it was worth posting it instead of just sending the email.

So there it goes.


The ant build file for openbasemovil-script creates various jar files for the engine, one of them contains just the runtime to execute compiled scripts, another one contains also the script compiler, and the other two are JavaSE tools to compile and run script files in a standard JavaSE environment. These tools can also be a good example of how to perform the same from a mobile device using JavaME.
Though bmScript is a scripting language, it is really compiled to a binary form for a couple of reasons. First to be able to compile the scripts on application build or a remote server and reduce application size by using the runtime-only jar, but most important to improve execution speed by spending time on interpretation just once.

Class loading

The engine provides the ScriptingClassLoader class, which searches for .bmc (compiled scripts) resources in the classpath under the folder “vm”. It also provides access to system defined classes and system or custom NativeClasses.
You can subclass the ScriptingClassLoader in order to provide other ways of finding classes. The compiler and runtime for JavaSE do it to find classes in standard folders, but you can extend it to download them from a remote server, for example.

Integration with non-scripting classes (Java classes)

The NativeClass provides an easy way to create proxy Java classes that can be injected in a ScriptingClassLoader to be able to access any other Java class from a script.
It could have been done a lot easier with reflection, but that is not available with JavaME, so we have to do it in another way.
The NativeClass provides all the “infrastructure” to define methods and properties and to find and check that they are properly invoked, so you can create proxy classes for Java classes easier by subclassing NativeClass.
A good example are the classes found in the bm.vm.sys package under the main src folder of openbasemovil-script: The Map class lets you create Hashtable objects from the script, though you call them “map” in the script.
The Map class declares the methods present in the class in a static block, and then just provides the implementation of the invoke method that is a switch to handle the different methods declared.
Let’s suppose that I have a NativeClass called List that will let me access java.util.Vector, and I want my scripts to access it as “list” (check the Map class, that is performed in the constructor).
Now I obviously want to run a script that will access this class, to do that all I have to do is add it to the class loader of a virtual machine (we’ll get later to the full process of creating and invoking a vm):

        new sample.List( vm )

Compiling a script

The bmsc class in the tools folder of openbasemovil-script is a JavaSE command line tool to compile .bms (script files) to .bmc (compiled scripts), very much in the way you do with javac.
The source code shows how to create a custom class loader, how to create a virtual machine and how to invoke the script compiler from Java code.
It is JavaSE 1.5+, but it can be used in a very similar way from JavaME.

Running a script

The bms class in the tools folder is a command line runtime, this time like the java command line tool from the jre. It shows how to create a custom class loader, how to create a virtual machine and how to invoke a script.

Using the example of the List NativeClass above, we could do something like this:
My scripting class (

class foo
    method int main()
        var list myList;
        set myList = new list();
        mylist.add( "hello world with list!" );
        system.println( mylist.get( 0 ) );

The java code to invoke the script (once compiled into foo.bmc):

    final VirtualMachine vm = new VirtualMachine();
        new sample.List( vm )
    ); "foo" );

The run method is a shortcut to the one used in bms that uses no arguments, it will load the scripting class foo, search for a main method and invoke it with no arguments.

If you want to retrieve a return value from a script, the run method or the invoke method in the virtual machine will always return an Instance object.
The Instance object represents (obviously) an instance of an ScriptingClass object.
For native types (boolean, int, etc) they always have a property called “value” that you can retrieve with the get method.

For other types, the real java object might be in an attachment. The Map class does this, it uses an attachment called “map” to hold the real Hashtable object used.

In further articles we will try to get deeper in the possibilities of the language. It obviously can be used from JavaSE, it allows you to compile or just run scripts that are loaded dynamically, and through the NativeClass system it allows you to extend the runtime to access any Java class you want.

Please, feel free to comment your thoughts, and remember that bmScript is still v0.1, it works, but it has still to be thoroughly tested and performance tunned.

BlogLines Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

2 Responses

  1. richardh

    Thanks, this is a very useful start. I now have a compile and invoke cycle running on JavaSE. Next stop J2ME!

    By the way, the downloadable zip file for OpenBaseMovil-bmscript does not contain the tools folder, but and can be downloaded directly from SourceForge.

  2. [...] start guide to bmScript, the mobile scripting language, that shows how to walk your first steps with Source Scripting Languages in JavaBeanShell is a small, free, embeddable, java source [...]

Leave a Reply

You must be logged in to post a comment.