Excuse me while I have a geeky moment.
So in the background for a couple of hours here and there I’ve been tinkering with a LISP interpreter, with the goal of eventually inserting the LISP engine into an iOS application in order to make a programmable calculator with some ability to do basic calculus, as well as standard scientific calculator stuff, and automatic unit conversion stuff. (I even have some code somewhere which can handle arbitrary unit conversions, including arbitrary conversions in and out of standard scientific units.)
(Well, properly it’s a LISP compiler which compiles to a VM instruction set.)
A little while ago I managed to write a LISP compiler in LISP, compiled by a bootstrap compiler written in C, which was capable of compiling itself.
Well, now I have a primitive IDE for writing LISP code, which supports syntax coloring, automatic indentation, as well as setting breakpoints in my LISP code (step over and step out turns out to be a bitch) and examining the variable stack.
Breakpoints are managed by maintaining a table (including PC references into the instruction set) and setting a special instruction which halts the VM, and “single step” is handled by executing one VM instruction at a time until I hit one of the PC breakpoints.
And when not single stepping instructions, the VM is run on a second thread, to allow me to stop execution arbitrarily (in case of infinite loops).
Some pictures: showing breakpoints
Showing the debugger in progress, examining the stack and variables.
Of course there are some usability issues; I certainly wouldn’t want to ship this as a product. (In particular, you need to specify the entry point of a routine to debug, and breakpoints require the code to be compiled first–and compilation is a manual process; you have to press the compile button before adding breakpoints or starting to debug.)
And there are some gaps–the LISP implementation is incomplete, closures haven’t been written into the compiler (yet), and I don’t have a means to write to the standard out via a LISP instruction.
But there is enough to start actively building these components and testing them within the IDE, and fleshing out my LISP implementation–particularly since my LISP compiler is built in LISP, so adding features can be done with my IDE.
Next steps: include a window in my IDE which emulates the planned UI for the iOS product (a calculator keyboard, menu and display system–with keyboard events executing predefined LISP instructions, the menu built from a LISP global variable and the display formatting display instructions from another LISP global variable), as well as fixing bugs, fleshing out the LISP interpreter, and creating a mechanism for printing from LISP into my output window.
After that I can start writing the calculator code in LISP.
The syntax coloring was hung off the NSTextView (by setting a 1 second timer on update text events, and running a simplified LISP parser to do syntax coloring and variable detection to color local variables), and autoindent was handled by listening for newline events and calculating the proper indentation for the current parenthesis level.
And the nice part is that similar hooks exist on iOS in UITextView, and the debugger wrapper class should all port fairly easily to iOS. Meaning the functionality of the IDE should port rather easily to iOS.