Garth, here's some of what I was referring to:
http://www.ultratechnology.com/cm52299.htmI had an interesting experience yesterday as I was trying to shove all of the F83 sources in to a single file. F83 works with Block files, vs text files. And it's core system comes in 5 files: KERNEL86.BLK, EXTEND86.BLK, META86.BLK, CPU8086.BLK, and UTILITY.BLK.
A Block files contains both code and documentation. Essentially the file is divided in half, and each code screen has an associated documentation, or Shadow, screen that's half a file away. So, if you have a file with 100 Screens, Code Screen 1's shadow screen would be Screen 51. In the editor, you can toggle between the 2 with the 'A' (Alternate) command. You can change the offset to suit you, but, you're working against the grain doing that.
Now, the Forth block commands have no concept of a file. So, the system has the trait of a Current File. Thus, when you enter 1 LIST or 1 EDIT or 1 LOAD, you will be working with the first screen of the "current" file.
F83 also has a nice facility called VIEW. If you type VIEW WORDS, it will list the source screen that has the "WORDS" word. You have source to everything, so it makes it easy to browse the source and the documentation. However, the VIEW word, under the covers, changes the Current File.
If you do:
Code:
OPEN MYFILE.BLK
1 LIST
VIEW WORDS
1 LOAD
You just loaded the first screen of KERNEL86.BLK, which is where the source for WORDS resides.
So, to simplify things, I was going to try and push all of the source in to a single block file, along with my own work, just to keep that from happening. To quote Forrest Gump: "That's good! One less thing."
So, I had to copy the existing block files in to a new monolithic one. But because of the nature of Shadow screens, and their relationship to the overall size of the file, I couldn't simply concatenate the files. I could, they'd just be more of a pain to deal with overall.
F83 also has the idea of the "INPUT" file, specifically for problems like moving screens from one to another. It also has the CONVEY word to perform the copy. CONVEY has the variable, HOPPED, which is used to offset the copy. Normally you'd do: 1 10 CONVEY, that would copy screens 1 thru 10 to screen 1 thru 10 in the new file. If HOPPED is set to 5, then the destination would be 6 through 15 (as HOPPED is added to each screen during the copy).
There's even a nice facility: 1 10 TO 5 CONVEY. Here, 'TO' is a bit of syntactic sugar to set HOPPED properly. This copies screen 1 10 to screen 5-14.
So, a copy session in the end would look like:
Code:
OPEN NEW.BLK
FROM OLD.BLK
1 10 TO 5 CONVEY
For my task, I need to break the original file up in to 2 pieces (the code, and the shadow screens) and relocate them to the new larger file. So, if NEW.BLK is 50 screens large, and OLD.BLK is 10 screens, I need to basically do:
Code:
OPEN NEW.BLK
FROM OLD.BLK
0 4 TO 0 CONVEY
5 9 TO 50 CONVEY
Then, if I 1 EDIT on NEW.BLK, and hit A, I'll get the proper shadow screen.
Turns out, as shown, none of that is automatable. Not readily. OPEN and FROM are immediate words, so you can't simply stick them in a colon definition. The word TO is also an immediate word that parses the 5 (in this case) out of the input stream. 1 and 10 are on the stack, but 5 is not. So, this also is not easily put in to a colon definition. What starts as a simple automation task, now becomes an advanced Forth exercise.
F83 has a word CAPACITY, which gives you the size of the current file. I need that to split the files in two. But CAPACITY doesn't work on the INPUT file (OLD.BLK in this case), only the current file. And CAPACITY only works with the global FILE variable. Thankfully, there's a SWITCH word to move these back and forth. Also, the word TO behaves differently from HOPPED. For: 5 9 TO 50 CONVEY, naively you'd think HOPPED would be set to 50. But that's not true, it's set to 45. Because we want 5 to become 50, and HOPPED is simply added during CONVEY.
In the end, I finally got CONVEY-FILE written.
Code:
OPEN NEW.BLK
FROM OLD.BLK
10 CONVEY-FILE
This would copy the code screens from OLD.BLK to starting at Screen 10 in NEW.BLK, and the Shadow screens to Screen 35.
This in all took about 2 hours to suss out, and now I get an I/O error when trying to load up the meta compiler from the monolithic file.
But what was interesting here was the fighting between words that are basically designed for interactive use and those used within other words. For example, perhaps it would have been better if CAPACITY were written as:
Code:
: CAPACITY FILE (CAPACITY) ;
: (CAPACITY) ( fcb - size in screens) ... ;
Then, perchance I could use (CAPACITY) in my code, rather than having to SWITCH back and forth between files. This goes to that cognitive load issue. "What file is current when I call CAPACITY?" Man, I tell ya, especially combined with the stack juggling, this little utility, which is, like 3-4 lines of code, boy was it an effort to type this stuff out.
A lot of that is practice, a lot of that is the nature of the F83 design in this case. The mixing of interactive commands and automating them. The premise that there is a difference between the two. (Lisp has different behaviors when LOADING and COMPILING, but they're less in your face as this is.) Some of that is F83 design choices, some of that is Forths nature to effectively allow such choices.
But all of that added up to being a bit of a struggle yesterday, for sure.