Fork me on GitHub

Register Level Debugger / Interpreter

Interpreter

To understand and debug RubyX better, an Interpreter was created for the Risc layer. Risc defines a relatively easy abstraction, that is both far away from the language level, yet still machine independent.

Risc has only 12 registers and almost as little instructions. Mostly moving data around, jumping and testing.

But since it is so simple, it it a little challenging to understand what is happening in terms of ruby language constructs, or even the Mom abstraction.

Many test use the Interpreter to test conversion output also dynamically. But to test successfully, one does need to know what should be happening.

To understand the Risc layer even better. A Graphical User Interface was created.

Visual Debugger

Web - tech

The application is implemented with web technology, in essence it is a JavaScript One Page Application. Luckily opal came to the rescue, and so not only the whole of Rubyx is running in the browser, but also all the application code is in ruby.

The app is so small it defines is own micro framework (2 classes), and basically only shows different list views.

From left to right there are several views showing different data and controls. All of the boxes with green border are in fact pop-up menus and can show more information. They represent memory/objects and by hovering one can
Most of these are implemented as a single class with the name reflecting what part. I wrote 2 base classes that handle element generation (ie there is no static html involved, just elements)

Code switch view

Top left at the top is a little control to switch programs. Currently there is a short hardcoded list of tiny tiny programs.

When one is selected, the Ruby is parsed and, Risc machine booted, the Interpreter (re)started and one can use the buttons to step through the code at various speeds.

Status View

The last view at the top right show the status of the interpreter, the instruction count, flags and any stdout.

Current controls include stepping and three speeds of running the program.

Space View

The second down on the left gives a view of the Space. It is the only instance of the class and the only global being used. It carries classes, types, singleton objects and some linked lists.

like other views it updates, so when for example an integer is "allocated" one can follow the list being relinked (the next free integer being swapped out)

Classes View

The lower column on the left is a list of classes in the system. Like on all boxes one can hover over a name to look at the class and it's instance type and so one, recursively.

Source View

Next is a view code to the right is currently broken, but should be the ruby code.

The next view on the right is Risc Machine Instruction panel. The are the instructions the Interpreter interprets. The next one is highlighted in blue.

Register Instruction view

RubyX defines a register machine level which is quite close to the arm machine, but with more sensible names. It has 12 registers (below) and an instruction set that is useful for the compiler.

Data movement related instruction implement an indexed get and set. There is also Constant load and integer operators and off course branches. Instructions print their name and used registers r0-r11.

The next instruction to be executed is highlighted in blue. A list of previous instructions is shown.

One can follow the effect of instruction in the register view below.

Register view

The bottom part of the screen is taken up by the 12 register. As we execute an object oriented language, we show the object contents if it is an object in a register. Data may occupy registers at this level, in which case the hex value is shown.

The (virtual) machine only uses objects, and specifically a linked list of Message objects to make calls. The current message is always in register 0 (analogous to a stack pointer). All other registers are scratch for statement use.

The Register view is now greatly improved, especially in it’s dynamic features:

This last feature of inspecting objects is show in the screenshot. This makes it possible to very quickly verify the programs behaviour. As it is a pure object system , all data is in objects, and all objects can be inspected.

Running the debugger

The debugger is online here. Because of the 10k lines of code it is a bit slow to load.

Also it is not yet possible to write one's own code yet. Just the basic examples.

You can off course clone the debugger from github and then change the codes.