I use CL (this is my own programming language, that allows you to write and mix object oriented assembly and C) and fasm. I wrote the compiler in ANSI C, and I use gcc to compile it.
I did this because I really wanted to start from ground up (including the compiler, the ABI and the object/executable format). I choose fasm because it's fast, small, supports amd64 and incredibly easy to port. Nevertheless it has rich macro capabilities.
I'm pretty sure many of you wondering what's the source look like, here's an example:
Code: Select all
//tell the compiler that code blocks use fasm syntax
#codeblock "fasm"
import lib.stdio;
class app.helloworld{
int counter=0; //initialized class variable
//entry point and arguments, similar to C's
int main(string[] args)
{
.var string hello="Hello World!" //initialized variable in local stack frame
//some meaningless code in native assembly
xor rax, rax
//same as counter++
clbaseof rbx, app_helloworld.counter //rbx=&counter;
inc qword [rbx]
//say hello
clcall0 lib_stdio.printf, hello
//return a value
clret 0
}
}
- or -
import lib.stdio;
class app.helloworld {
int counter=0;
int main(){
string hello="Hello World!";
app.helloworld.counter++; //will not call object.int.inc(counter) because it's an inline method
lib.stdio.printf(hello);
return(0);
}
}
The compiler generates an intermediate assembly source file, that can be assembled with a macro assembler and the corresponding CL header file (that contains macros for machine independent mnemonics, like clbaseof or clret). Currently I have headers for fasm, nasm and gas.
CL has basic support for aspect paradigm, and supports operator overloading, dynamic linking, monitors (aka critical sections), randezvous points, class level polymorphism and multiple dispatch. It does not support (and never will) inheritance and virtual methods (you have virtual classes, you can't change one method in a class, only all methods at once if the old and new interface conforming).