diff options
author | Araq <rumpf_a@web.de> | 2010-10-21 00:12:14 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2010-10-21 00:12:14 +0200 |
commit | 765366c1f377fbd9507e942385170b546d9d34d0 (patch) | |
tree | bffec904c5b980aa7b9c0961cda18d5dd30638ae /rod/c2nim | |
parent | 53cd61546dc798fc0f08baf0813f579a90d7e766 (diff) | |
download | Nim-765366c1f377fbd9507e942385170b546d9d34d0.tar.gz |
version 0.8.10
Diffstat (limited to 'rod/c2nim')
-rwxr-xr-x | rod/c2nim/cparse.nim | 4 | ||||
-rwxr-xr-x | rod/c2nim/manual.txt | 292 |
2 files changed, 4 insertions, 292 deletions
diff --git a/rod/c2nim/cparse.nim b/rod/c2nim/cparse.nim index de2355bba..2634e8598 100755 --- a/rod/c2nim/cparse.nim +++ b/rod/c2nim/cparse.nim @@ -719,6 +719,8 @@ proc enumFields(p: var TParser): PNode = addSon(result, e) if p.tok.xkind != pxComma: break getTok(p, e) + # allow trailing comma: + if p.tok.xkind == pxCurlyRi: break proc parseTypedefStruct(p: var TParser, result: PNode, isUnion: bool) = getTok(p, result) @@ -965,6 +967,8 @@ proc enumSpecifier(p: var TParser): PNode = addSon(result, c) if p.tok.xkind != pxComma: break getTok(p, c) + # allow trailing comma: + if p.tok.xkind == pxCurlyRi: break eat(p, pxCurlyRi, result) eat(p, pxSemicolon) of pxSymbol: diff --git a/rod/c2nim/manual.txt b/rod/c2nim/manual.txt deleted file mode 100755 index c485a57f1..000000000 --- a/rod/c2nim/manual.txt +++ /dev/null @@ -1,292 +0,0 @@ -================================= - c2nim User's manual -================================= - -:Author: Andreas Rumpf -:Version: |nimrodversion| - -.. contents:: - -Introduction -============ - -c2nim is a tool to translate Ansi C code to Nimrod. The output is -human-readable Nimrod code that is meant to be tweaked by hand after the -translation process. c2nim is no real compiler! - -c2nim is preliminary meant to translate C header files. Because of this, the -preprocessor is part of the parser. For example: - -.. code-block:: C - #define abc 123 - #define xyz 789 - -Is translated into: - -.. code-block:: Nimrod - const - abc* = 123 - xyz* = 789 - - -c2nim is meant to translate fragments of C code and thus does not follow -include files. c2nim cannot parse all of Ansi C and many constructs cannot -be represented in Nimrod: for example `duff's device`:idx: cannot be translated -to Nimrod. - - -Preprocessor support -==================== - -Even though the translation process is not perfect, it is often the case that -the translated Nimrod code does not need any tweaking by hand. In other cases -it may be preferable to modify the input file instead of the generated Nimrod -code so that c2nim can parse it properly. c2nim's preprocessor defines the -symbol ``C2NIM`` that can be used to mark code sections: - -.. code-block:: C - #ifndef C2NIM - // C2NIM should ignore this prototype: - int fprintf(FILE* f, const char* frmt, ...); - #endif - -The ``C2NIM`` symbol is only recognized in ``#ifdef`` and ``#ifndef`` -constructs! ``#if defined(C2NIM)`` does **not** work. - -c2nim *processes* ``#ifdef C2NIM`` and ``#ifndef C2NIM`` directives, but other -``#if[def]`` directives are *translated* into Nimrod's ``when`` construct: - -.. code-block:: C - #ifdef DEBUG - # define OUT(x) printf("%s\n", x) - #else - # define OUT(x) - #endif - -Is translated into: - -.. code-block:: Nimrod - when defined(debug): - template OUT*(x: expr): expr = - printf("%s\x0A", x) - else: - template OUT*(x: expr): stmt = - nil - -As can been seen from the example, C's macros with parameters are mapped -to Nimrod's templates. This mapping is the best one can do, but it is of course -not accurate: Nimrod's templates operate on syntax trees whereas C's -macros work on the token level. c2nim cannot translate any macro that contains -the ``##`` token concatenation operator. - -c2nim's preprocessor supports special directives that affect how the output -is generated. They should be put into a ``#ifdef C2NIM`` section so that -ordinary C compilers ignore them. - - -``#skipinclude`` directive --------------------------- -**Note**: There is also a ``--skipinclude`` command line option that can be -used for the same purpose. - -By default, c2nim translates an ``#include`` that is not followed by ``<`` -(like in ``#include <stdlib>``) to a Nimrod ``import`` statement. This -directive tells c2nim to just skip any ``#include``. - - -``#stdcall`` and ``#cdecl`` directives --------------------------------------- -**Note**: There are also ``--stdcall`` and ``--cdecl`` command line options -that can be used for the same purpose. - -These directives tell c2nim that it should annotate every proc (or proc type) -with the ``stdcall`` / ``cdecl`` calling convention. - - -``#dynlib`` directive ---------------------- -**Note**: There is also a ``--dynlib`` command line option that can be used for -the same purpose. - -This directive tells c2nim that it should annotate every proc that resulted -from a C function prototype with the ``dynlib`` pragma: - -.. code-block:: C - - #ifdef C2NIM - # dynlib iupdll - # cdecl - # if defined(windows) - # define iupdll "iup.dll" - # elif defined(macosx) - # define iupdll "libiup.dynlib" - # else - # define iupdll "libiup.so" - # endif - #endif - - int IupConvertXYToPos(PIhandle ih, int x, int y); - -Is translated to: - -.. code-block:: Nimrod - when defined(windows): - const iupdll* = "iup.dll" - elif defined(macosx): - const iupdll* = "libiup.dynlib" - else: - const iupdll* = "libiup.so" - - proc IupConvertXYToPos*(ih: PIhandle, x: cint, y: cint): cint {. - importc: "IupConvertXYToPos", cdecl, dynlib: iupdll.} - -Note how the example contains extra C code to declare the ``iupdll`` symbol -in the generated Nimrod code. - - -``#header`` directive ---------------------- -**Note**: There is also a ``--header`` command line option that can be used for -the same purpose. - -The ``#header`` directive tells c2nim that it should annotate every proc that -resulted from a C function prototype and every exported variable and type with -the ``header`` pragma: - -.. code-block:: C - - #ifdef C2NIM - # header "iup.h" - #endif - - int IupConvertXYToPos(PIhandle ih, int x, int y); - -Is translated to: - -.. code-block:: Nimrod - proc IupConvertXYToPos*(ih: PIhandle, x: cint, y: cint): cint {. - importc: "IupConvertXYToPos", header: "iup.h".} - -The ``#header`` and the ``#dynlib`` directives are mutually exclusive. -A binding that uses ``dynlib`` is much more preferable over one that uses -``header``! The Nimrod compiler might drop support for the ``header`` pragma -in the future as it cannot work for backends that do not generate C code. - - -``#prefix`` and ``#suffix`` directives --------------------------------------- - -**Note**: There are also ``--prefix`` and ``--suffix`` command line options -that can be used for the same purpose. - -c2nim does not do any name mangling by default. However the -``#prefix`` and ``#suffix`` directives can be used to strip prefixes and -suffixes from the identifiers in the C code: - -.. code-block:: C - - #ifdef C2NIM - # prefix Iup - # dynlib dllname - # cdecl - #endif - - int IupConvertXYToPos(PIhandle ih, int x, int y); - -Is translated to: - -.. code-block:: Nimrod - - proc ConvertXYToPos*(ih: PIhandle, x: cint, y: cint): cint {. - importc: "IupConvertXYToPos", cdecl, dynlib: dllname.} - - -``#mangle`` directive ---------------------- - -Even more sophisticated name mangling can be achieved by the ``#mangle`` -directive: It takes a PEG pattern and format string that specify how the -identifier should be converted: - -.. code-block:: C - #mangle "'GTK_'{.*}" "TGtk$1" - -For convenience the PEG pattern and the replacement can be single identifiers -too, there is no need to quote them: - -.. code-block:: C - #mangle ssize_t int - // is short for: - #mangle "'ssize_t'" "int" - - -``#private`` directive ----------------------- - -By default c2nim marks every top level identifier (proc name, variable, etc.) -as exported (the export marker is ``*`` in Nimrod). With the ``#private`` -directive identifiers can be marked as private so that the resulting Nimrod -module does not export them. The ``#private`` directive takes a PEG pattern: - -.. code-block:: C - #private "@('_'!.)" // all identifiers ending in '_' are private - -Note: The pattern refers to the original C identifiers, not to the resulting -identifiers after mangling! - - -``#skipcomments`` directive ---------------------------- -**Note**: There is also a ``--skipcomments`` command line option that can be -used for the same purpose. - -The ``#skipcomments`` directive can be put into the C code to make c2nim -ignore comments and not copy them into the generated Nimrod file. - - -``#typeprefixes`` directive ---------------------------- -**Note**: There is also a ``--typeprefixes`` command line option that can be -used for the same purpose. - -The ``#typeprefixes`` directive can be put into the C code to make c2nim -generate the ``T`` or ``P`` prefix for every defined type. - - -``#def`` directive ------------------- - -Often C code contains special macros that affect the declaration of a function -prototype but confuse c2nim's parser: - -.. code-block:: C - // does not parse! - EXTERN(int) f(void); - EXTERN(int) g(void); - -Instead of removing ``EXTERN()`` from the input source file (which cannot be -done reliably even with a regular expression!), one can tell c2nim -that ``EXPORT`` is a macro that should be expanded by c2nim too: - -.. code-block:: C - #ifdef C2NIM - # def EXTERN(x) static x - #endif - // parses now! - EXTERN(int) f(void); - EXTERN(int) g(void); - -``#def`` is very similar to C's ``#define``, so in general the macro definition -can be copied and pasted into a ``#def`` directive. - - -Limitations -=========== - -* C's ``,`` operator (comma operator) is not supported. -* C's ``union`` are translated to Nimrod's objects and only the first field - is included in the object type. This way there is a high chance that it is - binary compatible to the union. -* The condition in a ``do while(condition)`` statement must be ``0``. -* Lots of other small issues... - |