Now you can peek at the horrible horrible code I've hacked upon this past week, at
For today I want to add floats to the mix, right now it can only evaluate ints. And I have 2 ways of doing it:
1. Make the base value of the VM a tagged union so that every values carries runtime type info with it so that ops like ADD or MUL can check what the common denominator type is and coerce before executing the operation.
This means dynamic typing, for now; but when I eventually start writing a syntax tree and doing types anyway, I will have a head-start on the `var` type.
2. Generate an actual syntax tree that can be walked in order to resolve at compile time which coercions need to be done at which point and just emit bytecode that does it.
This also means that after adding ops that do int->float and float->int I can keep all of my other ops clean, specialized and devoid of dynamic guesswork.
I'll probably go with #2.
Took me the whole week but I finally added floats.
This was a biggie because I added a new pass to the backend. After parser, the syntax tree goes through the type checker, which deduces what type each and every expression has. This includes intermediate ones:
For example:
300 / 9 + 60 * 2
is checked as:
(+::float
(/:: float
300::int
9::int)
(*::int
60::int
2::int))
And yes, 300 / 9 comes out as a float, I also snuck in integer dvision as //
The other big change was in the VM, now we obviously have operations to handle floats, but, we also need conversion operations.
Ops expect their inputs to be of certain types. For example 10 + 3.0 requires that 10 is promoted to a float in order to execute ADD_FLOAT.
Here's the same example from the previous post, 300 / 9 + 60 * 2, being compiled and run:
@trickster Quantum computer invented. Gotta notify the scientists.
@pony I don't even have the excuse of making weird purchases in that weird state of consciousness you have when taking sedatives before sleep. I bought them all sober.
@u damn, you got me there
This is some bayes shite.