Rosy Retrocomputing|Hackaday
Most people are guilty of glamorizing the past. Do you long to be the captain of a high ship? Just as long as you do not mind weevils in your food, vitamin shortages, and death from an infection when there were no prescription antibiotics. Want to be a middle ages knight? Even even worse. But undoubtedly, retrocomputing is as enjoyable as we keep in mind, ideal? Turn your computer system on, and it develops BASIC! Ready for you to compose your own programs. None of this GUI absurdity. Of course, this is simply another example of rosy revision.
Even if you like BASIC or a comparable language today, things have actually altered. You have a great full-screen editor, a quick computer system, debugging tools, together with things like called functions, no line numbers, and modern-day control structures. None of those things were extremely typical in the 1980s. At least, not on a hobby-grade computer system.
Why am I considering this? Well, the Hackaday Retrocomputing Challenge is on, and it struck me that I wished to deal with some young trainees in marvelous MBASIC on aCP/M machine I built and modified from a Hackaday project Perfect, right? Many people began that method, so why should not they?
But it rapidly got old. Even a basic program gets slowed down with GOTOs and GOSUBs to mystical line numbers. It made me keep in mind the time back in the early 1980s, or perhaps even the late 1970s, that I composed a BASIC preprocessor to scan BASIC without any line numbers and produce appropriate source, transforming labels to line numbers in 2 passes.
Of course, that code is long gone or, a minimum of, on a floppy I have not attempted to check out in a couple of years. I chose to take another fracture at it 6 years back, however I still didn’t make it a lot more robust. For example:
PRINT: X= X +10
Is that 2 declarations? Or a label? Hard to inform. My 2020 variation utilized awk. Awk is terrific for this example since of the routine expressions and the input loop. But it still has some concerns with things like remarks and strings. Consider the code listed below.
PRINT "HELLO: IS IT ME YOU'RE SEARCHING FOR?"
This would most likely have actually made my awk preprocessor chew the string up and produce a phony label called HELLO.
History of Preprocessors
Preprocessing one language to another is absolutely nothing brand-new. RATFOR and RATFIV by Brian Kernighan transformed modern-day constructs to traditional FORTRAN IV. Even C++ began as a program that released C code.
So the concept is great, however there are lots of corner cases. As I prepared for having another address the concept for BASIC, I recognized my earlier variations had some style options that made it more difficult than it ought to have been. So I went back to square one.

First, I quit the concept of simply having labels as you may in other languages. Instead, they ‘d belong to a remark and difficult to error. This produces simpler parsing and likewise enables you to keep them around for referral. I likewise quit on having labels amazingly broaden. You require a method to make them special, too. Here’s what I chose:
': TOPLABEL. GOTO @TOPLABEL
The strategy was to go through the source as soon as to appoint line numbers. When a label happens, it contributes to the sign table. Then a 2nd pass really composes output, changing @TOPLABEL with the worth from the sign table. Of course, you still desire this line to not activate a label growth:
PRINT "Send messages to @JTKIRK"
I chose to keep entering awk, however my ultimate objective was to reword the entire thing in BASIC utilizing the exact same syntax. Then you might transform the translator itself utilizing the awk variation as soon as and after that run it on an old computer system utilizing BASIC, even if you wished to retranslate the translator itself. Perverse, huh? But that enables you to keep that genuine advancement experience. You do not need to leap over to a PC to process your code, unless you simply wish to.
Awk as in Awkward
So I chose to do a much better task on the awk part with this brand-new plan. At some point, however, you lose a few of the benefits. Then function creep embeded in.
I expect I was unconsciously keeping in mind RATFOR. I chose to include a little number of modern-day control structures. Again, I desired something simple to select of the source file, so I chose this:
IF X= 0 THEN!
PRINT “There is no X!”
X= 10
ENDIF!
There’s likewise WHILE!, DO!, EXIT!, and CONTINUE!
Of course, it didn’t end there. I chose to include a method to consist of or omit parts of the source (sort of like #if in C however easier), together with source code addition and a couple of other cool alternatives such as numerical constants, conditional source blocks, compile-time mistakes, and even a little numerical stack with PUSH! and POP!.
The source code addition can be made to deal with awk, however it is awful. I chose it was much better to continue with another language, however because I didn’t seem like beginning over, I simply had an LLM transform my awk to Python, which it made with no difficulty at all. I then did a bit more function advancement in Python, however I ensured not to utilize those brand-new functions in the translator itself so the awk variation might still process an input file.
So while the initial strategy was to establish and evaluate in awk and after that carry out comparable code in MBASIC, I now had 3 variations: a frozen awk script, a Python variation, and an MBASIC variation.
This was getting a bit much to test. I had the LLM formulate some documents, extra remarks, and tests. It was particularly good to confirm that all 3 variations– awk, Python, and BASIC– did the exact same things for their typical functions. The LLM was proficient at running tests and discovering corner cases. It would even run tests in a RunCPM session on the MBASIC variation.
BASIC
As you may anticipate, the BASIC variation is a bit more complicated. However, making use of labels and control structures makes it a lot easier to compose, check out, and preserve.
Writing the translator in MBASIC enforced some extremely old-fashioned restrictions. There are no dictionaries or vibrant lists, so labels and obstruct state reside in fixed-size ranges. Included files need a clearly handled stack, and parsing strings and remarks needs to be done character by character. It is not as compact as the Python variation, however it is normal MBASIC and can operate on the target CP/M device. The constraints likewise affected some functions that would have been practical in Python however are almost difficult in an MBASIC program.
Better yet, lblbasic.bal remains within the subset the initial awk translator comprehended. That offers a bootstrap course: awk produces the very first lblbas.bas, after which the MBASIC translator can process its own BAL source.
A Few Samples
One task I wanted was to drive an LED display screen module. I composed a library and after that composed the test program listed below. It does not matter, however I utilized bal as a file extension.
RAPID EYE MOVEMENT TM1637 TEST– PORT 3, BIT 2= DIO, BIT 3= CLK
RAPID EYE MOVEMENT Uses the TM1637.BAL library with LBLBASIC
STACK! 8′ Required by the library
‘ Confirm that the library protects I while initializing its information table.
I= 3141
gosub @init
print “I is now:”; I
PRINT “Starting number: “;
INPUT CT
PRINT “1-Up, 0-Down: “;
INPUT UD
OFFSET= -1
IF UD<>< > 0 THEN OFFSET= 1
‘: CDLOOP
WHILE! CT>>= 0 and CT< 0 THEN OFFSET= 1
110 ‘: CDLOOP
120 IF CT>>= 0 and CT<

