Years ago (more than a dozen), I tried to write (in C) an interpreter/compiler for a dialect of BASIC that I made up. It was based on BBC BASIC and the BBC's graphics facilities (which I was very familiar with at the time) but it would have run on the PC and had some additional features:
- Operators and control structures from C
- More string and array processing facilities
- More graphics commands
- Interactive editor and debugger
- Commands for accessing PC facilities (interrupts, calling native code etc.)
- Built-in help
- Facilities for storing chunks of code as a library
- Complex numbers
- Self-modification and introspection facilities
The last of these is what I want to write about today.
As a child I used many of the 8-bit BASIC variants which had line numbers and it always irked me that there were some things you could do in immediate mode that you couldn't do from a running program, such as editing the program. Why was it that typing:
PRINT "HELLO"
printed "HELLO" immediately and:
10 PRINT "HELLO"
printed "HELLO" when the program was run but
10 10 PRINT "HELLO"
didn't create a program that replaced itself with the program '10 PRINT "HELLO"' when it was run? While doing so didn't seem terribly useful it seemed to me that an interpreter would be just as easy (if not easier) to write with this facility than without it, and that it was an unnatural ommission.
Along similar lines, my dialect had an "INTERPRET" command which took a string and ran it as BASIC code and a "PROGRAM$" array which contained the lines of the program.
I got some way in to writing a parser for it but as I didn't know how to write a parser back then I got horribly tangled trying to write code for each possible combination of current state and next piece of input.
The similarities between this and the UnityALFE language that I'm in the (very slow and gradual) process of writing haven't escaped me.