Jim Driscoll's Blog

Notes on Technology and the Web

Archive for October 2012

Turtle Graphics DSL Implementation, part 1

leave a comment »

Last post, I described a Turtle Graphics DSL, as implemented in my sample program Napili.  (Please download it if you want to see the full code I’m discussing here).  This time, I’ll discuss how to implement it.  It’s surprisingly easy – though long enough that I’m going to tackle it in chunks, this is just Part 1.

First, to run the program, there’s the following snip of code inside a Java class (which is triggered when the user clicks the Run button):

Class clazz = Class.forName("org.netdance.napili.language.BasicRunner"); 
InvokerHelper.getMetaClass(clazz).invokeStaticMethod(clazz, "run", new Object[]{});

All this does is use Groovy’s dynamic invoker structures to invoke BasicRunner.run() – this code is only there so I can swap out the Groovy DSL classes at a later time, when I’ll discuss things like security.  I could have done the same thing with Java’s reflection classes, but if you already have Groovy in your class path, I heartily advise using InvokerHelper, there’s lots of handy stuff in there, and it’s considerably easier than using Java’s native reflection library.  One thing to be aware of, though, if you do:  it’s in the package org.codehaus.groovy.runtime, which means that the Groovy team reserves the right to change the APIs whenever they need to – which could make an upgrade of your Groovy version painful (though it’s not likely that InvokerHelper.getMetaClass(Class) is going to change anytime soon).

There are three classes that make up the language portion of the code.  The first, and by far easiest, is the BaseScript (you’ll remember, I hope, that I already discussed BaseScripts).  Written in Groovy, it becomes fairly trivial:

package org.netdance.napili.language
abstract class TurtleDelegateBaseScript extends Script {
    def methodMissing(String name, args) {
        turtle."$name"(*args)
    }
}

This uses a different method of Method Dispatch than I’ve previously discussed – he methodMissing method is called by Groovy whenever there’s no method found which matches a given name.  Since we don’t provide any methods at all, that means that pretty much every method called is going to go through this method.  (Since Scripts define other methods which will be inherited, like run and getBinding, and those won’t go through methodMissing, but that’s a problem for another day).  

The meat of the program is just a single line, in bold above.  I’ve already described what that kind of call does when I discussed Method Dispatch, but it’s worth going through one more time.  The first word, turtle, is interpreted as a Binding variable.   So the Groovy script goes into the Binding class (which I’ll describe shortly), and fetches the value corresponding to turtle.   Next, the “$name” is substituted with the method name called, which will then call the method name on the Turtle object.  Lastly, * is called the spread operator, and serves to break up the list of arguments into individual objects.   At runtime, a command like forward 100 will thus be transformed into something like: getBinding().getVariable("turtle").forward(100) – moving the turtle forward 100 steps.

The next portion is the BasicRunner itself – you’ll recall that we called the static public run method of that class, above.  It looks something like this:

static def run() {
  String scriptStr = Napili.code;
  def config = new CompilerConfiguration()
  config.setScriptBaseClass("org.netdance.napili.language.TurtleDelegateBaseScript")
  def ic = new ImportCustomizer();
  ic.addImports('javafx.scene.paint.Color')
  def ti = new ASTTransformationCustomizer([value: 15L],TimedInterrupt)
  config.addCompilationCustomizers(ic, ti)
  def shell = new GroovyShell(config)
  try {
    def script = shell.parse(scriptStr)
    script.setBinding(new BasicBinding())
    script.run()
  } catch (Exception e) {
    // error handling here
  }
}

In this method, first you fetch the script String to execute from the passed class.  Then, create a CompilerConfiguration object.  To the configuration object, set the BaseScript to the TurtleDelegateBaseScript just described, above.  Add a new import of javafx.scene.paint.Color, which will be applied to every script, so the user can say things like pencolor Color.PURPLE without having to do an import themselves. 

The next line, with it’s creation of an ASTTransformationCustomizer, looks a bit mysterious, but it’s effect is very straightforward – it sets a timeout on the script of 15 seconds.  After that, the script will throw an exception.  How it does this is a bit of an involved explanation, but we’ll have a lot more to say about AST Tranformations in a future post.

Then, as I’ve previously covered, just create a GroovyShell, parse the script, add a Binding (as I’ve also previously covered), and run the script.  If the user makes an error in the program, it’ll be caught as an Exception in the catch block.

The Binding itself isn’t terribly complicated either, but this is getting long, so I’ll continue on to describe the Binding section in the next post.

Advertisements

Written by jamesgdriscoll

October 13, 2012 at 1:38 PM

Posted in DSL, Groovy

A Turtle Graphics DSL

leave a comment »

In my previous post, I discussed the example program that I wrote to exercise the things I’ve described so far.  Today I’ll discuss what the DSL will actually look like – as with most programming tasks, designing your DSL before implementation is almost always advised.

There are a couple of different ways that you can use to describe languages, the most popular (and my favorite) being BNF, but for our purposes, that’s certainly overkill.  Instead, let’s just do this informally.

First, we’ll allow all existing Groovy operators and control structures – there are good reasons to strip those out on occasion, but this isn’t one of them.  We’ll cover how to do that at a later date.  What this means is that structures like while (condition) {block} and if (condition) {block} will work just fine.  We’ll also be able to create methods inline, just as you can with Groovy scripts.  And standard comments (i.e., // and /* */) will also work as expected.

We’ll need the following commands to create an environment that allows for turtle graphics:

  • Turtle / Movement Commands
    • forward number 
      • move the turtle forward by number of steps
    • back number
      • move the turtle backward by number of steps
    • right number
      • turn the turtle number of degrees to the right (clockwise)
    • left number
      • turn the turtle number of degrees to the left (counter clockwise)
    • home
      • return the turtle to the starting position, without drawing any lines
  • Pen / Drawing Commands
    • pendown
      • set the pen to draw when the turtle moves
    • penup
      • set the pen to not draw when the turtle moves
    • pencolor Color
      • change the pen color to Color
  • Animation / Demo Commands
    • show
      • show the turtle icon
    • hide
      • hide the turtle icon
    • speed number
      • change the speed at which the turtle draws, larger is faster
Keywords/methods are in bold, parameters are in italics.  Since we need to decide what number means, we can define it as a double, and since Groovy will auto convert int to double, we’re done with that.  Color is a little more problematic – ideally, we’d make it easy to use and understand, and have a whole bunch of code to do that, but since we’re currently just making a sample program, we’ll just use javafx.scene.paint.Color.
 
If you download the Groovy Turtle Graphics program Napili, you’ll see that all of these methods are already implemented in org.netdance.napili.Turtle.  I’ll talk about how to turn those methods into a DSL in the next post.  For now, here’s a sample program that you can run using these commands, along with the standard stuff that Groovy provides:
 
def circle(size) {
    45.times {
        forward size
        right 8
    }
}

speed 3
penup
forward 250
pendown
pencolor Color.PURPLE

12.times {
    circle 10
    right 30
}

home
hide

This program draws a series of interlocking circles, like you’d get from the child’s toy Spirograph.   We define a method (circle), set the speed a bit higher to make it all draw quickly, move forward without drawing to center the design, set the pen color to purple (PURPLE is one of many predefined values in javafx.scene.paint.Color), then draw 12 circles, turning 30 degrees after each.  At the end, we park the turtle in the home position and then hide it.  If you’re unfamiliar with Groovy, Integer.times(Closure) is a method that Groovy places on all values of Integer (and primitives are auto boxed to their class type in Groovy) – it just executes the closure as many times as the value of the integer – remember, parenthesis are optional for methods with arguments, so the circle method is really the equivalent of Integer.valueOf(45).times({forward size; right 8;}) – I trust you’ll agree that the format I used is actually easier to read, once you’re used to it.

See you next time, where I’ll talk about how to turn the methods on Class Turtle into the DSL above.

Written by jamesgdriscoll

October 6, 2012 at 12:46 PM

Posted in DSL

Napili – a Turtle Graphics program with JavaFX and Groovy

leave a comment »

My very first programming language was BASIC.  But the first time I ever thought I could do this for a living was when I discovered LOGO.  While the language itself didn’t interest me in particular, I was fascinated by Turtle Graphics.

If you’re unfamiliar with Turtle Graphics, it’s a pretty simple concept:  while traditional graphics paradigms involve an x/y coordinate system, where each pixel is filled in based on it’s coordinate location, and all functionality is built around coordinates, turtle graphics systems instead work with a two objects:  a drawing surface, whose properties are opaque to the programmer (except possibly it’s size), and a turtle, which is the object the programmer manipulates.  The Turtle is, in turn, an abstraction – it has a location, an orientation, and a pen.  The pen, in turn, has attributes such as color, width, and up verses down.  The turtle is usually represented on the screen by either a triangle, a diamond, or a bitmap of a cartoon turtle.

The turtle is controlled via commands, such as PEN DOWN, FORWARD 100, and RIGHT 45 (which sets the pen to draw, moves forward by 100 arbitrary units, and turns the turtle 45 degrees clockwise).

This is a great example of a DSL for our purposes, since it’s a very specific domain (drawing via a turtle), is a very well understood paradigm, and would benefit greatly from the control structures that Groovy gives us.

At the same time that I was thinking about what kinds of programs to use for my examples, I attended the GR8US conference, and several speakers sang the praises of JavaFX, which had just been released as part of the JDK.  So, I thought, why not learn about JavaFX while creating this Groovy Turtle Graphics program?  Scala already has the excellent Kojo, but I couldn’t find something similar for Groovy, so, why not?

The result is Napili, now available  on GitHub under the Apache License.

Over the next few posts, I’ll go over how I applied my previous posts on DSLs to the problem of creating a Turtle Graphics DSL.  I’ll also use this program to cover a few other topics that I have planned, such as program throttling and security.

In the interim, if you’re interested in a small, simple example of a DSL (or, for that matter, of JavaFX animations), download it and check it out.  

One last note: Napili isn’t really ready to indoctrinate some new high school kid into the world of Groovy programming.  In particular, it’s “editor” is just a text area, not some spiffy syntax highlighting full featured component, and it’s error reporting is very, very primitive.  If you think that the world really needs a Groovy turtle graphics programming IDE, please drop me a line and let me know.  Bonus points if you want to help.

Written by jamesgdriscoll

October 3, 2012 at 11:53 AM

Posted in Groovy, JavaFX

DSLs – What we’ve covered so far…

leave a comment »

At this point, we’ve covered many of the basics of creating DSLs in Groovy:

With that, we’re ready to tackle a real example…  Which I’ll detail in the next post.

Written by jamesgdriscoll

October 1, 2012 at 7:33 PM

Posted in DSL