documentation for source code filters

This commit is contained in:
Araq
2011-01-06 23:06:40 +01:00
parent 693ed29345
commit b2e9977592
3 changed files with 49 additions and 78 deletions

View File

@@ -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.

View File

@@ -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>

View File

@@ -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.