In recent times I’ve been thinking about ACE BASIC, a compiler for the Amiga I stopped working on just over 20 years ago; nostalgia’s setting in I guess. A few years ago wrote a bit about ACE in relation to BASIC’s 50th; there’s more in these 1994 and 1997 articles.
As mentioned in the 50th post, a wonderfully thriving community built up around ACE between 1991 and 1996 centred upon an active mailing list and contributions of ideas, example programs and tools. I have been mildly (but pleasantly) surprised by a couple of things since I stopped development:
- Continued use of ACE on Amiga hardware and emulators for at least a decade afterward.
- A project to modify the code generator for post mid-90s Amiga operating systems and additional targets such as PowerPC and Intel.
A new compiler or interpreter is a non-trivial task, especially in my current spare-time-poor state, but I wanted to explore how an ACE program could be rewritten for an HTML5 context.
One of my favourite ACE programs was an implementation of IFS (Iterated Function Systems) to generate simple 2D structures such as ferns, trees, the Sierpinski Triangle and so on. So I started with this. It’s simple yet complex enough to allow for a comparison of approaches.
- The ACE code is quite data-centric. DATA statements containing comma-separated values are read into two dimensional arrays, so the original data is not close to where it’s used and it’s not clear what the numbers are associated with. I could have taken this approach in the port, but chose instead to create a data object, a map, close to the point of use, copying the original array names (bad in some cases: a, b, c, okay in others: xoffset, yscale) from the ACE program for use as map key names, to make a correspondence easier to see.
- This meant first transposing the data (in Excel) so that DATA columns became rows.
- Preserving the existing DATA organisation could be accomplished by introducing functions such as data() and read() that create and read, respectively, a pool of data values. For future DATA-centric ACE program ports, I’ll try that approach.
- In ACE, the creation of a menu and its items is simple as shown by the creation of the Special menu below; this menu name is an Amiga convention. Shortcut key letters are optional.
menu 1,0,1,"Project" menu 1,1,1,"Sierpinski Triangle" menu 1,2,1,"Square" menu 1,3,1,"Fern" menu 1,4,1,"Tree #1" menu 1,5,1,"Tree #2" menu 1,6,1,"Sunflower" menu 1,7,0,"-------------------" menu 1,8,1,"Help...","H" menu 1,9,1,"About...","A"
- On the other hand, ACE’s (and so AmigaBASIC’s) reliance upon numeric identifiers is almost as unreadable as a collection of DATA statements. The MENU statements above declare the Project menu to be the first (from the left of a menu bar), with each menu item numbered in order of desired appearance and 1 or 0 enabling or disabling the menu item. Subsequent enable/disable operations on menus must refer to the same combination of numeric IDs, e.g. menu 1,2,0 would disable the Square item. Also, menu item selection handling is a bit awkward in ACE.
I don’t currently have a screenshot of ifs.b running on an Amiga or an emulator.
- Functions like menu(), window(), dialog() manipulate the DOM to add elements (canvas, list etc) via jQuery under the hood.
- A menu declaration corresponding to the ACE code’s Project menu (with Help and separator items omitted) follows, a key difference being that menu items are paired with callback functions (e.g. see sierpinski below), another being that there is no support for shortcut keys currently:
acejs.menu("Project", [ ["Sierpinski Triangle", sierpinski], ["Square", square], ["Fern", fern], ["Tree #1", tree1], ["Tree #2", tree2], ["Sunflower", sunflower], ["About...", about] ]);
- A window declaration that adds a framed canvas looks like this:
- wdw_id = acejs.window(“IFS”, 640, 400);
- and operations on the window make use of an ID:
- acejs.pset(wdw_id, outX, outY, pixelColor);
- Multiple menus and windows can be created.
- acejs.css is almost non-existent currently. I’m sure someone who delights in CSS could make it look suitably dark and brooding with their eyes closed. I make no claim to have any special talent in web design.
With ACEjs you only have to write an app.js source file for your application and use a standard index.html that brings in your code and whatever else is needed, in particular acejs.css (trivial right now) and acejs.js. The only special thing you have to do is to define an init() function in app.js to be invoked by the framework. The best way to see how this works is to look at the example.
A variant of the ideas that led to ACEjs are revealed in what I said on this page:
Peter Girard has suggested the creation of an ECMAScript code library for astronomical algorithms.
An idea I’ve had is to write a BASIC (which dialect: GWBASIC, QBasic, etc?) to ECMAScript translator, written in ECMAScript or Java. One could paste BASIC code into a text area on a web page, and have ECMAScript and HTML code generated on the fly. This would make the BASIC code on Sky & Telescope‘s web site available as interactive programs. Or, it could generate a listing, making Peter Girard’s idea of a code library easier to achieve.
History has shown that a programming language does not have to be perfect to succeed. I love C, but it’s far from perfect and holes in its type system allow one to, as the saying goes, “shoot one’s foot off”. Additionally, these same holes are responsible for security vulnerabilities in the operating systems we rely upon. Notice, I’m not saying that C itself is responsible (it’s not a person or a company) for exploits of those vulnerabilities; that’s attributable to the moral barrenness of the people involved. It’s unlikely that we’ll see the sum total of mainstream OS-land rewritten in safer languages (Rust, Haskell, …), to save us from ourselves, anytime soon.
But I digress…
When I was a junior academic in the computing department at UTAS in the mid-90s, upon learning about my development of ACE, a senior and sometimes less-than-tactful colleague remarked that creating a new language was, as he so delicately put it, “a wank”. I disagreed. ACE was about providing the power of a compiled language for a particular platform (Amiga) to people who knew an interpreted language (AmigaBASIC), wanted to leverage that experience and existing code and didn’t feel confident enough to learn the dominant systems-level language of the time (C). It was also about improving the precursor language.
Now, I would agree that the decision to create a new programming language or library requires some circumspection, at the very least. But the programming language landscape has expanded a lot since the mid-90s. There is of course value in writing an interpreter or compiler, just for the learning as an end in itself and every computer science or software engineering student should do so.
So, in the end: why ACEjs?
In part because I wanted to explore simple ways to write or port a certain class of application (e.g. old ACE programs) to client-side web applications.
Partly out of a sense of nostalgia.
Mostly, I wanted to get a bundle of ideas out of my system, which I’ve more or less done.
Finally, look in the About box of the example application for a small dedication, also present in the even simpler About box of ifs.b; my wife spent far too long listening to me talk about programming languages and compilers in the 90s. Now the talk is more likely to be about variable stars. Thanks Karen. We both like ferns as well, IFS generated or natural. 🙂
In any case, enjoy. Feedback welcome.