mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 14:00:35 +00:00
documentation for source code filters
This commit is contained in:
@@ -22,6 +22,10 @@ The documentation consists of several documents:
|
||||
- | `Manual <manual.html>`_
|
||||
| The Nimrod manual is a draft that will evolve into a proper specification.
|
||||
|
||||
- | `Source code filters <filters.html>`_
|
||||
| The Nimrod compiler supports source code filters as a simple yet powerful
|
||||
builtin templating system.
|
||||
|
||||
- | `Internal documentation <intern.html>`_
|
||||
| The internal documentation describes how the compiler is implemented. Read
|
||||
this if you want to hack the compiler.
|
||||
|
||||
@@ -1,45 +1,14 @@
|
||||
===================
|
||||
Parsers and Filters
|
||||
Source Code Filters
|
||||
===================
|
||||
|
||||
.. contents::
|
||||
|
||||
The Nimrod compiler contains multiple parsers. The standard is
|
||||
indentation-based. Two others are available: The `braces`:idx: parser and the
|
||||
`endX`:idx: parser. Both parsers use the same lexer as the standard parser.
|
||||
A `Source Code Filter` transforms the input character stream to an in-memory
|
||||
output stream before parsing. A filter can be used to provide templating
|
||||
systems or preprocessors.
|
||||
|
||||
To use a different parser for a source file the *shebang* notation is used:
|
||||
|
||||
.. code-block:: nimrod
|
||||
#! braces
|
||||
if (x == 10) {
|
||||
echo "x is ten"
|
||||
} else {
|
||||
echo "x isn't ten"
|
||||
}
|
||||
|
||||
The special ``#!`` comment for specifying a parser needs to be in the first
|
||||
line with no leading whitespace, unless an UNIX shebang line is used. Then the
|
||||
parser shebang can occur in the second line:
|
||||
|
||||
.. code-block:: nimrod
|
||||
#! /usr/bin/env nimrod c -r
|
||||
#! braces
|
||||
if (x == 10) {
|
||||
echo "x is ten"
|
||||
} else {
|
||||
echo "x isn't ten"
|
||||
}
|
||||
|
||||
An UNIX shebang line is defined by the pattern ``'#!' \s* '/' .*``
|
||||
(``#!`` followed by optional whitespace followed by ``/``).
|
||||
|
||||
|
||||
Filters
|
||||
=======
|
||||
|
||||
Nimrod's shebang also supports the invokation of `source filters`:idx: before
|
||||
the source code file is passed to the parser::
|
||||
To use a filter for a source file the *shebang* notation is used::
|
||||
|
||||
#! stdtmpl(subsChar = '$', metaChar = '#')
|
||||
#proc generateXML(name, age: string): string =
|
||||
@@ -49,22 +18,17 @@ the source code file is passed to the parser::
|
||||
<age>$age</age>
|
||||
</xml>
|
||||
|
||||
Filters transform the input character stream to an in-memory output stream.
|
||||
They are used to provide templating systems or preprocessors.
|
||||
|
||||
As the example shows, passing arguments to a filter (or parser) can be done
|
||||
As the example shows, passing arguments to a filter can be done
|
||||
just like an ordinary procedure call with named or positional arguments. The
|
||||
available parameters depend on the invoked filter/parser.
|
||||
available parameters depend on the invoked filter.
|
||||
|
||||
|
||||
Pipe operator
|
||||
-------------
|
||||
=============
|
||||
|
||||
Filters and parsers can be combined with the ``|`` `pipe operator`:idx:. Only
|
||||
the last operand can be a parser because a parser returns an abstract syntax
|
||||
tree which a filter cannot process::
|
||||
Filters can be combined with the ``|`` `pipe operator`:idx:\ ::
|
||||
|
||||
#! strip(startswith="<") | stdtmpl | standard
|
||||
#! strip(startswith="<") | stdtmpl
|
||||
#proc generateXML(name, age: string): string =
|
||||
# result = ""
|
||||
<xml>
|
||||
|
||||
@@ -1529,6 +1529,7 @@ Example:
|
||||
finally:
|
||||
close(f)
|
||||
|
||||
|
||||
The statements after the `try`:idx: are executed in sequential order unless
|
||||
an exception ``e`` is raised. If the exception type of ``e`` matches any
|
||||
of the list ``exceptlist`` the corresponding statements are executed.
|
||||
@@ -2324,6 +2325,7 @@ invoked by an expression following a colon::
|
||||
The following example outlines a macro that generates a lexical analyzer from
|
||||
regular expressions:
|
||||
|
||||
|
||||
.. code-block:: nimrod
|
||||
import macros
|
||||
|
||||
@@ -2651,30 +2653,30 @@ Example:
|
||||
|
||||
.. code-block:: nimrod
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
|
||||
Pragma pragma
|
||||
-------------
|
||||
|
||||
The `pragma`:idx: pragma can be used to declare user defined pragmas. This is
|
||||
useful because Nimrod's templates and macros do not affect pragmas. User
|
||||
defined pragmas are in a different module-wide scope than all other symbols.
|
||||
They cannot be imported from a module.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: nimrod
|
||||
when appType == "lib":
|
||||
{.pragma: rtl, exportc, dynlib, cdecl.}
|
||||
else:
|
||||
{.pragma: rtl, importc, dynlib: "client.dll", cdecl.}
|
||||
|
||||
proc p*(a, b: int): int {.rtl.} =
|
||||
return a+b
|
||||
|
||||
In the example a new pragma named ``rtl`` is introduced that either imports
|
||||
a symbol from a dynamic library or exports the symbol for dynamic library
|
||||
generation.
|
||||
|
||||
|
||||
Pragma pragma
|
||||
-------------
|
||||
|
||||
The `pragma`:idx: pragma can be used to declare user defined pragmas. This is
|
||||
useful because Nimrod's templates and macros do not affect pragmas. User
|
||||
defined pragmas are in a different module-wide scope than all other symbols.
|
||||
They cannot be imported from a module.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: nimrod
|
||||
when appType == "lib":
|
||||
{.pragma: rtl, exportc, dynlib, cdecl.}
|
||||
else:
|
||||
{.pragma: rtl, importc, dynlib: "client.dll", cdecl.}
|
||||
|
||||
proc p*(a, b: int): int {.rtl.} =
|
||||
return a+b
|
||||
|
||||
In the example a new pragma named ``rtl`` is introduced that either imports
|
||||
a symbol from a dynamic library or exports the symbol for dynamic library
|
||||
generation.
|
||||
|
||||
|
||||
Disabling certain messages
|
||||
@@ -2786,17 +2788,18 @@ string expressions in general:
|
||||
|
||||
**Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
|
||||
strings, because they are precompiled.
|
||||
|
||||
|
||||
Dynlib pragma for export
|
||||
------------------------
|
||||
|
||||
------------------------
|
||||
|
||||
With the ``dynlib`` pragma a procedure can also be exported to
|
||||
a dynamic library. The pragma then has no argument and has to be used in
|
||||
a dynamic library. The pragma then has no argument and has to be used in
|
||||
conjunction with the ``exportc`` pragma:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
proc exportme(): int {.cdecl, exportc, dynlib.}
|
||||
|
||||
This is only useful if the program is compiled as a dynamic library via the
|
||||
``--app:lib`` command line option.
|
||||
|
||||
|
||||
This is only useful if the program is compiled as a dynamic library via the
|
||||
``--app:lib`` command line option.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user