Edd Biddulph

Twitter | CV


July 2011
An Interpreter for a BASIC-like Programming Language, with 3D Graphics

This is an interpreter for a pretty simple custom programming language similar to BASIC, which includes a subset of the OpenGL 1.1 API. Simple games (or perhaps even complex ones, given enough determination and patience!) can be created, as the language provides a way to capture keyboard state. Provided examples include a navigable procedurally-generated terrain and an implementation of insertion sort. The terrain demo includes a way to create textures, despite the language not supporting pointers (however, it does support arrays) and it does this using a built-in utility function and glCopyTexImage2D. The interpreter itself is a register-based virtual machine and was written in C. Although the VM is register-based, the compiler uses a stack to track register usage. The stack is only used when parsing the input program source.

Here is the full example of insertion sort which is included with the download, and can be run with the compiled interpreter. It should give you a feeling for what the syntax is like.

array SortArray[32] ; Step one: Fill array with pseudorandom numbers i=0 while i < SortArray.length SortArray[i] = (i*23) % 31 i=i+1 wend ; Step two: Perform in-place insertion sort i=1 while i < SortArray.length val=SortArray[i] j=i while (j > 0) & (SortArray[j - 1] > val) SortArray[j] = SortArray[j - 1] j = j - 1 wend SortArray[j]=val i=i+1 wend ; Step three: Print out sorted array i=0 while i < SortArray.length debugprint SortArray[i] i=i+1 wend

Programs can easily be written in this language, as there is no requirement for variables to be declared with a strict datatype or for the program code to be modular. Furthermore, the written programs can be run on any platform to which the interpreter has been ported. Porting of the interpreter should not be too troublesome as it was written in portable C and many platforms provide support for OpenGL. Even if real OpenGL support is not available, the interpreter can be re-written to target any graphics API without requiring any changes to the interpreted programs.

The interpreter has also been designed to allow the binding of other C APIs to BASIC function calls, not just OpenGL.

I used a separate program to automatically produce OpenGL-binding code, which made it easy to provide a subset of the OpenGL API. While this has resulted in a number of GL functions effectively having no use but still being accepted due to their signature, those functions should not hinder the program in any way. The symbol table used during compilation is a hash table. The hashing expression is quite simple, so I added a histogram display feature to check the distribution wasn't terrible. Last time I checked, there were 700 or so symbols (this would include GL functions and enumerations, plus any custom things) and the symbol lookup would at most perform a full check on about 30 of them for a given string.

One of the example programs, a game similar to Asteroids

Another example program

What follows is a list of the language's features and currently missing functionality. As previously mentioned, please see the included sample programs if you are interested in writing your own.

Available functions include math, functions to update the display and the input state, query the input state, print a number to standard output (for debugging), return the current number of milliseconds since the engine was initialized, and create a 2D texture. The language does not support pointers, so any OpenGL function with an address parameter is not included. However I added CreateTexture2D which has the exact same parameters as glTexImage2D save for the last which would be a pointer. This last parameter is not needed and is set to NULL by the interpreter. As there is no way to load an image file, a texture must be created procedurally as demonstrated in one of the sample programs.

The following commandline switches can be used:

o Lists all the operations in the compiled program. Effectively a disassembly. h Lists some hash table statistics. Only useful to anyone developing the interpreter itself. s Lists the entire symbol table after compilation has completed. This includes all internally-defined symbols and those defined by the interpreted program source. f Runs the program fullscreen

The interpreter internally uses either C float or C int depending on context, but it would be great to convert it to use a multiprecision format instead. For example, Java's BigDecimal class covers both floating and fixed formats plus a greatly extended range and arbitrary precision at the cost of reduced performance. A C equivalent of this would be ideal.

Download (23/Aug/2011) - Includes source, Windows 32-bit executable, and example programs. Source code is licensed under the zlib license.