Conditional Compilation

Note: Feature is as of yet TBD.

Syntax isn’t finalized, but there are a few main options.

The first is to have the lexer handle it, in a syntax (but not semantics) similar to the C preprocessor. Note that this is not a preprocessor, and especially not a C one. For example, conditional compilation is based on actual variables, and is not an arbitrary text/token replacement system. Likewise, function macros will not be supported, allowing a single pass over the entire source. I believe C# uses a similar system?

#if OS.Windows >= v`6.0`	// 6.0 is Vista
import windows.foo;
#else
import posix.bar;
#endif
// note that unlike a C preprocessor, this does *not* affect the rest of the code:
var x = OS;	// ERROR: variable `OS` does not exist
var y = debug.defines["OS"];	// if we really want it (e.g. for debugging), we can access it (exact module TBD)

A second approach is to instead do it in the parser. Note that this implies that even the “non-compiled” path must parse successfully — which removes the possibility of using this approach for syntactic extensions (not the worst downside ever, though).

// note: does not create a new scope (unlike e.g. `if`)
version(OS.Windows >= v`6.0`)
    import windows.foo;
else
    import posix.bar;

A third option, which is also the most powerful one, would be a system that allowed arbitrary compile-time execution. It does, however, create a chicken-and-egg problem with imports (needing separate imports for compile-time) and further complicates matters. In the example, compile-time statements are prefixed with # (but could use some different syntax):

#import platform.os;
#if(OS == "Windows" && OS.version >= v`6.0`)
	module.imports.add("windows.foo");
#else
	module.imports.add("posix.bar");

// using compile-time execution to generate a lookup table
ubyte[] CRCLookupTable = #generateCRC8Lookup();