One of my major tasks at work at the moment is writing a BSP (Board Support Package - a set of drivers) for the Freescale MPC55xx processor. The catch - it's being written in Ada, because this is the language our micro-controller programs are written in (ah, defense industry...).
Freescale supplies a set of C header files that define the memory mapped registers, as follows:
} MCR; /* Module Configuration Register */
Basically, this is a memory-mapped struct. When I tell the compiler that some pointer points to it, I can then access the register's bits through the struct.
In Ada, this is done differently, and there's a lot of code that needs to be translated, quite mechanically. The
header file is over 3000 lines long. And I really hate mechanic work, really really hate it. I prefer to spend 2 hours writing a script that will solve me 1 hour of nasty work.
After much looking around, I finally settled on using Perl's Parse::RecDescent module. I've had some experience with it before, and managed to craft a script that parses a small subset of C - these struct/union declarations, and spits out the corresponding Ada code. It took me a few hours and I had lots of fun, which is important :-)
Later at home, I run across some interesting tools that can help with this even further. For example
- a program that reads C source code, analyzes and type-checks it, builds an AST and spits out C code from this AST. The cool thing is that you can ask it to just leave the AST and print it out.
It was the usual nightmare of compiling Unix-y stuff on Windows, but I managed it. MinGW really helps, because it's very much GCC compatible.
Another interesting tool is TCC - tiny C compiler. A fully functional, C99 compatible compiler with open source code.