From: Rainer Thonnes Date: Sun Oct 6, 2002 2:09 pm Subject: IMP15 compiler resurrected As reported a few weeks ago, Graham and I have typed in the source of the IMP15 compiler, dated 1978, from a paper listing which Ian Young had lying around at home. There was a faint hope that, once John Gray's DECtapes were read in Grenoble, assuming they contained a copy of the operating system and the prim/perm library, we might be able to fire it up under emulation, or possibly even on Grenoble's real live PDP9. But I couldn't wait that long, and there is a possibility that the DECtapes might not contain what we'd need, and since we were without copies of prim/perm sources, it seemed a good idea, given that emulation was going to be involved anyway, to emulate/simulate not just the behaviour of the PDP9 (or PDP15) instruction set, but also that of the prim routines themselves. It was relatively easy, aided by partial recall, to deduce from the compiler source what they were all expected to do, and to implement the required functionality at a higher level. Actually to re-write the perm from scratch in assembly code would have been much more tedious, not to mention error-prone. This approach also neatly obviated the need to emulate the underlying operating system, since interfacing to the file system of the host machine is much easier if you can intercept the I/O calls at the level of the interface between the language and perm rather than at the level of IOT instructions, especially when DECtapes are involved. I'm pleased to report that this exercise has been sufficiently succesful that I have been able to run the compiler, and to use it not only to compile and run an original 1975 ECCE source, but also to get the compiler to compile itself. The groundwork for all this was done by Graham, by using his automated IMP to C translator to provide a C version of the compiler, which I was able to compile and run on my Windows PC. Then all I had to do was write code to read, reverse, load, and run (emulate) the object code produced by feeding any IMP15 source file to Graham's C version of the compiler. My code is a self-contained program "run.c" of less than 1000 lines (actually less than 750 if comments and blank lines aren't counted). In the original IMP15 system the reverser was one of the component parts of the operating system (written in assembly language). It was automatically invoked whenever the compiler had successfully compiled a program. It did more than just turn the object file back to font, it amalgamated fragmented code and data sections, and also exbedded nested blocks, so that there was no need for the compiler to plant jumps around inner procedures. The loader, also an operating system module, expected the code to be in this reversed format, not because it helped with fixing up forward references (this was something the loader was not only well able to deal with itself, but was obliged to do in any case -- with the file reversed, backward references effectively became forward ones, and certainly no allocation of fixed addresses was done by the compiler, thus the file could be run on machines with any amount of memory), but simply to make it easy to load the file incrementally backwards from the high address end of memory, given that the resident supervisor sat at the low address end. Free memory was the space inbetween, from which file-processors allocated buffer blocks on demand upwards from the low end, while the compiler allocated space for arrays and recursive stack frames and complicated expressions downwards from the high end. The compiler reads (compiles) a file of specs for all the perm routines before tackling the main program itself. It is crucial that the spec file matches up with the run-time emulator, because prim/perm calls are matched up by tag numbers, so the order, and number of them, must be right.