I've put some thought into macros into my various cross-assemblers. One thing that's important is to have different types of macros, and different types of argument values (some that are evaluated for you, some that are intentionally not evaluated.)
macro function square(integer value) {
return value * value;
}
integer x = square(foo() + bar()); //foo() and bar() each only called once
//square(integer) will exist as an exported function symbol
macro inline twice(statement operation) {
operation;
operation;
}
twice(foo()); //invokes foo() two times
//twice() will not generate an actual function
macro class vector(type T) {
T* pool;
integer capacity;
integer size;
function append(type U) { ... }
...
}
vector(integer) powersOfTwo{2, 4, 8, 16, 32, 64};
//any vector(type) will generate all the class functions for it
> I think if you emit C code, it is much harder to get good debug information, which is important.
I think you can annotate the generated code with certain preprocessor instructions to tell the compiler about the real source lines in order to get proper debug information. I think lex/yacc or flex/bison use that. Don't know if it's a gcc extension.
I think if you emit C code, it is much harder to get good debug information, which is important.
I am also thinking hard how to approach macros/preprocessor. For now there is none, but a powerful system could make all the difference.