You are currently browsing the code.timst() posts tagged: GUI


Project: Casio Basic Editor

I guess most of us had one of these ridiculously outdated graphing calculators in high school or college. You know what I’m talking about: 2 colors? 64K memory? One of the handful of items that still runs on AA batteries? Yes, these ones. Now, I guess real geeks had a TI calculator of some sort, or maybe another, more street cred-worthy brand. Well, I didn’t. I had a Casio. Specifically, a Casio Graph 35+, better know in the rest of the world as a Fx-9750 Plus:

casio fx9750

Back then, "power graphic" didn't exactly mean what you'd expect.

It boasted a badass 128*64 screen, 763 features (of which I used maybe 30 in my whole education), the ability to program in a BASIC-like language, and absolutely zero computer connectivity.  It only had a proprietary socket that allowed you to connect your Fx-9750 to other Casio calculators. Like you would connect Gameboys to exchange pokemons. Only, you know, sadder.

Since then they added a USB port, so for the low price of $80, you can allow your computer to discover how it feels to be stuck in the nineties. But seriously, that would have been a great tool to export and import some of the aforementioned Casio code to a computer where you could have edited it, tested it and so forth. Sadly, nothing of the sort existed back then, so I decided that even though there was nothing I could do on the connectivity part (short of jury-rigging a usb-to-casio cable, which apparently is possible, though I wouldn’t risk it), I could try to act on the edit and test part.

So I fired up Eclipse and set to work on a Casio BASIC Editor, with a poor man’s IDE, a simplified emulator and a compiler (well, interpreter, technically). It was a fun project, but also a hard one, since I had no previous experience in compilers, languages and that sort of things. I was helped by a friend of mine, and at the end I managed to obtain something that wasn’t too shabby. I divided the application in several parts :

 

  • A system unit, simulating the memory and screen of the calculator,
...

public final static int SIZEX = 128;
public final static int SIZEY = 64;

public final static int NB_FILES = 6;
public final static int NB_LISTS = 6;

/*
* The user has access to 60 kB of memory.
* Each number in the list represent 10 bytes of memory,
* therefore the theoretical maximum size of a list
* is 6 000 numbers.
*/
public final static int NB_ROWS = 6000;

private int currentListFile = 1;

private Stack<Double> stack = new Stack<Double>();
private Stack textStack = new Stack();

private Vars var = new Vars();
private boolean[][] screen = new boolean[SIZEX][SIZEY];
private double[][][] lists = new double[NB_FILES][NB_LISTS][NB_ROWS];

...

 

  • A GUI, displaying the screen of the device, a code editor, and a debug console,

gui

 

  • And obviously, the compilation unit.

The parsing of the code is divided in three parts. First, the code goes through a lexical analyzer that removes the syntaxic sugar and other human-friendly features to reduce the code to its basic elements.

Then, the lexed code is parsed. In my case, it was basically a large switch structure that created a tree of the program. Each instruction was turned into a class, which defined its name,  behavior during execution, and more important, the kind of data or statement that it contains. So for instance, a statement like NUMBER (representing any kind of numeric constant) can only contains a number, but a statement like PLUS contains two parameters, which can be statements too. Some statements are even more complex and involve entire blocks of instructions (IF or LOOP, for instance). Finding and parsing the parameters of each statement is thus a bit complicated, especially since there are infix, prefix and postfix operators, control structures (including GOTOs), and ambiguous statements (the “-” sign can be used both to denote a subtraction, but also to indicate a negative number). So in the end, I obtain a list of statements that contains statements that contains statements, repeated ad infinitum.

Once the list is complete, it executes it. Each statement has an exec() method that represent what it’s supposed to do. Sometime it’s assigning a variable, sometimes it’s writing to the screen, but most of the time it’s retrieving, modifying and pushing numbers from and to the memory.

 

Let’s take an example :

0->A
A+1->A
Locate 1,1,A

This code initializes the variable “A” (there is only 28 variables, A-Z and two special symbols) to 0, then increments it, then prints it on the top left corner of the screen. Once lexed, this resolve to :

NUMBER(0) ASSIGN VAR(A) EOL
VAR(A) PLUS NUMBER(1) ASSIGN VAR(A)  EOL
LOCATE NUMBER(1) COMMA NUMBER(1) COMMA VAR(A) EOL

Numbers and vars are encapsulated in appropriate keywords and instructions are ended by an EOL token, but it’s little more than the uppercase version of the code above. The real magic happens during the compilation:

Assign ENumber(0.0) to EVar(A)
Assign Plus
 (EVar(A), ENumber(1.0)) to EVar(A)
Locate ENumber(1.0), ENumber(1.0), EVar(A)

There are three top-level statement here: the initial assignment, that takes the number parameter and assigns it to the var parameter; the second assignment, that takes a plus parameter and assigns it to the var parameter; and the locate statement, that outputs the var parameter to the two number parameters. Note that the plus statement contains itself two parameters, the var and the number.

The code tree is then executed, which means that “0” is pushed onto the stack, then moved to the A var, the content of the A var and 1 are pushed onto the stack, they are retrieved, added, pushed to the A var, then 1, 1 and the content of the A var are pushed onto the stack, then used to write to the screen on the tile (1,1). And a beautiful “1” appear on the corner of the screen.

 

I didn’t finish the project, sadly. Most features are implemented, including “if” statements and some loops, but there are still a bunch of issues that need ironing out, meaning it probably won’t work as intended for anything but the most trivial bit of code. The harder part is done though, so maybe I’ll get back to it one day to finish it, or at least clean it up nicely and release the source code on github.

If you’re interested,  feel free to send me an e-mail (you’ll find it on the main site). I’ll be happy to talk about it, or about similar projects that you or others have been working on.