diff options
author | Araq <rumpf_a@web.de> | 2015-08-14 02:18:12 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-08-14 02:19:34 +0200 |
commit | 134c44f3be373a94fd5ee144d98cd296ee967107 (patch) | |
tree | a70b53ccadcb1e5239d8745a75a278e269bc5ddd /doc | |
parent | dd0acfdf375b45a226f44feb4f04aef2c0aa0ac3 (diff) | |
download | Nim-134c44f3be373a94fd5ee144d98cd296ee967107.tar.gz |
refs #2973; manual contains almost all pragmas now, few are left in the compiler guide
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual/pragmas.txt | 464 | ||||
-rw-r--r-- | doc/nimc.txt | 457 |
2 files changed, 464 insertions, 457 deletions
diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index 51125f576..8166994a9 100644 --- a/doc/manual/pragmas.txt +++ b/doc/manual/pragmas.txt @@ -511,3 +511,467 @@ Example: add "foo" add "bar" + +Implementation Specific Pragmas +=============================== + +This section describes additional pragmas that the current Nim implementation +supports but which should not be seen as part of the language specification. + + +Volatile pragma +--------------- +The ``volatile`` pragma is for variables only. It declares the variable as +``volatile``, whatever that means in C/C++ (its semantics are not well defined +in C/C++). + +**Note**: This pragma will not exist for the LLVM backend. + + +NoDecl pragma +------------- +The ``noDecl`` pragma can be applied to almost any symbol (variable, proc, +type, etc.) and is sometimes useful for interoperability with C: +It tells Nim that it should not generate a declaration for the symbol in +the C code. For example: + +.. code-block:: Nim + var + EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as + # Nim does not know its value + +However, the ``header`` pragma is often the better alternative. + +**Note**: This will not work for the LLVM backend. + + +Header pragma +------------- +The ``header`` pragma is very similar to the ``noDecl`` pragma: It can be +applied to almost any symbol and specifies that it should not be declared +and instead the generated code should contain an ``#include``: + +.. code-block:: Nim + type + PFile {.importc: "FILE*", header: "<stdio.h>".} = distinct pointer + # import C's FILE* type; Nim will treat it as a new pointer type + +The ``header`` pragma always expects a string constant. The string contant +contains the header file: As usual for C, a system header file is enclosed +in angle brackets: ``<>``. If no angle brackets are given, Nim +encloses the header file in ``""`` in the generated C code. + +**Note**: This will not work for the LLVM backend. + + +IncompleteStruct pragma +----------------------- +The ``incompleteStruct`` pragma tells the compiler to not use the +underlying C ``struct`` in a ``sizeof`` expression: + +.. code-block:: Nim + type + DIR* {.importc: "DIR", header: "<dirent.h>", + final, pure, incompleteStruct.} = object + + +Compile pragma +-------------- +The ``compile`` pragma can be used to compile and link a C/C++ source file +with the project: + +.. code-block:: Nim + {.compile: "myfile.cpp".} + +**Note**: Nim computes a SHA1 checksum and only recompiles the file if it +has changed. You can use the ``-f`` command line option to force recompilation +of the file. + + +Link pragma +----------- +The ``link`` pragma can be used to link an additional file with the project: + +.. code-block:: Nim + {.link: "myfile.o".} + + +PassC pragma +------------ +The ``passC`` pragma can be used to pass additional parameters to the C +compiler like you would using the commandline switch ``--passC``: + +.. code-block:: Nim + {.passC: "-Wall -Werror".} + +Note that you can use ``gorge`` from the `system module <system.html>`_ to +embed parameters from an external command at compile time: + +.. code-block:: Nim + {.passC: gorge("pkg-config --cflags sdl").} + +PassL pragma +------------ +The ``passL`` pragma can be used to pass additional parameters to the linker +like you would using the commandline switch ``--passL``: + +.. code-block:: Nim + {.passL: "-lSDLmain -lSDL".} + +Note that you can use ``gorge`` from the `system module <system.html>`_ to +embed parameters from an external command at compile time: + +.. code-block:: Nim + {.passL: gorge("pkg-config --libs sdl").} + + +Emit pragma +----------- +The ``emit`` pragma can be used to directly affect the output of the +compiler's code generator. So it makes your code unportable to other code +generators/backends. Its usage is highly discouraged! However, it can be +extremely useful for interfacing with `C++`:idx: or `Objective C`:idx: code. + +Example: + +.. code-block:: Nim + {.emit: """ + static int cvariable = 420; + """.} + + {.push stackTrace:off.} + proc embedsC() = + var nimVar = 89 + # use backticks to access Nim symbols within an emit section: + {.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimVar`);""".} + {.pop.} + + embedsC() + +As can be seen from the example, to Nim symbols can be referred via backticks. +Use two backticks to produce a single verbatim backtick. + +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*/``: + +.. code-block:: Nim + {.emit: """/*TYPESECTION*/ + struct Vector3 { + public: + Vector3(): x(5) {} + Vector3(float x_): x(x_) {} + float x; + }; + """.} + + type Vector3 {.importcpp: "Vector3", nodecl} = object + x: cfloat + + proc constructVector3(a: cfloat): Vector3 {.importcpp: "Vector3(@)", nodecl} + + +ImportCpp pragma +---------------- + +**Note**: `c2nim <c2nim.html>`_ can parse a large subset of C++ and knows +about the ``importcpp`` pragma pattern language. It is not necessary +to know all the details described here. + + +Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the +``importcpp`` pragma can be used to import `C++`:idx: methods or C++ symbols +in general. The generated code then uses the C++ method calling +syntax: ``obj->method(arg)``. In combination with the ``header`` and ``emit`` +pragmas this allows *sloppy* interfacing with libraries written in C++: + +.. code-block:: Nim + # Horrible example of how to interface with a C++ engine ... ;-) + + {.link: "/usr/lib/libIrrlicht.so".} + + {.emit: """ + using namespace irr; + using namespace core; + using namespace scene; + using namespace video; + using namespace io; + using namespace gui; + """.} + + const + irr = "<irrlicht/irrlicht.h>" + + type + IrrlichtDeviceObj {.final, header: irr, + importcpp: "IrrlichtDevice".} = object + IrrlichtDevice = ptr IrrlichtDeviceObj + + proc createDevice(): IrrlichtDevice {. + header: irr, importcpp: "createDevice(@)".} + proc run(device: IrrlichtDevice): bool {. + header: irr, importcpp: "#.run(@)".} + +The compiler needs to be told to generate C++ (command ``cpp``) for +this to work. The conditional symbol ``cpp`` is defined when the compiler +emits C++ code. + + +Namespaces +~~~~~~~~~~ + +The *sloppy interfacing* example uses ``.emit`` to produce ``using namespace`` +declarations. It is usually much better to instead refer to the imported name +via the ``namespace::identifier`` notation: + +.. code-block:: nim + type + IrrlichtDeviceObj {.final, header: irr, + importcpp: "irr::IrrlichtDevice".} = object + + +Importcpp for enums +~~~~~~~~~~~~~~~~~~~ + +When ``importcpp`` is applied to an enum type the numerical enum values are +annotated with the C++ enum type, like in this example: ``((TheCppEnum)(3))``. +(This turned out to be the simplest way to implement it.) + + +Importcpp for procs +~~~~~~~~~~~~~~~~~~~ + +Note that the ``importcpp`` variant for procs uses a somewhat cryptic pattern +language for maximum flexibility: + +- A hash ``#`` symbol is replaced by the first or next argument. +- A dot following the hash ``#.`` indicates that the call should use C++'s dot + or arrow notation. +- An at symbol ``@`` is replaced by the remaining arguments, separated by + commas. + +For example: + +.. code-block:: nim + proc cppMethod(this: CppObj, a, b, c: cint) {.importcpp: "#.CppMethod(@)".} + var x: ptr CppObj + cppMethod(x[], 1, 2, 3) + +Produces: + +.. code-block:: C + x->CppMethod(1, 2, 3) + +As a special rule to keep backwards compatibility with older versions of the +``importcpp`` pragma, if there is no special pattern +character (any of ``# ' @``) at all, C++'s +dot or arrow notation is assumed, so the above example can also be written as: + +.. code-block:: nim + proc cppMethod(this: CppObj, a, b, c: cint) {.importcpp: "CppMethod".} + +Note that the pattern language naturally also covers C++'s operator overloading +capabilities: + +.. code-block:: nim + proc vectorAddition(a, b: Vec3): Vec3 {.importcpp: "# + #".} + proc dictLookup(a: Dict, k: Key): Value {.importcpp: "#[#]".} + + +- An apostrophe ``'`` followed by an integer ``i`` in the range 0..9 + is replaced by the i'th parameter *type*. The 0th position is the result + type. This can be used to pass types to C++ function templates. Between + the ``'`` and the digit an asterisk can be used to get to the base type + of the type. (So it "takes away a star" from the type; ``T*`` becomes ``T``.) + Two stars can be used to get to the element type of the element type etc. + +For example: + +.. code-block:: nim + + type Input {.importcpp: "System::Input".} = object + proc getSubsystem*[T](): ptr T {.importcpp: "SystemManager::getSubsystem<'*0>()", nodecl.} + + let x: ptr Input = getSubsystem[Input]() + +Produces: + +.. code-block:: C + x = SystemManager::getSubsystem<System::Input>() + + +- ``#@`` is a special case to support a ``cnew`` operation. It is required so + that the call expression is inlined directly, without going through a + temporary location. This is only required to circumvent a limitation of the + current code generator. + +For example C++'s ``new`` operator can be "imported" like this: + +.. code-block:: nim + proc cnew*[T](x: T): ptr T {.importcpp: "(new '*0#@)", nodecl.} + + # constructor of 'Foo': + proc constructFoo(a, b: cint): Foo {.importcpp: "Foo(@)".} + + let x = cnew constructFoo(3, 4) + +Produces: + +.. code-block:: C + x = new Foo(3, 4) + +However, depending on the use case ``new Foo`` can also be wrapped like this +instead: + +.. code-block:: nim + proc newFoo(a, b: cint): ptr Foo {.importcpp: "new Foo(@)".} + + let x = newFoo(3, 4) + + +Wrapping constructors +~~~~~~~~~~~~~~~~~~~~~ + +Sometimes a C++ class has a private copy constructor and so code like +``Class c = Class(1,2);`` must not be generated but instead ``Class c(1,2);``. +For this purpose the Nim proc that wraps a C++ constructor needs to be +annotated with the `constructor`:idx: pragma. This pragma also helps to generate +faster C++ code since construction then doesn't invoke the copy constructor: + +.. code-block:: nim + # a better constructor of 'Foo': + proc constructFoo(a, b: cint): Foo {.importcpp: "Foo(@)", constructor.} + + +Wrapping destructors +~~~~~~~~~~~~~~~~~~~~ + +Since Nim generates C++ directly, any destructor is called implicitly by the +C++ compiler at the scope exits. This means that often one can get away with +not wrapping the destructor at all! However when it needs to be invoked +explicitly, it needs to be wrapped. But the pattern language already provides +everything that is required for that: + +.. code-block:: nim + proc destroyFoo(this: var Foo) {.importcpp: "#.~Foo()".} + + +Importcpp for objects +~~~~~~~~~~~~~~~~~~~~~ + +Generic ``importcpp``'ed objects are mapped to C++ templates. This means that +you can import C++'s templates rather easily without the need for a pattern +language for object types: + +.. code-block:: nim + type + StdMap {.importcpp: "std::map", header: "<map>".} [K, V] = object + proc `[]=`[K, V](this: var StdMap[K, V]; key: K; val: V) {. + importcpp: "#[#] = #", header: "<map>".} + + var x: StdMap[cint, cdouble] + x[6] = 91.4 + + +Produces: + +.. code-block:: C + std::map<int, double> x; + x[6] = 91.4; + + +- If more precise control is needed, the apostrophe ``'`` can be used in the + supplied pattern to denote the concrete type parameters of the generic type. + See the usage of the apostrophe operator in proc patterns for more details. + +.. code-block:: nim + + type + VectorIterator {.importcpp: "std::vector<'0>::iterator".} [T] = object + + var x: VectorIterator[cint] + + +Produces: + +.. code-block:: C + + std::vector<int>::iterator x; + + +ImportObjC pragma +----------------- +Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the +``importobjc`` pragma can be used to import `Objective C`:idx: methods. The +generated code then uses the Objective C method calling syntax: ``[obj method +param1: arg]``. In addition with the ``header`` and ``emit`` pragmas this +allows *sloppy* interfacing with libraries written in Objective C: + +.. code-block:: Nim + # horrible example of how to interface with GNUStep ... + + {.passL: "-lobjc".} + {.emit: """ + #include <objc/Object.h> + @interface Greeter:Object + { + } + + - (void)greet:(long)x y:(long)dummy; + @end + + #include <stdio.h> + @implementation Greeter + + - (void)greet:(long)x y:(long)dummy + { + printf("Hello, World!\n"); + } + @end + + #include <stdlib.h> + """.} + + type + Id {.importc: "id", header: "<objc/Object.h>", final.} = distinct int + + proc newGreeter: Id {.importobjc: "Greeter new", nodecl.} + proc greet(self: Id, x, y: int) {.importobjc: "greet", nodecl.} + proc free(self: Id) {.importobjc: "free", nodecl.} + + var g = newGreeter() + g.greet(12, 34) + g.free() + +The compiler needs to be told to generate Objective C (command ``objc``) for +this to work. The conditional symbol ``objc`` is defined when the compiler +emits Objective C code. + + +CodegenDecl pragma +------------------ + +The ``codegenDecl`` pragma can be used to directly influence Nim's code +generator. It receives a format string that determines how the variable or +proc is declared in the generated code: + +.. code-block:: nim + var + a {.codegenDecl: "$# progmem $#".}: int + + proc myinterrupt() {.codegenDecl: "__interrupt $# $#$#".} = + echo "realistic interrupt handler" + + +InjectStmt pragma +----------------- + +The ``injectStmt`` pragma can be used to inject a statement before every +other statement in the current module. It is only supposed to be used for +debugging: + +.. code-block:: nim + {.injectStmt: gcInvariants().} + + # ... complex code here that produces crashes ... + diff --git a/doc/nimc.txt b/doc/nimc.txt index 15c9f2955..95449d060 100644 --- a/doc/nimc.txt +++ b/doc/nimc.txt @@ -263,454 +263,6 @@ Nim manual. Some of the features here only make sense for the C code generator and are subject to change. -NoDecl pragma -------------- -The ``noDecl`` pragma can be applied to almost any symbol (variable, proc, -type, etc.) and is sometimes useful for interoperability with C: -It tells Nim that it should not generate a declaration for the symbol in -the C code. For example: - -.. code-block:: Nim - var - EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as - # Nim does not know its value - -However, the ``header`` pragma is often the better alternative. - -**Note**: This will not work for the LLVM backend. - - -Header pragma -------------- -The ``header`` pragma is very similar to the ``noDecl`` pragma: It can be -applied to almost any symbol and specifies that it should not be declared -and instead the generated code should contain an ``#include``: - -.. code-block:: Nim - type - PFile {.importc: "FILE*", header: "<stdio.h>".} = distinct pointer - # import C's FILE* type; Nim will treat it as a new pointer type - -The ``header`` pragma always expects a string constant. The string contant -contains the header file: As usual for C, a system header file is enclosed -in angle brackets: ``<>``. If no angle brackets are given, Nim -encloses the header file in ``""`` in the generated C code. - -**Note**: This will not work for the LLVM backend. - - -IncompleteStruct pragma ------------------------ -The ``incompleteStruct`` pragma tells the compiler to not use the -underlying C ``struct`` in a ``sizeof`` expression: - -.. code-block:: Nim - type - DIR* {.importc: "DIR", header: "<dirent.h>", - final, pure, incompleteStruct.} = object - - -Compile pragma --------------- -The ``compile`` pragma can be used to compile and link a C/C++ source file -with the project: - -.. code-block:: Nim - {.compile: "myfile.cpp".} - -**Note**: Nim computes a SHA1 checksum and only recompiles the file if it -has changed. You can use the ``-f`` command line option to force recompilation -of the file. - - -Link pragma ------------ -The ``link`` pragma can be used to link an additional file with the project: - -.. code-block:: Nim - {.link: "myfile.o".} - - -PassC pragma ------------- -The ``passC`` pragma can be used to pass additional parameters to the C -compiler like you would using the commandline switch ``--passC``: - -.. code-block:: Nim - {.passC: "-Wall -Werror".} - -Note that you can use ``gorge`` from the `system module <system.html>`_ to -embed parameters from an external command at compile time: - -.. code-block:: Nim - {.passC: gorge("pkg-config --cflags sdl").} - -PassL pragma ------------- -The ``passL`` pragma can be used to pass additional parameters to the linker -like you would using the commandline switch ``--passL``: - -.. code-block:: Nim - {.passL: "-lSDLmain -lSDL".} - -Note that you can use ``gorge`` from the `system module <system.html>`_ to -embed parameters from an external command at compile time: - -.. code-block:: Nim - {.passL: gorge("pkg-config --libs sdl").} - - -Emit pragma ------------ -The ``emit`` pragma can be used to directly affect the output of the -compiler's code generator. So it makes your code unportable to other code -generators/backends. Its usage is highly discouraged! However, it can be -extremely useful for interfacing with `C++`:idx: or `Objective C`:idx: code. - -Example: - -.. code-block:: Nim - {.emit: """ - static int cvariable = 420; - """.} - - {.push stackTrace:off.} - proc embedsC() = - var nimVar = 89 - # use backticks to access Nim symbols within an emit section: - {.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimVar`);""".} - {.pop.} - - embedsC() - -As can be seen from the example, to Nim symbols can be referred via backticks. -Use two backticks to produce a single verbatim backtick. - -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*/``: - -.. code-block:: Nim - {.emit: """/*TYPESECTION*/ - struct Vector3 { - public: - Vector3(): x(5) {} - Vector3(float x_): x(x_) {} - float x; - }; - """.} - - type Vector3 {.importcpp: "Vector3", nodecl} = object - x: cfloat - - proc constructVector3(a: cfloat): Vector3 {.importcpp: "Vector3(@)", nodecl} - - -ImportCpp pragma ----------------- - -**Note**: `c2nim <c2nim.html>`_ can parse a large subset of C++ and knows -about the ``importcpp`` pragma pattern language. It is not necessary -to know all the details described here. - - -Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the -``importcpp`` pragma can be used to import `C++`:idx: methods or C++ symbols -in general. The generated code then uses the C++ method calling -syntax: ``obj->method(arg)``. In combination with the ``header`` and ``emit`` -pragmas this allows *sloppy* interfacing with libraries written in C++: - -.. code-block:: Nim - # Horrible example of how to interface with a C++ engine ... ;-) - - {.link: "/usr/lib/libIrrlicht.so".} - - {.emit: """ - using namespace irr; - using namespace core; - using namespace scene; - using namespace video; - using namespace io; - using namespace gui; - """.} - - const - irr = "<irrlicht/irrlicht.h>" - - type - IrrlichtDeviceObj {.final, header: irr, - importcpp: "IrrlichtDevice".} = object - IrrlichtDevice = ptr IrrlichtDeviceObj - - proc createDevice(): IrrlichtDevice {. - header: irr, importcpp: "createDevice(@)".} - proc run(device: IrrlichtDevice): bool {. - header: irr, importcpp: "#.run(@)".} - -The compiler needs to be told to generate C++ (command ``cpp``) for -this to work. The conditional symbol ``cpp`` is defined when the compiler -emits C++ code. - - -Namespaces -~~~~~~~~~~ - -The *sloppy interfacing* example uses ``.emit`` to produce ``using namespace`` -declarations. It is usually much better to instead refer to the imported name -via the ``namespace::identifier`` notation: - -.. code-block:: nim - type - IrrlichtDeviceObj {.final, header: irr, - importcpp: "irr::IrrlichtDevice".} = object - - -Importcpp for enums -~~~~~~~~~~~~~~~~~~~ - -When ``importcpp`` is applied to an enum type the numerical enum values are -annotated with the C++ enum type, like in this example: ``((TheCppEnum)(3))``. -(This turned out to be the simplest way to implement it.) - - -Importcpp for procs -~~~~~~~~~~~~~~~~~~~ - -Note that the ``importcpp`` variant for procs uses a somewhat cryptic pattern -language for maximum flexibility: - -- A hash ``#`` symbol is replaced by the first or next argument. -- A dot following the hash ``#.`` indicates that the call should use C++'s dot - or arrow notation. -- An at symbol ``@`` is replaced by the remaining arguments, separated by - commas. - -For example: - -.. code-block:: nim - proc cppMethod(this: CppObj, a, b, c: cint) {.importcpp: "#.CppMethod(@)".} - var x: ptr CppObj - cppMethod(x[], 1, 2, 3) - -Produces: - -.. code-block:: C - x->CppMethod(1, 2, 3) - -As a special rule to keep backwards compatibility with older versions of the -``importcpp`` pragma, if there is no special pattern -character (any of ``# ' @``) at all, C++'s -dot or arrow notation is assumed, so the above example can also be written as: - -.. code-block:: nim - proc cppMethod(this: CppObj, a, b, c: cint) {.importcpp: "CppMethod".} - -Note that the pattern language naturally also covers C++'s operator overloading -capabilities: - -.. code-block:: nim - proc vectorAddition(a, b: Vec3): Vec3 {.importcpp: "# + #".} - proc dictLookup(a: Dict, k: Key): Value {.importcpp: "#[#]".} - - -- An apostrophe ``'`` followed by an integer ``i`` in the range 0..9 - is replaced by the i'th parameter *type*. The 0th position is the result - type. This can be used to pass types to C++ function templates. Between - the ``'`` and the digit an asterisk can be used to get to the base type - of the type. (So it "takes away a star" from the type; ``T*`` becomes ``T``.) - Two stars can be used to get to the element type of the element type etc. - -For example: - -.. code-block:: nim - - type Input {.importcpp: "System::Input".} = object - proc getSubsystem*[T](): ptr T {.importcpp: "SystemManager::getSubsystem<'*0>()", nodecl.} - - let x: ptr Input = getSubsystem[Input]() - -Produces: - -.. code-block:: C - x = SystemManager::getSubsystem<System::Input>() - - -- ``#@`` is a special case to support a ``cnew`` operation. It is required so - that the call expression is inlined directly, without going through a - temporary location. This is only required to circumvent a limitation of the - current code generator. - -For example C++'s ``new`` operator can be "imported" like this: - -.. code-block:: nim - proc cnew*[T](x: T): ptr T {.importcpp: "(new '*0#@)", nodecl.} - - # constructor of 'Foo': - proc constructFoo(a, b: cint): Foo {.importcpp: "Foo(@)".} - - let x = cnew constructFoo(3, 4) - -Produces: - -.. code-block:: C - x = new Foo(3, 4) - -However, depending on the use case ``new Foo`` can also be wrapped like this -instead: - -.. code-block:: nim - proc newFoo(a, b: cint): ptr Foo {.importcpp: "new Foo(@)".} - - let x = newFoo(3, 4) - - -Wrapping constructors -~~~~~~~~~~~~~~~~~~~~~ - -Sometimes a C++ class has a private copy constructor and so code like -``Class c = Class(1,2);`` must not be generated but instead ``Class c(1,2);``. -For this purpose the Nim proc that wraps a C++ constructor needs to be -annotated with the `constructor`:idx: pragma. This pragma also helps to generate -faster C++ code since construction then doesn't invoke the copy constructor: - -.. code-block:: nim - # a better constructor of 'Foo': - proc constructFoo(a, b: cint): Foo {.importcpp: "Foo(@)", constructor.} - - -Wrapping destructors -~~~~~~~~~~~~~~~~~~~~ - -Since Nim generates C++ directly, any destructor is called implicitly by the -C++ compiler at the scope exits. This means that often one can get away with -not wrapping the destructor at all! However when it needs to be invoked -explicitly, it needs to be wrapped. But the pattern language already provides -everything that is required for that: - -.. code-block:: nim - proc destroyFoo(this: var Foo) {.importcpp: "#.~Foo()".} - - -Importcpp for objects -~~~~~~~~~~~~~~~~~~~~~ - -Generic ``importcpp``'ed objects are mapped to C++ templates. This means that -you can import C++'s templates rather easily without the need for a pattern -language for object types: - -.. code-block:: nim - type - StdMap {.importcpp: "std::map", header: "<map>".} [K, V] = object - proc `[]=`[K, V](this: var StdMap[K, V]; key: K; val: V) {. - importcpp: "#[#] = #", header: "<map>".} - - var x: StdMap[cint, cdouble] - x[6] = 91.4 - - -Produces: - -.. code-block:: C - std::map<int, double> x; - x[6] = 91.4; - - -- If more precise control is needed, the apostrophe ``'`` can be used in the - supplied pattern to denote the concrete type parameters of the generic type. - See the usage of the apostrophe operator in proc patterns for more details. - -.. code-block:: nim - - type - VectorIterator {.importcpp: "std::vector<'0>::iterator".} [T] = object - - var x: VectorIterator[cint] - - -Produces: - -.. code-block:: C - - std::vector<int>::iterator x; - - -ImportObjC pragma ------------------ -Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the -``importobjc`` pragma can be used to import `Objective C`:idx: methods. The -generated code then uses the Objective C method calling syntax: ``[obj method -param1: arg]``. In addition with the ``header`` and ``emit`` pragmas this -allows *sloppy* interfacing with libraries written in Objective C: - -.. code-block:: Nim - # horrible example of how to interface with GNUStep ... - - {.passL: "-lobjc".} - {.emit: """ - #include <objc/Object.h> - @interface Greeter:Object - { - } - - - (void)greet:(long)x y:(long)dummy; - @end - - #include <stdio.h> - @implementation Greeter - - - (void)greet:(long)x y:(long)dummy - { - printf("Hello, World!\n"); - } - @end - - #include <stdlib.h> - """.} - - type - Id {.importc: "id", header: "<objc/Object.h>", final.} = distinct int - - proc newGreeter: Id {.importobjc: "Greeter new", nodecl.} - proc greet(self: Id, x, y: int) {.importobjc: "greet", nodecl.} - proc free(self: Id) {.importobjc: "free", nodecl.} - - var g = newGreeter() - g.greet(12, 34) - g.free() - -The compiler needs to be told to generate Objective C (command ``objc``) for -this to work. The conditional symbol ``objc`` is defined when the compiler -emits Objective C code. - - -CodegenDecl pragma ------------------- - -The ``codegenDecl`` pragma can be used to directly influence Nim's code -generator. It receives a format string that determines how the variable or -proc is declared in the generated code: - -.. code-block:: nim - var - a {.codegenDecl: "$# progmem $#".}: int - - proc myinterrupt() {.codegenDecl: "__interrupt $# $#$#".} = - echo "realistic interrupt handler" - - -InjectStmt pragma ------------------ - -The ``injectStmt`` pragma can be used to inject a statement before every -other statement in the current module. It is only supposed to be used for -debugging: - -.. code-block:: nim - {.injectStmt: gcInvariants().} - - # ... complex code here that produces crashes ... - - LineDir option -------------- The ``lineDir`` option can be turned on or off. If turned on the @@ -744,15 +296,6 @@ The *breakpoint* pragma was specially added for the sake of debugging with ENDB. See the documentation of `endb <endb.html>`_ for further information. -Volatile pragma ---------------- -The ``volatile`` pragma is for variables only. It declares the variable as -``volatile``, whatever that means in C/C++ (its semantics are not well defined -in C/C++). - -**Note**: This pragma will not exist for the LLVM backend. - - DynlibOverride ============== |