ObjoScript

An open source object-oriented scripting language written in Xojo that is designed to be embedded in a Xojo app. it's fast, production-ready and easily extensible.

Repository

https://github.com/gkjpettet/ObjoScript

Background

For years I've toyed around with the idea of writing an app that can make games. Something along the lines of GameMaker Studio or Godot but simpler with a much narrower focus on desktop 2D gaming. Since I'm very experienced with Xojo and not many other languages, I always intended on building this app with Xojo. I knew that if I did build such an app, it would need a scripting language that the user would develop their game in. Of course, Xojo provides its own scripting language, XojoScript, that I could have used but there are several pain points with XojoScript that make it a non-starter. There are other embeddable scripting languages (mostly offered by Einhugur Software) that you can use with Xojo such as Wren, Lua, Python and JavaScript but none of them were the perfect fit for my needs. The biggest issue with all of them is the inability to debug the scripts line by line and inspect their variables.

Rather than settle on a suboptimal language, I decided to implement my own and named it ObjoScript. The name comes from the fact that I plan to call the game making app Objo if it ever gets made. The language is heavily influenced by Wren with just a few changes to make it more suitable for embedding in a game engine. Honestly I would have used Wren in a heartbeat if it was possible to step-through debug it from within Xojo.

Technical implementation

ObjoScript is an object-oriented dynamic scripting language. Source code is first parsed into an abstract syntax tree and is then compiled to bytecode to be run on the stack-based ObjoScript virtual machine (VM). The entire pipeline is written in Xojo and there are no external dependencies. The code is fully documented and is API 2.0-compliant. Since it is/was designed to be used within a Xojo game engine, it is very easy to embed within a Xojo app.

Currently, the source code for the script is compiled each time the VM runs - there is no ahead of time (AOT) compilation. This is something that is technically feasible to implement (since the source code eventually gets transformed into bytecode anyway so storing it in a MemoryBlock should be simple enough) but has not yet been implemented. The primary reason for this is that you'd lose debugging capability without access to the script's source code so it wasn't a priority to get working early on in development.

Syntax

As mentioned, ObjoScript is very similar to Wren and so most Wren code will run with little or no changes. The only aspects of the Wren language that aren't in ObjoScript are fibres, closures and anonymous functions. In essence, it's a curly-braces language with no semicolons.

class Person {
	greet(who) {
		System.print("Hello " + who + ", I'm a Person.")
	}
}
			
class Doctor is Person {
	greet(who) {
		System.print("Hello " + who + ", I'm a Doctor.")
	}
}
			
var garry = Doctor()
garry.greet("Steve")

What's in the repo?

Like all my open source work, the source code lives over at GitHub. Launch the development harness project (src/dev harness/ObjoScript.xojo_project) in a modern version of Xojo and run it. You'll be presented with a demo app that includes a syntax highlighting editor, debugger and bytecode disassembler and comprehensive test suite. If you examine the source code, you should be able to figure out how the language is embedded within the app. You'll also find a command line tool to run scripts from the Terminal.

Code editor

Code editor

Bytecode disassembler

Bytecode disassembler

Debugger

Debugger

AST viewer

AST view

Test suite

ObjoScript test suite

Requirements

Whilst ObjoScript is 100% Xojo code and itself doesn’t depend on any plugins, the development harness uses Einhugur’s TreeView plugin and the code editor uses Einhugur’s open source TextInputCanvas. Demo versions are included in the repo.

Documentation

The language features and how to embed are explained in the project's GitHub wiki.