ALPHA: breaking changes expected. What that means
NanoC

Translate-time generation with @tt

@tt runs translate-time programs before C is emitted. Use dynamic values, functions, lists, strings, quote and emit, or transform source with rewrite and again. Native TT can read and write files, create directories, remove files, and execute host programs: run(argv[,cwd]) returns [status,stdout,stderr], exec(argv[,cwd]) returns stdout or fails, and sh(command) runs a shell. eval(read(path)) loads a TT library. The browser supports pure transformations and context information; host commands and filesystem operations require the native compiler.

NanoC
@tt
  f square(n) = n*n
  values:=[]
  for i range(4)
    values=push(values,str(square(i)))
  emit("static const int squares[]={"+join(values,",")+"};")
f main()
  < squares[3]!=9
C
static const int squares[]={0,1,4,9};

int main(void) {
    return squares[3]!=9;
}

The pipeline expands until stable. rewrite replaces source; again requests another cycle. Defaults bound steps, cycles, nesting and output. --max-steps 0 --max-passes 0 disables count limits. Native TT executes with the compiler process permissions. --check evaluates pure TT and rejects host writes or commands, including calls reached through eval or macros.

TT functionInformation
cycle()Current one-based expansion cycle
line()Source line of the TT call
file()Input file spelling
path()Resolved input path when available
name()Enclosing runtime function name, or empty at file scope
target()Selected C standard or c++17
NanoC
f answer i32
  @tt
    assert(name()=="answer")
    assert(cycle()>=1)
    log(file()+":"+str(line()))
  42
f main
  answer()!=42
C
int answer(void) {
    return 42;
}

int main(void) {
    return answer()!=42;
}