A Java scripting language -- Leola

Hello Java-Gaming.org,

I have been working on a programming language on and off now for about 3 years. It doesn’t really have an objective other than for entertainment for myself. With that said, I have found it quite fun to program in!

It is written in Java and interfaces fairly well with Java. If you are interested you can check out the project page at https://github.com/tonysparks/leola.

As a proof of concept I began to write a simple 2D game framework (currently just wraps Java2D) for simple/rapid prototyping.

Here is a screenshot of a simple Space Invaders clone:

Here is the Leola source code for the Space Invaders clone: http://pastebin.java-gaming.org/4584c18435b

Here is another screenshot of an in progress top down shooter:

Thank you all for your time!

-Tony

Looks like Javascript, a lot. Do you have benchmark on how well it performs calculus?

It does borrow a lot of features from JavaScript. The key differences are explicit language support for classes and namespaces. I almost think it being so closely related to JavaScript is a good thing, in that it is easy to read and write.

I don’t have a benchmark for the calculus, but I’d imagine they wouldn’t be very good compared to C or Java. Calculus isn’t necessarily Leola’s forte, the example was to show off closures and higher order functions.

For an interpreted language, it is actually fairly “fast”. The simple prototype games average ~60 FPS, which is pretty good given that 90% of the code is in Leola (the render calls and game loop are in Java).

I also use Leola for simple scripting tasks (updating/querying databases, moving/parsing files, etc.) and have never encountered performance problems.

Very cool.

How did you learn how to write your own scripting language, with classes, closures, and all that? :o

Thanks davedes!

It’s just like anything else, just by taking the time to dig into it. I initially toyed around with parser generators (in particular Antlr) but found them extremely confusing and cumbersome to use. Once I decided to write the lexing/parsing manually, things started going smoothly. The book that helped out tremendously is http://www.amazon.com/Writing-Compilers-Interpreters-Software-Engineering/dp/0470177071.

My initial implementation was just a very simple Abstract Syntax Tree walker, essentially what BeanShell is. Performance was not very good at all, but it motivated me in the sense that creating a language was “doable”.

Wow! :o
Really amazing!

I’ve seen those switch'es in the example code…
Can we do pattern matching with it?

Would be AWESOME!

Thanks :smiley:

There is a ‘switch’ and a ‘case’ statement, they only differ in that the ‘switch’ executes a statement when a condition is met, and the ‘case’ executes an expression. They both support a type of pattern matching, not as robust as say Scala’s pattern matching – but still useful.

Here are some examples:



// finds the first match
var myFavoriteTeam = "Packers"
var status = case myFavoriteTeam {
	when "Bears" -> "the worst"
	when "49ers" -> "OK"
	when "Seahawks" -> "Meh"
        when 1234 -> "Just showing the conditions can be anything"
	when "Packers" -> "The greatest"

	else "not so good"
}

println(status) // prints "The greatest"


class X();
class Y();

var x = new X()

// finds the first match
switch {
	when x is Y -> println("x is Y")
	when x is X -> println("x is X")	
	else println("Unknown")
} // prints "x is X"

class Z() is Y(); // Z inherits from Y
var z = new Z()


// finds the first match, in this case it is Y because Z inherits from Y
switch {
	when z is X -> println("z is X")
	when z is Y -> println("z is Y")
	
	else println("Unknown")
} // prints "z is Y"

This looks really cool! I would love to test it out–is there a compiled library JAR out there? Also, I love the love for the Packers and hatred of the Bears :smiley:

Great fun building a language. Thought about it too, however IDE support or lack of is problematic.

An editor like Sublime or Notepad++ is enough for this.

Why call this scripting? AFAIK scripting is something like HTML, CSS, JSON, etc where there is no logic inside.

Then why they call [icode]JavaScript[/icode], [icode]ActionScript[/icode], [icode]VBScript[/icode] with their names? Don’t they have logic in them?

They do. But I talked about the “scripting” verb, which is used by web designer on their HTML & CSS replacing “coding”/“programming” on other side.

Yeah, the Bears suck :wink:

I use Notepad++ (with my own custom syntax highlighting) with the NppExec plugin – works awesome. I bound CTRL+SHIFT+C to compile and run the current file. As ReBirth has mentioned, an IDE would be overkill.

You can download the jar file, a windows executable file (for convenience) and the space invaders game here: https://dl.dropboxusercontent.com/u/11954191/leola.zip

To install, just extract to a directory (ex. C:\leola)

To run the space invaders game, open a cmd prompt and navigate to the install directory and
run the following command:


C:\leola>leola.exe "./live.leola" "./spaceinvaders/spaceInvaders.leola"

A cool feature about the game framework is that it detects when a file has changed. If a file has changed, it will reload the game. This helps facilitate the rapid prototyping by giving almost instant feedback when modifying the code.

If anyone is interested, I can put up a short tutorial on how to setup Notepad++ for nice easy integration with Leola.

Thanks!

Tony

@ReBirth – with regards to calling it “scripting”; I think of a small little one-off program as just little scripts to quickly accomplish a task. I got this nomenclature from shell scripts. Same concept, at least for me. I see what you are saying though.

I was really interested in this. (Also got a copy of the book you mentioned from a local shop). However got one doubt though.


class Entity(pos, speed) {

What if I want to do multiple constructors? Is this available?

Scripting: Using pre-defined commands to automate a process which could be done by a human.

There aren’t any operator overloads in Leola (a slight lie). A work around can be to use a Map to populate the constructor such as:



// the map can contain values that you want to
// populate in the class.  If the value is not supplied, use a default
class Entity(settings) {
   var pos = settings.pos
   var vel = settings.vel

   var someOptionalParameter = case when settings.option != null -> settings.option else "defaultValue"
}


var hero = new Entity({
   pos -> live:math:newVec2(),
   vel -> live:math:newVec2(),
})

var enemy = new Entity({
   pos -> live:math:newVec2(),
   vel -> live:math:newVec2(),
   someOptionalParameter -> "Something that isn't the defaultValue"
})

/* You can even add properties dynamically after construction */
enemy.somethingNew = "a new property"
enemy.somethingElse = def() return "a new function"

println( enemy.somethingNew ) // prints "a new property"
println( enemy.somethingElse() ) // prints "a new function"


Does Leola layer on top of Java? So you can quickly write an implementation for networking, or do you have to manually write new things etc?

@Argo – I’m not exactly sure what you are asking. Are you asking if you can interop directly with Java classes without writing a “binding” layer?

The answer is yes, the “binding” layer is completely optional. I only recommend using it when you want to have a closer integration with Leola. For instance in the SQL library I have this construct:


// conn is a simple "wrapper" around java.sql.Connection.  It adds some useful
// methods for taking advantage of Leola's features
var conn = db:connect("dbUrl", "myuser", "password")

/* wraps all of the delete statements into 1 transaction */
conn.transaction(def() {
  
  conn.query("delete from table where table.id = :ID").params({ID -> 1234}).update()
  conn.query("delete from table2 where table2.id = :ID").params({ID -> 9876}).update()
}) 


If you want to instantiate a Java object, it is as simple as:


var javaArray = new java.util.ArrayList()
javaArray.add( 20 )
println(javaArray.get(0) ) // prints "20"

Oh, that’s neat. I love that. I’ll try it out later!