Multics > People > Stories
14 Jun 2005

Multics SNOBOL and the Missing END Statement

Olin Sibert

In addition to the GCOS version, there was a native Multics SNOBOL implementation.

Building on a lot of earlier work by Steve Kent, Warren Montgomery, and others, and at the urging of Bob Frankston, I converted the standard Arizona SNOBOL implementation to run on Multics sometime around 1977. The SNOBOL code was a threaded code interpreter for which I provided PL/I glue code for I/O and stuff. I don't believe it was ever distributed as part of the product (not much demand for SNOBOL, even then), but it may have lived in MIT's AML/IML libraries.

The standard SNOBOL implementation was a novelty: it was a portable assembly language program, and had been ported to many different machines by the time it reached Multics. To port it, one had to write a bunch of macros (maybe 50?) that generated appropriate native code, then assemble the standard 50,000-line SNOBOL source with those macro definitions. Steve Kent did most of the macros, using the mexp outboard macro processor, but never finished the project (possibly because of limitations in mexp, I can't remember now).

By the time I took it over, Bernie Greenberg had integrated macro expansion directly into the ALM assembler, so I thought it would be a piece of cake. I wrote and tested the little PL/I runtime code, fixed some macro syntax errors, and finally fed the whole thing to ALM, expecting it to assemble.

ALM's response, after several (expensive) CPU minutes, was "End statement missing"

This was ridiculous. I looked. There certainly was an "end" statement, right there at the end where it belonged. Just in case, I put in half a dozen more as a preventative against software inertia and tried again (it was a big program, after all). Still no dice.

After quite a lot of expensive CPU minutes, I finally hit on a strategy of binary search: cut the program in half, see if that half gets through pass 1, etc. This worked, isolating the problem to a single line about 3/4 of the way into the program. The line contained a perfectly legitimate-looking macro call, and I tried a bunch of changes to see if I could make it work. No dice: with that line present, I got the same mysterious error message; with it absent, the assembly worked. Finally, by accident, I made some change that also removed the comment... and it assembled. Leaving the comment off, I changed the macro back to what it should be, and... it assembled.

Turned out that the comment contained a single open parenthesis. For reasons too complicated to explain, the macro expander paid attention to that parenthesis (even though in a comment), treating it as the beginning of a macro argument, and then ate the rest of the file as macro arguments, and failed to find an "end" statement.

This bug turned out to be utterly intractable--it resulted from a complex interaction of the internal structures of the assembler and the macro expander. As far as I know, it was never fixed.

Once over that hurdle, the code needed one or two other minor touchups and then it just worked--not bad for 50,000 lines of assembler. The neat thing about the portable macro approach is that if the macros work at all, they will likely work everywhere, and there are rarely any subtle problems to track down. I've never run across another software package built that way, but I can't believe the approach is unique.

Also as far as I know, Multics SNOBOL was never used for any significant purpose. Bob Frankston had lost interest in it by the time I finally found the missing end statement; I can't remember why he wanted it in the first place. It wasn't a complete orphan--I sent tapes of it to USL and a few other sites, and I fixed at least one bug for USL (in my PL/I code, of course, not in the macro part), but I don't believe it ever saw much use beyond an occasional languages course.