Let's build a transpiler! Part 53
This is the fifty-third post in a series of building a transpiler.You can find the previous ones here.
Seven scientific facts that I find baffling
-
Even though nothing in our universe can move faster than the speed of light, our universe is expanding faster than it.
Or something like that. See explanation here and here.
-
We know that nothing can escape the gravitational pull of a black hole, not even light, but its reach does not go beyond the one the original star had before collapsing.
Take a look at the sixth question here to understand what I mean.
-
It is widely accepted that an asteroid collision killed the dinosaurs, but this was not the only mass extinction event on Earth.
There were four more.
-
Have you ever seen an image of a galaxy with a little red arrow pointing to one of its edges saying "You are here?"
How can we know how our galaxy looks from the outside if no human or machine has ever left the Milk Way? The answer is, "we don't."
It's an extrapolation from what we can see from other galaxies.
-
If one releases a feather and a bowling ball in a vacuum, which one hits the ground first?
Watch this experiment to learn the answer.
-
OK, the experiment above was made in a vacuum chamber. What about a different one in normal conditions?
Suppose there are two bullets. One is held at a certain height, and the other is inside a gun that's held as high as the first one.
The gun is aimed at the horizon, in a plain landscape. The gun is fired at the same time the second bullet is released. Which one hits the floor first?
Spoilers: They don't get there at the same time.
-
The Earth is round. Well, actualy, more of an oblate spheroid, but, really, folks. It is round.
Back to business
Last time I said I would be back to our transpiler. Actually, I did quite a few things with the source code. Here are the main points:-
I've converted the sources to TypeScript. It took me around a week working on the code, and I had to resort to a few workarounds.
I got two things from this experience:
- First, it helped me find a few bugs that were fixed.
- Second, I realized I take nullability too much for granted. In TypeScript, null is a different type.
That was kinda an eye-opener.
- First, it helped me find a few bugs that were fixed.
-
I split our transpiler into two projects. One is the parser, the other is the converter/transpiler.
Due to the numerous changes I did on them, I'll "dump" the parser project today.
-
As we have now two projects, I had to create a Statics class, where I expose some objects from the parser project to the transpiler project,
like the v Vocabulary and m Messages objects.
At this point in my life, I'm still learning things from VB. I learned the hard way that nothing inside a module is made available to the outside world.
Whatever is there and is needed should be moved to a class.
-
To not have to spell Statics' name all the time, I made it a GlobalMultiUse class, meaning its methods are available globally in the transpiler project.
If you read my 2021-08-11 post, it is an Omni class.
(I'm not supporting this keyword yet, though.)
-
While previously I was generating _basic.h header file programmatically, now it is done manually. I think this makes things clearer.
And, by the way, it is called Foundation.h now.
-
In my post of 2021-04-21 I said that if any non-set property would give me a hard time, I would apply the null object pattern.
Well, there were some, so I created a NullProject variable and a NullMethod object.
Nuff said!
-
Another thing I grew to dislike was my pre-processing of contextual keywords. It is a convoluted mess, so I tried a different approach.
They start as regular identifiers now and are promoted to keywords as needed.
It mostly worked, the "problem guys" were Lock, Name, Width, and Reset.
In a future post, I'll detail what were my limitations in identifying them.
-
Back in 2021-07-14, I said I did not know how to deal with the Any data type.
The best way I've found was to mark some classes and modules as being "standard libs" and allow the use o Any inside them, and only inside them.
It's a half-baked solution, but, oh well...
-
On a related note, I mentioned in my post of 2021-03-24 that I did not like LHS Expression member being null/Nothing.
I still don't, so I created a PlaceHolder class and I'm using it there.
-
GetExpression failed me one more time, and one more time I had to fix it.
It morphed from one method to four: GetExpression, AcceptOperand, AcceptOperator, and FixToken.
Oh, my! Will it ever end? VB expressions are hard...
-
I finally scratched an old itch I had. When I wrote ReadDate, I choose to make it raise an error in certain circumstances.
The problem is, the error was meant to be final, aborting the program.
When I reused it in ReadHash, I was unsure if I would lose some token when using On Error Resume Next, as the object's state could be messed up.
To prevent that, IEncoderReaders are "transactional" now. Before reading a date, we start a "transaction". If things go bad, we'll roll back the "transaction", that is, we'll jump back to the same file reading position we were before the transaction.
-
Finally, I renamed and moved several things.
My current host does not allow uploading .ZIP files, but thanks to this project, I can upload text files and you can download them zipped.
Enjoy!
Andrej Biasic
2022-01-12