ALPHA: breaking changes expected. What that means
NanoC

C preprocessing without braces

Preprocessor sigils emit directives for the C preprocessor; NanoC never evaluates their conditions. Indentation closes conditional chains with endif, with no C braces. A lone colon is exclusively a preprocessor else. Runtime else uses the word else.

NanoC
+ <stdio.h>
?+ _WIN32
  $ PLATFORM = "Windows"
:# defined(__linux__)
  $ PLATFORM = "Linux"
:
  $ PLATFORM = "Other"
f main()
  puts(PLATFORM)
  < 0
C
#include <stdio.h>
#ifdef _WIN32
#define PLATFORM "Windows"
#elif defined(__linux__)
#define PLATFORM "Linux"
#else
#define PLATFORM "Other"
#endif

int main(void) {
    puts(PLATFORM);
    return 0;
}
SyntaxC directive
?+ NAMEifdef NAME
?- NAMEifndef NAME
?# expressionif expression
:# expressionelif expression
:else in a preprocessor chain
Dedent after a chainendif
$ NAME = replacementdefine NAME replacement
$ NAME(args) = replacementFunction-like define; keep NAME and ( adjacent
$- NAMEundef NAME
+ <header.h> / + "local.h"include
!! "message"error; adjacent exclamation marks and a string literal
$! payloadpragma payload; support depends on the C compiler

Conditions can nest at file scope or inside functions, mixing with runtime blocks. Declarations may differ between configurations. Directive ordering, # stringification and ## token pasting are retained. Use raw C for multiline replacement lists, unusual include operands or configurations with different brace structure. Test each configuration you ship. NanoC expands macros and TT in every preprocessor branch, even ?# 0, before the C preprocessor runs. Use C macros for C-configuration-dependent definitions.