IRBasic - object-oriented BASIC

You’ve probably noticed a trend in the last few articles. I’ve actually stopped waxing lyrical about Python, and instead I’ve been going on about the innards of BBC BASIC V. I promised that I’d talk a bit about the old programs I had discovered and decoded using the BBC BASIC detokeniser.

To be honest, the only program I was interested in looking at was IRClient — an IRC client I had written for the Archimedes while at University. IRClient was a shareware program which kept me in beers during my days at Exeter Uni. Like many IRC clients, IRClient was fully scriptable. Back in those days I was far too big-headed to consider using someone else’s scripting language; so I devised my own — IRBasic.

The clue’s in the name, isn’t it? IRBasic was predominantly BBC BASIC V, but with a few rather interesting extras. While I was supposed to be studying Physics, a lot of my friends were doing Computer Science, and were learning languages like Java and Javascript — which rather influenced the design of IRBasic. Conversations with Malcolm in particular shaped the language into a dynamically-typed, overloadable, garbage-collected, object-oriented version of BBC BASIC.

I’ve just been looking through some of the source code, and two things strike me. One, that the interpreter is an absolute mess and it’s impossible to imagine how I wrote it — pure ARM assembler all the way through; stupendous label names (e.g. OhShiteNoNoNoNono, WombleLoopJedi2, MMFOOMBO2) and hard-to-fathom error messages (“Worm tablets at line 6780”)1 to name but a few.

Secondly, the language itself was actually pretty good. Good enough anyway for someone to notice it tucked away unannounced in a “Scripts” directory and then set about writing their own IRClient extensions. That somebody was the rather talented Justin Fletcher (aka Gerph) — a great friendship sprung up between us over that. Justin was able to write an integrated web browser, FTP client and email reader amongst other things — hats off to his reverse engineering skills! Interestingly, this makes IRClient an example of Zawinski’s Law of Software Envelopment“Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.”

So, for a quick taster of IRBasic, let’s define a class2. Classes are semi-dynamic inasmuch as they’re defined dynamically, and can be modified so long as there’s no active instance of a class.

Class_BTree = FNRegisterClass("BTree")
PROCAddField(Class_BTree,"data")
PROCAddField(Class_BTree,"less")
PROCAddField(Class_BTree,"more")
PROCAddField(Class_BTree,"compare")

As you can see, classes are defined using functions and procedure calls. The Class_BTree is then a “handle” to the metadata of a class, and an instance can be created and used via code like:

tree = NEW Class_BTree
PROCtree.Add("test")

Method calls are specially named procedures. For a class XX, a method call of YY on an instance of XX is equivalent to calling XX_YY — with the exception that within XX_YY there’s a magic “this” pointer @. There’s also a constructor XX_Construct and destrutor XX_Destroy, for example:

DEF PROCBTree_Construct
@.compare = FNnewString("BTree_CompareNumbers")
ENDPROC

As mentioned above, IRBasic is garbage collected; so there’s no need to explicitly free any object. In fact, IRBasic reference counts every object and then also has a mark/sweep garbage collector to free circular dependencies.

Functions can be overloaded too. If a function with the same name as another is defined, the most recently-defined function will be called. However, that function may call its “parent” function, with a call to PROC@. IRClient used this facility extensively to allow user-defined overloads on core functionality.

Overall, I was pretty impressed with how sophisticated IRBasic was. However, I do remember one bad thing about it — it was incredibly slow, about 4–5 times slower than vanilla BBC BASIC. Nevertheless, it was a fun project, and it was really quite interesting to take a look at my ten-year-old code again!


  1. Incidentally, this error message apparently occurs if you tried to use the . operator on a non-numeric value. Something like:
    PROC”hi”.foo 

  2. I hope Justin won’t mind me using his BTree class as an example here. 

Filed under: Coding
Posted at 23:35:00 GMT on 19th November 2007.

About Matt Godbolt

Matt Godbolt is a C++ developer working in Chicago for Aquatic. Follow him on Mastodon.