Monday, August 30, 2010

Self compiling!


I am pleased to say that bmx2 (STILL haven't decided on a new name yet) is now fully self-compiling!

In theory, this just involved converting the existing bmx source files to bmx2 via a little 'convbmx' util, but in practice it has been a tricky and at times somewhat mind bending exercise.

In particular, with 2 sets of sources I had to stop and think several times which one I actually needed to modify - and occasionally even found myself modifying the wrong one!

But it all seems to be working remarkably well now, and although I've only managed to compile the compiler itself as a C++ target (because that's the only target with sufficient filesystem support right now), the 'new' compiler has compiled all my other little tests successfully to html5, flash, xna and android.

Some more details about how it all works...

Bmx2 will required that the appropriate SDK's for the various targets be installed separately. For example, to compile to c++ you'll need MinGW installed. Current list of supported targets/SDK's is:

* HTML5 - HTML5 compatible browser required for testing.
* Flash - Open source Flex SDK required.
* XNA - Visual C# Express + XNA framework
* Android - The Android SDK (plus Java SDK and 'Ant' on Windows).
* Native (ie: C++) - Mingw/GCC (will probably add visualc support too in future).
* iPhone - XCode.

This has the obvious benefit of making life a whole bunch easier for myself, but it also means you'll be able to take full advantage of the various SDK tools available. For example, iPhone projects will be 'real' xcode projects, so you'll be able to edit them in xcode, mess with the NIB file etc. When you compile your bmx2 program, the translator simply replaces a chunk of text in a 'main' file somewhere in the target project, and leaves the rest of the project alone.

Installation of SDK's can be a little messy in some cases, but the compiler already automagically deals with any PATH or ENV var issues which makes life a whole lot easier.

Some more details on the new language:

* 'Type' renamed to 'Class'.

* Identifiers now case sensitive.

* Private can at last be used inside classes!

* A single 'End' can be used to terminate blocks, eg:

Function MyFunc()
Print "Boo!"

Ye olde bmx1 style terminators are still permitted too.

* Function/method overloading added, eg:

Function DrawImage( image:Image,x,y )

Function DrawImage( image:Image,x,y,frame )

* 'Proper' constructors, eg:

Method New( x,y )

* Support for 'properties', eg:

Method X() Property
Return x

Method X( x ) property

* Simple class template support, eg:

Local list:=New List<Actor>

* Simple 'boxing', eg:

Local list:=New List<IntObject>
list.AddLast 10
list.AddLast 20
Local n=list.Last()

* Auto type inference for initializers, eg:

Local t:=New Actor 'instead of Local t:Actor=New Actor

* Strict mode is back, but will effectively mean bmx1-style SuperStrict (or possibly even stricter). Default mode will be plain bmx1-style Strict (and probably even lazier).

I agonized for a while over whether bmx2 should go 'SuperStrict only', but after realizing that some of the superstrict crowd wanted things even stricter(!) while I wanted things more relaxed, I decided to keep Strict in there in the hope the final product will appeal to a wider range of people.

I have a related theory on this: SuperStrict users prefer C# over C++; Strict users vice versa...

* Module 'Imports' can now be cyclic, eg:

'Module A
Import B

'Module B
Import A

I can't BELIEVE I thought this wasn't a big deal in bmx1!

It was kind of mission to get going too - I basically had to change the compilation process from a top down, 2 pass algorithm to a 'compile on demand' one.

It worked out really well though - the entire program is compiled simply by compiling 'Main'...which causes anything main depends on to compile, and so on.

As a nice side effect, you end up with a very clear picture of what code the program actually uses, meaning apps should be nice and tight.

It's not all good news though (assuming you already though it was) - here are a few nasty 'detail' things that may or may not be fixed/improved over time, but for now would be very hard to do efficiently in ALL target languages. I consider them pretty minor, but you're free to disagree with me on that...

* Strings and Arrays are NOT objects in bmx2 the way they are in bmx1 - they are more like primitives such as int and float, eg:

Local t:Object="Hello world" 'OK in bmx1, Error in bmx2.

* Multidimensional arrays are out, although you can still have arrays of arrays, eg:

Local t[10,20] 'OK in bmx1, Error in bmx2
Local t[][10] 'OK in bmx1 and bmx2.

* Arrays can not be 'downcast' in bmx2, eg:

Local t:Object[]=New Thing[10]
Local p:Thing[]=Thing[]( t ) 'OK in bmx1, Error in bmx2.

This will mean that arrays may have to be manually 'wrapped' in some situations.

And that's it for now. Hope you found it informative!