diff options
-rw-r--r-- | compiler/ccgcalls.nim | 30 | ||||
-rw-r--r-- | doc/nimc.txt | 941 | ||||
-rw-r--r-- | todo.txt | 1 |
3 files changed, 490 insertions, 482 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index b9fc694cb..fb878a83e 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -430,15 +430,27 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = assert(typ.kind == tyProc) var length = sonsLen(ri) assert(sonsLen(typ) == sonsLen(typ.n)) - - if length > 1: - app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) - app(pl, ~" ") - app(pl, op.r) - if length > 2: - app(pl, ~": ") - app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) - for i in countup(3, length-1): + + # don't call 'ropeToStr' here for efficiency: + let pat = ri.sons[0].sym.loc.r.data + internalAssert pat != nil + var start = 3 + if ' ' in pat: + start = 1 + app(pl, op.r) + if length > 1: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + start = 2 + else: + if length > 1: + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + app(pl, ~" ") + app(pl, op.r) + if length > 2: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) + for i in countup(start, length-1): assert(sonsLen(typ) == sonsLen(typ.n)) if i >= sonsLen(typ): internalError(ri.info, "varargs for objective C method?") diff --git a/doc/nimc.txt b/doc/nimc.txt index 80fcf927b..84d596e3c 100644 --- a/doc/nimc.txt +++ b/doc/nimc.txt @@ -1,45 +1,45 @@ -=================================== - Nim Compiler User Guide -=================================== - -:Author: Andreas Rumpf -:Version: |nimversion| - -.. contents:: - - "Look at you, hacker. A pathetic creature of meat and bone, panting and - sweating as you run through my corridors. How can you challenge a perfect, - immortal machine?" - - -Introduction -============ - -This document describes the usage of the *Nim compiler* -on the different supported platforms. It is not a definition of the Nim -programming language (therefore is the `manual <manual.html>`_). - -Nim is free software; it is licensed under the -`MIT License <http://www.opensource.org/licenses/mit-license.php>`_. - - -Compiler Usage -============== - -Command line switches ---------------------- -Basic command line switches are: - -Usage: - -.. include:: basicopt.txt - ----- - -Advanced command line switches are: - -.. include:: advopt.txt - +=================================== + Nim Compiler User Guide +=================================== + +:Author: Andreas Rumpf +:Version: |nimversion| + +.. contents:: + + "Look at you, hacker. A pathetic creature of meat and bone, panting and + sweating as you run through my corridors. How can you challenge a perfect, + immortal machine?" + + +Introduction +============ + +This document describes the usage of the *Nim compiler* +on the different supported platforms. It is not a definition of the Nim +programming language (therefore is the `manual <manual.html>`_). + +Nim is free software; it is licensed under the +`MIT License <http://www.opensource.org/licenses/mit-license.php>`_. + + +Compiler Usage +============== + +Command line switches +--------------------- +Basic command line switches are: + +Usage: + +.. include:: basicopt.txt + +---- + +Advanced command line switches are: + +.. include:: advopt.txt + List of warnings @@ -53,21 +53,16 @@ Name Description ========================== ============================================ CannotOpenFile Some file not essential for the compiler's working could not be opened. -OctalEscape The code contains an unsupported octal +OctalEscape The code contains an unsupported octal sequence. Deprecated The code uses a deprecated symbol. ConfigDeprecated The project makes use of a deprecated config file. -SmallLshouldNotBeUsed The letter 'l' should not be used as an +SmallLshouldNotBeUsed The letter 'l' should not be used as an identifier. -AnalysisLoophole The thread analysis was incomplete due to - an indirect call. -DifferentHeaps The code mixes different local heaps in a - very dangerous way. -WriteToForeignHeap The code contains a threading error. -EachIdentIsTuple The code contains a confusing ``var`` +EachIdentIsTuple The code contains a confusing ``var`` declaration. -ShadowIdent A local variable shadows another local +ShadowIdent A local variable shadows another local variable of an outer scope. User Some user defined warning. ========================== ============================================ @@ -103,30 +98,30 @@ enable builds in release mode (``-d:release``) where certain safety checks are omitted for better performance. Another common use is the ``-d:ssl`` switch to activate `SSL sockets <sockets.html>`_. - -Configuration files -------------------- - -**Note:** The *project file name* is the name of the ``.nim`` file that is -passed as a command line argument to the compiler. - - -The ``nim`` executable processes configuration files in the following -directories (in this order; later files overwrite previous settings): - -1) ``$nim/config/nim.cfg``, ``/etc/nim.cfg`` (UNIX) or ``%NIMROD%/config/nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option. -2) ``/home/$user/.config/nim.cfg`` (UNIX) or ``%APPDATA%/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option. -3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option. -4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option. -5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option. - - -Command line settings have priority over configuration file settings. - -The default build of a project is a `debug build`:idx:. To compile a -`release build`:idx: define the ``release`` symbol:: - - nim c -d:release myproject.nim + +Configuration files +------------------- + +**Note:** The *project file name* is the name of the ``.nim`` file that is +passed as a command line argument to the compiler. + + +The ``nim`` executable processes configuration files in the following +directories (in this order; later files overwrite previous settings): + +1) ``$nim/config/nim.cfg``, ``/etc/nim.cfg`` (UNIX) or ``%NIMROD%/config/nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option. +2) ``/home/$user/.config/nim.cfg`` (UNIX) or ``%APPDATA%/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option. +3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option. +4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option. +5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option. + + +Command line settings have priority over configuration file settings. + +The default build of a project is a `debug build`:idx:. To compile a +`release build`:idx: define the ``release`` symbol:: + + nim c -d:release myproject.nim Search path handling @@ -138,8 +133,8 @@ found an ambiguity error is produced. ``nim dump`` shows the contents of the PATH. -However before the PATH is used the current directory is checked for the -file's existance. So if PATH contains ``$lib`` and ``$lib/bar`` and the +However before the PATH is used the current directory is checked for the +file's existance. So if PATH contains ``$lib`` and ``$lib/bar`` and the directory structure looks like this:: $lib/x.nim @@ -152,83 +147,83 @@ And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x`` then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match and so the compiler should reject it. Currently however this check is not implemented and instead the first matching file is used. - - -Generated C code directory --------------------------- + + +Generated C code directory +-------------------------- The generated files that Nim produces all go into a subdirectory called ``nimcache`` in your project directory. This makes it easy to delete all generated files. Files generated in this directory follow a naming logic which you can read about in the `Nim Backend Integration document <backends.html#nimcache-naming-logic>`_. -However, the generated C code is not platform independent. C code generated for -Linux does not compile on Windows, for instance. The comment on top of the -C file lists the OS, CPU and CC the file has been compiled for. - - -Compilation cache -================= - -**Warning**: The compilation cache is still highly experimental! - -The ``nimcache`` directory may also contain so called `rod`:idx: -or `symbol files`:idx:. These files are pre-compiled modules that are used by -the compiler to perform `incremental compilation`:idx:. This means that only -modules that have changed since the last compilation (or the modules depending -on them etc.) are re-compiled. However, per default no symbol files are -generated; use the ``--symbolFiles:on`` command line switch to activate them. - -Unfortunately due to technical reasons the ``--symbolFiles:on`` needs -to *aggregate* some generated C code. This means that the resulting executable -might contain some cruft even when dead code elimination is turned on. So -the final release build should be done with ``--symbolFiles:off``. - -Due to the aggregation of C code it is also recommended that each project -resides in its own directory so that the generated ``nimcache`` directory -is not shared between different projects. - - -Cross compilation -================= - -To cross compile, use for example:: - - nim c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim - -Then move the C code and the compile script ``compile_myproject.sh`` to your +However, the generated C code is not platform independent. C code generated for +Linux does not compile on Windows, for instance. The comment on top of the +C file lists the OS, CPU and CC the file has been compiled for. + + +Compilation cache +================= + +**Warning**: The compilation cache is still highly experimental! + +The ``nimcache`` directory may also contain so called `rod`:idx: +or `symbol files`:idx:. These files are pre-compiled modules that are used by +the compiler to perform `incremental compilation`:idx:. This means that only +modules that have changed since the last compilation (or the modules depending +on them etc.) are re-compiled. However, per default no symbol files are +generated; use the ``--symbolFiles:on`` command line switch to activate them. + +Unfortunately due to technical reasons the ``--symbolFiles:on`` needs +to *aggregate* some generated C code. This means that the resulting executable +might contain some cruft even when dead code elimination is turned on. So +the final release build should be done with ``--symbolFiles:off``. + +Due to the aggregation of C code it is also recommended that each project +resides in its own directory so that the generated ``nimcache`` directory +is not shared between different projects. + + +Cross compilation +================= + +To cross compile, use for example:: + + nim c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim + +Then move the C code and the compile script ``compile_myproject.sh`` to your Linux i386 machine and run the script. Another way is to make Nim invoke a cross compiler toolchain:: - - nim c --cpu:arm --os:linux myproject.nim - -For cross compilation, the compiler invokes a C compiler named -like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration + + nim c --cpu:arm --os:linux myproject.nim + +For cross compilation, the compiler invokes a C compiler named +like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration system is used to provide meaningful defaults. For example for ``ARM`` your configuration file should contain something like:: arm.linux.gcc.path = "/usr/bin" arm.linux.gcc.exe = "arm-linux-gcc" arm.linux.gcc.linkerexe = "arm-linux-gcc" - - -DLL generation -============== - -Nim supports the generation of DLLs. However, there must be only one -instance of the GC per process/address space. This instance is contained in -``nimrtl.dll``. This means that every generated Nim DLL depends -on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: - - nim c -d:release lib/nimrtl.nim - -To link against ``nimrtl.dll`` use the command:: - - nim c -d:useNimRtl myprog.nim - -**Note**: Currently the creation of ``nimrtl.dll`` with thread support has -never been tested and is unlikely to work! + + +DLL generation +============== + +Nim supports the generation of DLLs. However, there must be only one +instance of the GC per process/address space. This instance is contained in +``nimrtl.dll``. This means that every generated Nim DLL depends +on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: + + nim c -d:release lib/nimrtl.nim + +To link against ``nimrtl.dll`` use the command:: + + nim c -d:useNimRtl myprog.nim + +**Note**: Currently the creation of ``nimrtl.dll`` with thread support has +never been tested and is unlikely to work! Additional compilation switches @@ -247,10 +242,10 @@ Define Effect version. ``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``. ``useNimRtl`` Compile and link against ``nimrtl.dll``. -``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's +``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's own memory manager. This only works with ``gc:none``. -``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime - systems. See the documentation of the `gc <gc.html>`_ +``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime + systems. See the documentation of the `gc <gc.html>`_ for further information. ``nodejs`` The JS target is actually ``node.js``. ``ssl`` Enables OpenSSL support for the sockets module. @@ -258,84 +253,84 @@ Define Effect ``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes) ================== ========================================================= - - -Additional Features -=================== - -This section describes Nim's additional features that are not listed in the -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 CRC 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".} - - + + +Additional Features +=================== + +This section describes Nim's additional features that are not listed in the +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 CRC 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 @@ -365,76 +360,76 @@ embed parameters from an external command at compile time: {.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; - """.} - +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`);""".} + 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() + + 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. - -ImportCpp pragma + +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 +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 + +.. 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 {. + 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 + +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. @@ -446,9 +441,9 @@ declarations. It is usually much better to instead refer to the imported name via the ``namespace::identifier`` notation: .. code-block:: nim - type + type IrrlichtDeviceObj {.final, header: irr, - importcpp: "irr::IrrlichtDevice".} = object + importcpp: "irr::IrrlichtDevice".} = object Importcpp for enums @@ -586,61 +581,61 @@ Produces: std::map<int, double> x; x[6] = 91.4; - -ImportObjC pragma ------------------ + +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. + +.. 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 +generator. It receives a format string that determines how the variable or proc is declared in the generated code: .. code-block:: nim @@ -660,56 +655,56 @@ 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 -generated C code contains ``#line`` directives. This may be helpful for -debugging with GDB. - - -StackTrace option ------------------ -If the ``stackTrace`` option is turned on, the generated C contains code to -ensure that proper stack traces are given if the program crashes or an -uncaught exception is raised. - - -LineTrace option ----------------- -The ``lineTrace`` option implies the ``stackTrace`` option. If turned on, -the generated C contains code to ensure that proper stack traces with line -number information are given if the program crashes or an uncaught exception -is raised. - -Debugger option ---------------- -The ``debugger`` option enables or disables the *Embedded Nim Debugger*. -See the documentation of endb_ for further information. - - -Breakpoint pragma ------------------ -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. + + +LineDir option +-------------- +The ``lineDir`` option can be turned on or off. If turned on the +generated C code contains ``#line`` directives. This may be helpful for +debugging with GDB. + + +StackTrace option +----------------- +If the ``stackTrace`` option is turned on, the generated C contains code to +ensure that proper stack traces are given if the program crashes or an +uncaught exception is raised. + + +LineTrace option +---------------- +The ``lineTrace`` option implies the ``stackTrace`` option. If turned on, +the generated C contains code to ensure that proper stack traces with line +number information are given if the program crashes or an uncaught exception +is raised. + +Debugger option +--------------- +The ``debugger`` option enables or disables the *Embedded Nim Debugger*. +See the documentation of endb_ for further information. + + +Breakpoint pragma +----------------- +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 ============== -By default Nim's ``dynlib`` pragma causes the compiler to generate +By default Nim's ``dynlib`` pragma causes the compiler to generate ``GetProcAddress`` (or their Unix counterparts) calls to bind to a DLL. With the ``dynlibOverride`` command line switch this can be prevented and then via ``--passL`` the static library can be linked @@ -736,28 +731,28 @@ Nim provides the `doc`:idx: and `doc2`:idx: commands to generate HTML documentation from ``.nim`` source files. Only exported symbols will appear in the output. For more details `see the docgen documentation <docgen.html>`_. -Nim idetools integration -======================== - -Nim provides language integration with external IDEs through the -idetools command. See the documentation of `idetools <idetools.html>`_ -for further information. - - -Nim interactive mode -==================== - -The Nim compiler supports an interactive mode. This is also known as -a `REPL`:idx: (*read eval print loop*). If Nim has been built with the -``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal -input management. To start Nim in interactive mode use the command -``nim i``. To quit use the ``quit()`` command. To determine whether an input -line is an incomplete statement to be continued these rules are used: - -1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace). -2. The line starts with a space (indentation). -3. The line is within a triple quoted string literal. However, the detection - does not work if the line contains more than one ``"""``. +Nim idetools integration +======================== + +Nim provides language integration with external IDEs through the +idetools command. See the documentation of `idetools <idetools.html>`_ +for further information. + + +Nim interactive mode +==================== + +The Nim compiler supports an interactive mode. This is also known as +a `REPL`:idx: (*read eval print loop*). If Nim has been built with the +``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal +input management. To start Nim in interactive mode use the command +``nim i``. To quit use the ``quit()`` command. To determine whether an input +line is an incomplete statement to be continued these rules are used: + +1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace). +2. The line starts with a space (indentation). +3. The line is within a triple quoted string literal. However, the detection + does not work if the line contains more than one ``"""``. Nim for embedded systems @@ -768,107 +763,107 @@ for 16bit micro controllers is feasible. Use the `standalone`:idx: target (``--os:standalone``) for a bare bones standard library that lacks any OS features. -To make the compiler output code for a 16bit target use the ``--cpu:avr`` +To make the compiler output code for a 16bit target use the ``--cpu:avr`` target. For example, to generate code for an `AVR`:idx: processor use this command:: - + nim c --cpu:avr --os:standalone --deadCodeElim:on --genScript x.nim For the ``standalone`` target one needs to provide a file ``panicoverride.nim``. See ``tests/manyloc/standalone/panicoverride.nim`` for an example implementation. - + Nim for realtime systems ======================== -See the documentation of Nim's soft realtime `GC <gc.html>`_ for further +See the documentation of Nim's soft realtime `GC <gc.html>`_ for further information. - -Debugging with Nim -================== - -Nim comes with its own *Embedded Nim Debugger*. See -the documentation of endb_ for further information. - - -Optimizing for Nim -================== - -Nim has no separate optimizer, but the C code that is produced is very -efficient. Most C compilers have excellent optimizers, so usually it is -not needed to optimize one's code. Nim has been designed to encourage -efficient code: The most readable code in Nim is often the most efficient -too. - -However, sometimes one has to optimize. Do it in the following order: - -1. switch off the embedded debugger (it is **slow**!) -2. turn on the optimizer and turn off runtime checks -3. profile your code to find where the bottlenecks are -4. try to find a better algorithm -5. do low-level optimizations - -This section can only help you with the last item. - - -Optimizing string handling --------------------------- - -String assignments are sometimes expensive in Nim: They are required to -copy the whole string. However, the compiler is often smart enough to not copy -strings. Due to the argument passing semantics, strings are never copied when -passed to subroutines. The compiler does not copy strings that are a result from -a procedure call, because the callee returns a new string anyway. -Thus it is efficient to do: - -.. code-block:: Nim - var s = procA() # assignment will not copy the string; procA allocates a new - # string already - -However it is not efficient to do: - -.. code-block:: Nim - var s = varA # assignment has to copy the whole string into a new buffer! - -For ``let`` symbols a copy is not always necessary: - -.. code-block:: Nim - let s = varA # may only copy a pointer if it safe to do so - - -If you know what you're doing, you can also mark single string (or sequence) -objects as `shallow`:idx:\: - -.. code-block:: Nim - var s = "abc" - shallow(s) # mark 's' as shallow string - var x = s # now might not copy the string! - -Usage of ``shallow`` is always safe once you know the string won't be modified -anymore, similar to Ruby's `freeze`:idx:. - - -The compiler optimizes string case statements: A hashing scheme is used for them -if several different string constants are used. So code like this is reasonably -efficient: - -.. code-block:: Nim - case normalize(k.key) - of "name": c.name = v - of "displayname": c.displayName = v - of "version": c.version = v - of "os": c.oses = split(v, {';'}) - of "cpu": c.cpus = split(v, {';'}) - of "authors": c.authors = split(v, {';'}) - of "description": c.description = v - of "app": - case normalize(v) - of "console": c.app = appConsole - of "gui": c.app = appGUI - else: quit(errorStr(p, "expected: console or gui")) - of "license": c.license = UnixToNativePath(k.value) - else: quit(errorStr(p, "unknown variable: " & k.key)) + +Debugging with Nim +================== + +Nim comes with its own *Embedded Nim Debugger*. See +the documentation of endb_ for further information. + + +Optimizing for Nim +================== + +Nim has no separate optimizer, but the C code that is produced is very +efficient. Most C compilers have excellent optimizers, so usually it is +not needed to optimize one's code. Nim has been designed to encourage +efficient code: The most readable code in Nim is often the most efficient +too. + +However, sometimes one has to optimize. Do it in the following order: + +1. switch off the embedded debugger (it is **slow**!) +2. turn on the optimizer and turn off runtime checks +3. profile your code to find where the bottlenecks are +4. try to find a better algorithm +5. do low-level optimizations + +This section can only help you with the last item. + + +Optimizing string handling +-------------------------- + +String assignments are sometimes expensive in Nim: They are required to +copy the whole string. However, the compiler is often smart enough to not copy +strings. Due to the argument passing semantics, strings are never copied when +passed to subroutines. The compiler does not copy strings that are a result from +a procedure call, because the callee returns a new string anyway. +Thus it is efficient to do: + +.. code-block:: Nim + var s = procA() # assignment will not copy the string; procA allocates a new + # string already + +However it is not efficient to do: + +.. code-block:: Nim + var s = varA # assignment has to copy the whole string into a new buffer! + +For ``let`` symbols a copy is not always necessary: + +.. code-block:: Nim + let s = varA # may only copy a pointer if it safe to do so + + +If you know what you're doing, you can also mark single string (or sequence) +objects as `shallow`:idx:\: + +.. code-block:: Nim + var s = "abc" + shallow(s) # mark 's' as shallow string + var x = s # now might not copy the string! + +Usage of ``shallow`` is always safe once you know the string won't be modified +anymore, similar to Ruby's `freeze`:idx:. + + +The compiler optimizes string case statements: A hashing scheme is used for them +if several different string constants are used. So code like this is reasonably +efficient: + +.. code-block:: Nim + case normalize(k.key) + of "name": c.name = v + of "displayname": c.displayName = v + of "version": c.version = v + of "os": c.oses = split(v, {';'}) + of "cpu": c.cpus = split(v, {';'}) + of "authors": c.authors = split(v, {';'}) + of "description": c.description = v + of "app": + case normalize(v) + of "console": c.app = appConsole + of "gui": c.app = appGUI + else: quit(errorStr(p, "expected: console or gui")) + of "license": c.license = UnixToNativePath(k.value) + else: quit(errorStr(p, "unknown variable: " & k.key)) diff --git a/todo.txt b/todo.txt index 15521eae1..408bfefe5 100644 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,7 @@ version 0.10.4 - improve GC-unsafety warnings - make 'nil' work for 'add' and 'len' - get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}' +- 'result' shadowing warning version 1.0 |