Apologies for the silence, but I’ve been busy cleaning up and finalizing 1001 ‘little things’ I have encountered while converting the compiler to ‘pure’ mx2.
It hasn’t been very exciting stuff but the end result is that the compiler – which is indeed now pure mx2! – is a LOT more solid than the last version. It picks up a lot more errors than it used to (stuff that used to just break at the c++ compile stage) and hopefully reports them in a more useful way.
There are also a few additions that, while they seem outwardly sensible and ‘easy’ – were in fact quite tricky to implement. This includes stuff like allowing you to use assignment operators such as += etc with a class that only provides an operator+ (you *can* provide +=, but if you don’t mx2 will generate one for you), being able to use += etc with properties and operator=, and several other similarly helpful shortcuts.
A lot of this is stuff that c++ and (I think) c# don’t allow, but they’re the kind of thing that, when you’re learning about operator/assignment overloading (well, when I was anyway) you often wonder why the compiler doesn’t help out a bit more. So mx2 does!
I have also finalized how objects/values are compared, and how comparison operators work. I did have this ‘sort of’ working in the last version but, like many things, kind of just got it working and moved on to the next thing, vaguely aware there were holes in it.
Anyway, the system I have settled on works like this:
- Any object/value can be compared with another object/value of a common type, using any comparison operator.
- There is a new operator ‘<=>’ that returns an int value <0, 0 or >0 depending on the ordering of 2 objects/values.
- In the case of objects, ‘=’ and ‘<>’ works as they do in monkey1 (ie: instances are compared) while ‘<‘, ‘>’ etc will effectively give you an arbitrary but consistent order (yes, pointers are compared!). This is a bit naughty, but I find it too useful to be able to throw together maps/sets etc of any object type to leave out. And in general, it just massively simplifies a lot of stuff to be able to compare anything.
- In the case of structs, ‘<=>’ is implemented by using ‘<=>’ on all members of the 2 values and returning the first non-zero result (or 0 if all member comparisons return 0). Again, this is kind of arbitrary, but consistent so you can stick anything in a map/set etc.
- You can overload any of the comparison operators including ‘<=>’. If you overload ‘<=>’, you don’t have to overload any other comparison operator (although you can) as the compiler will generate code using ‘<=>’ for you.
Note that, like all operators, comparison operators are ‘statically typed’. This means that if you create an object of a class with custom operators, and assign it to a plain ‘Object’ variable, the operator is effectively lost as the compiler can only see a plain object. However, operators can still be virtual (or not).
I also spent a fair amount of time speeding up the whole build process. The real killer here currently is c++ compile times, so the new mx2 translator tries much harder than old mx2 did to #include as little as possible. A lot of translated files now just start with a bunch of simple ‘forward type declarations’ where the old files would have used #include. This reduces dependencies so modifying one file has less of a knock on effect on other files.
Other tweaks include: massively improved overload resolution algorithm; support for invoking generic methods declared in an external module (never worked!); support for ‘generic generic parameters’ (WIP!); full support for all numeric types; addition of native CString, WString and Utf8String types for use with external APIs.
I plan to release new mx2 as a ‘language only’ release sometime this week, probably via github (finally!).
This wont be of much interest in people wanting to write apps, but I’ll be getting back into that side of things soon so please be patient. People who are interested in stress testing the language side of things though, please check it out!