I'll focus on my TRS-80 Model 100 and Tandy 102. I'll attempt to retrieve them from my garage (nontrivial) and rehabilitate them. Pending/barring that, I may also work with some Model T emulators such as Virtual T. I may program some games in MFORTH, and outline a book about the Model T platform to write after my current book is finished.
Retrochallenge 2016/10 Entrants List
Another idea: it might be fun to implement Forth in Model T BASIC. To increase the challenge, I might code a nontrivial app in the Forth I implement on top of BASIC...
Start/end: The Retrochallenge 2016/10 competition will run from October 1st to the end of the month. Blog entries should be complete by midnight on Monday 31st October GMT.
Local start: Midnight between Friday, September 30, 2016 and Saturday, October 1, 2016 UTC = Friday, September 30, 2016 at 5:00:00 PM PDT
Local end: Midnight between Monday, October 31, 2016 and Tuesday, November 1, 2016 UTC = Monday, October 31, 2016 at 5:00:00 PM PDT
I just read about RBASIC today. It will compile BASIC programs for the Model 100, as I understand it. That would certainly speed up my Forth implementation!
Well, it says in the manual (available separately) that the speed benefits may be small, because the code is only partially compiled and partially still in BASIC. Still, if anyone has a lead on it, I'd like to at least try it.
I got the idea to implement Forth in BASIC partly from someone who implemented a quick and dirty Forth in Perl. It will be harder to do in BASIC, because BASIC has no stack variables, among other things.
(morning)
I didn't get much sleep last night, and I'm exhausted and addled. Not a good start to Day 1.
I'm thinking about the actual mechanics of contorting a Forth compiler into a fairly vanilla Microsoft BASIC of the early 1980s. It's somewhat intimidating. For starters, I'm thinking of storing Forth programs in DATA statements, but that would automatically make the language less extensible.
I found this article: Bootstrapping a Forth in 40 lines of Lua code. Forty lines is pretty short, but I bet it would be longer in BASIC than Lua.
I think I'll model mine on the Perl code. It's flawed but easier to understand (for me) and easier to convert to BASIC. I may start sketching out a parallel version today or tomorrow.
(5pm Pacific Time, end of Day 1)
I've started outlining the BASIC program. Rather than writing the inner and outer loops, etc. first, I'm starting with the easy bits, such as the subroutines for the Forth words my program will support.
I set myself the goal of finishing the book Starting Forth before my wife gets home from a day's outing. I blush to self-incriminate that this is the first Forth book I'll have finished, although I've read plenty of miscellanea elsewhere.
The later chapters of Starting Forth, such as the one describing the architecture of a typical Forth, are laughably redundant for the kind of thing I'm trying to do. I don't even know if my Forth is going to have an extensible dictionary, although I had some good ideas about that yesterday. There's only so much you can do with Microsoft BASIC and 32K of RAM. "Stone knives and bearskins", as Mr. Spock said.
(11pm Pacific)
This book is becoming more and more edge-casy. I have 1.5 chapters left. I don't know whether I'm going to finish it tonight. Most of it is irrelevant to me right now, although I can see myself coming back to it as a reference book.
(morning)
I did finish the book last night. It really puts the lie to the idea that Forth is a tiny, simple language (at least modern versions).
I'm working on another project this afternoon, so I'm not sure how much time I can devote to the Retrochallenge today.
In fact, I was attending a tabletop game design event yesterday afternoon, and as predicted, I didn't have time for the Retrochallenge. With luck, I can do some work in the morning.
(later)
I have a job interview tomorrow, so that's taking some of my time. I started reading Thinking Forth, the more philosophical sequel to Starting Forth. It's not much, but it's arguably a step forward.
Busy, busy. Another job interview tomorrow (Friday) to prep for. Will probably not return to the Retrochallenge until Saturday afternoon (8-9 Oct), when I should have a lot of time.
Still reading Thinking Forth.
Over the past couple of days, I've written some code for the basic Forth words, like the four-banger math ops and stuff. I sketched it out in a notebook when I didn't have access to my laptop, so I haven't even tried the code. But it's available at BasicForthOps if you want to take a look.
(morning)
So that's nine out of the 14 words implemented in the Perl Forth interpreter I linked to, plus stuff like push and pop. Of course, I have yet to run them; that will take actually implementing a stack, etc. which means calculating how much space it can afford to use in the tiny Model 100 memory, and so on.
As well, every Forth needs a catchy name. The obvious one is Basic Forth, which incorporates a pun. If someone tells me that's already taken, I'll have to go with something like Crap Forth or Pisspoor Forth. I know you don't want me to do that.
Briefly returning to the project in 15 minutes before bed, I figure out how to load BFORTH.BA onto my Model 102 emulator and eventually run it there.
I've decided for the sake of expedience that Basic Forth programs will consist of one or more DATA statements in BASIC. Also, I may satisfy myself for now with the nine Forth words I've already implemented, which are sufficient to do simple arithmetic, and like that.
(later)
Setback: After an update, my laptop won't boot. I have a backup of the Basic Forth files, but nothing to work on them with until I reformat my laptop and reinstall Ubuntu. I'm busy all weekend, too. I'm definitely getting concerned about whether I can finish this.
It only took about 90 minutes to get my laptop up and running again, so optimism reigns.
Back to work on Basic Forth. Feeling the time pressure. Have a 92-line version that is complete in theory but reports a syntax error on the third line. Here it is if you want to see what I have so far: BasicForthCrashy.
This is my first Basic Forth test program. Again in theory, it should add 2 plus 3 and print 5.
2 3 + .
(later)
OK, I allocated too big a stack. The Model 100 has a brain the size of a raisin.
Now it will load my test program and run without error, but it never displays any output.
(later)
Maybe it wasn't the stack. I'm allocating a stack only 10% of before, but still getting a syntax error. This is what I get for not doing this whole thing with GitHub.
...
Well, apparently WORD$ is a BASIC keyword or something, so I abbreviated it to W$ and my Virtual T is much happier.
I also had a problem with program flow. I'm having a bit of a time with the "unstructured programming" paradigm of BASIC. Right now I would give a lot for a simple CASE statement...
(approaching bedtime)
OK, I have a working interpreter, for certain values of "working" (some of the math routines are "working" in mysterious ways, for example). I'm putting the code up at HoldingDownTheForth and will debug later. You can write tiny programs for it if you can figure out how from the code. Otherwise, I'll document it later (where have I heard that before? Oh yeah, developers).
OK, here is a "working" Basic Forth program (which gives the wrong answer). Says 20, should say 15 -- as I reckon it. You have to name it PROG.DO.
5 dup dup + + . end
The interpreter is down to 82 lines. Of course, I could probably write it in 8, not 82, if it only understood one keyword. The secret to my success!
Showtime.
I failed the challenge I set myself this month with BasicForth. It was my first attempt at writing a language interpreter, and I learned a few useful lessons.
First, leave yourself enough time. Everyone who succeeded this month already knows this lesson.
Second, know your medium. I found I didn't grok the idiosyncrasies of TRS-80 Model 100 BASIC well enough to dissect some bugs. For example, toward the end I was encountering a bug where the first time I added two numbers, the addition would succeed, but the second time, a plus sign (+) would appear on the stack. Or again, I wondered, why does the STR$ function prepend a space character when it converts a number to a string?
Third (and here I'm cribbing from The Seventy Maxims of Maximally Effective Mercenaries by Howard Tayler), "Failure is not an option - it is mandatory. The option is whether or not to let failure be the last thing you do."
With that maximally effective maxim in mind, congratulations to the winners, and see you in future RetroChallenges!
Ron Hale-Evans (@rwhe)
It looks to me like Ron made a good start on his Forth implementation in BASIC on the TRS-80 Model 100. A good start, but not a lot more. Ron’s final entry is circumspect with a good analysis of the project’s successes and failures — always an important step towards future improvement! I hope to see more from Ron in the future events, where I suspect he will do well.