Emit pragma

The emit pragma can be used to directly affect the output of the compiler’s code generator. The code is then unportable to other code generators/backends. Its usage is highly discouraged! However, it can be extremely useful for interfacing with C++ or Objective C code.

Example:

  1. {.emit: """
  2. static int cvariable = 420;
  3. """.}
  4. {.push stackTrace:off.}
  5. proc embedsC() =
  6. var nimVar = 89
  7. # access Nim symbols within an emit section outside of string literals:
  8. {.emit: ["""fprintf(stdout, "%d\n", cvariable + (int)""", nimVar, ");"].}
  9. {.pop.}
  10. embedsC()

nimbase.h defines NIM_EXTERNC C macro that can be used for extern “C” code to work with both nim c and nim cpp, eg:

  1. proc foobar() {.importc:"$1".}
  2. {.emit: """
  3. #include <stdio.h>
  4. NIM_EXTERNC
  5. void fun(){}
  6. """.}

For backwards compatibility, if the argument to the emit statement is a single string literal, Nim symbols can be referred to via backticks. This usage is however deprecated.

For a toplevel emit statement the section where in the generated C/C++ file the code should be emitted can be influenced via the prefixes /*TYPESECTION*/ or /*VARSECTION*/ or /*INCLUDESECTION*/:

  1. {.emit: """/*TYPESECTION*/
  2. struct Vector3 {
  3. public:
  4. Vector3(): x(5) {}
  5. Vector3(float x_): x(x_) {}
  6. float x;
  7. };
  8. """.}
  9. type Vector3 {.importcpp: "Vector3", nodecl} = object
  10. x: cfloat
  11. proc constructVector3(a: cfloat): Vector3 {.importcpp: "Vector3(@)", nodecl}