I'm releasing a FOCAL interpreter

I suspect it would be trivially easy to adapt my original RetroBASIC to JOSS, almost as easy as converting it to FOCAL which took me a couple of hours here and there. Happy to do this with you if you’re interested, I was likely going to do it anyway this summer.

1 Like

The idea is to emulate the JOHNNIAC computer and have the JOSS implementation run on it. Not to emulate the JOSS language.

The dartmouth :: BASIC 4th Edition Jan68 manual only has:

IF [formula] [relation] [formula] THEN [line number] 

I think that most micro Basic interpreters were shipped as a Minimum Viable Product. Woz’s Integer Basic was enough to play his demo game. Later manufacturers knew they needed to include a language interpreter to keep the buyers (= parents) happy that it was an “educational” purchase. Commodore certainly didn’t waste a single cent on their interpreters, or anything else: I’ve seen the bandsaw marks on the cut-down cassette players inside PET 2001s …

Maybe what didn’t help Focal’s uptake was that the name FOCAL was a trademark of Digital Equipment Corporation.

If you have a chance, see if you can completely fill the heap with random bytes by going:

FOR X=1 TO FRE(0): A$ = CHR$(RND(1)*256): NEXT

This will certainly work, as CHR$() includes a string operation.
(This is really a consequence of strings being pointers to memory segments of variable length, and there being no optimizations of any kind, like checking for possible slices in already allocated strings.)

Fun fact: it takes 1 min 31 secs to fill the heap on an 8K instance at 1MHz: Try it here.

P.S.: As far as I can see, there is a clear alternative for simple optimizations for heap allocation: you can either copy pointers to existing allocations on assignment (like MS BASIC), or you can re-use existing allocations on re-assignments, if the new value is of equal or smaller length than the previous value. In order to have both, you really need some kind of reference count associated to each heap instance, which may not be a favorable option under low memory conditions.

(E.g.: We could use a leading byte for a reference count, and, on re-assignment, we first check the length, and, if this matches, we inspect the reference count for the current allocation, and if this happens to be exactly 1, we may re-use the existing allocation, otherwise, we create a new one. This also means, we’ll have to adjust the reference count on any assignments, as well, but this may be worth the overhead that comes with this. But, mind that this also complicates GC and we may need some kind of back-reference, too. As a further optimization, we may have another header byte, which stores the initial allocation size, which may cover a few more cases than just looking up the current string length of the variable.)