mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 09:54:49 +00:00
Merge pull request #1132 from gradha/pr_index_improvements
Documentation index improvements
This commit is contained in:
@@ -541,8 +541,14 @@ proc genOutFile(d: PDoc): PRope =
|
||||
if toc != nil:
|
||||
toc = ropeFormatNamedVars(getConfigVar("doc.toc"), ["content"], [toc])
|
||||
for i in countup(low(TSymKind), high(TSymKind)): app(code, d.section[i])
|
||||
if d.meta[metaTitle].len != 0: title = d.meta[metaTitle]
|
||||
else: title = "Module " & extractFilename(changeFileExt(d.filename, ""))
|
||||
|
||||
# Extract the title. Non API modules generate an entry in the index table.
|
||||
if d.meta[metaTitle].len != 0:
|
||||
title = d.meta[metaTitle]
|
||||
setIndexTerm(d[], "", title)
|
||||
else:
|
||||
# Modules get an automatic title for the HTML, but no entry in the index.
|
||||
title = "Module " & extractFilename(changeFileExt(d.filename, ""))
|
||||
|
||||
let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc"
|
||||
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
|
||||
|
||||
13
doc/apis.txt
13
doc/apis.txt
@@ -1,6 +1,6 @@
|
||||
==========
|
||||
API design
|
||||
==========
|
||||
=================
|
||||
API naming design
|
||||
=================
|
||||
|
||||
The API is designed to be **easy to use** and consistent. Ease of use is
|
||||
measured by the number of calls to achieve a concrete high level action.
|
||||
@@ -79,3 +79,10 @@ string str
|
||||
identifier ident
|
||||
indentation indent
|
||||
------------------- ------------ --------------------------------------
|
||||
|
||||
|
||||
Coding Guidelines
|
||||
=================
|
||||
|
||||
For coding guidelines see the `Internals of the Nimrod Compiler
|
||||
<intern.html#coding-guidelines>`_ documentation.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
=================================
|
||||
c2nim User's manual
|
||||
=================================
|
||||
=======================
|
||||
c2nim User's manual
|
||||
=======================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimrodversion|
|
||||
|
||||
@@ -164,20 +164,10 @@ Index switch
|
||||
nimrod doc2 --index:on filename.nim
|
||||
|
||||
This will generate an index of all the exported symbols in the input Nimrod
|
||||
module, and put it into a neighboring file with the extension of `.idx`. The
|
||||
index file is line oriented (newlines have to be escaped). Each line represents
|
||||
a tab separated record of several columns, the first two mandatory, the rest
|
||||
optional:
|
||||
|
||||
1. Mandatory term being indexed. Terms can include quoting according to
|
||||
Nimrod's rules (eg. ```^```)
|
||||
2. Base filename plus anchor hyper link (eg.
|
||||
``algorithm.html#*,int,TSortOrder``).
|
||||
3. Optional human readable string to display as hyper link. If the value is not
|
||||
present or is the empty string, the hyper link will be rendered using the
|
||||
term.
|
||||
4. Optional title or description of the hyper link. Browsers usually display
|
||||
this as a tooltip after hovering a moment over the hyper link.
|
||||
module, and put it into a neighboring file with the extension of ``.idx``. The
|
||||
index file is line oriented (newlines have to be escaped). Each line
|
||||
represents a tab separated record of several columns, the first two mandatory,
|
||||
the rest optional. See the `Index (idx) file format`_ section for details.
|
||||
|
||||
Once index files have been generated for one or more modules, the Nimrod
|
||||
compiler command ``buildIndex directory`` can be run to go over all the index
|
||||
@@ -295,6 +285,60 @@ symbols in the `system module <system.html>`_.
|
||||
<system.html#newException.t,typedesc,string>`_
|
||||
|
||||
|
||||
Index (idx) file format
|
||||
=======================
|
||||
|
||||
Files with the ``.idx`` extension are generated when you use the `Index
|
||||
switch`_ along with commands to generate documentation from source or text
|
||||
files. You can programatically generate indices with the `setIndexTerm()
|
||||
<rstgen.html#setIndexTerm>`_ and `writeIndexFile()
|
||||
<rstgen.html#writeIndexFile>`_ procs. The purpose of ``idx`` files is to hold
|
||||
the interesting symbols and their HTML references so they can be later
|
||||
concatenated into a big index file with `mergeIndexes()
|
||||
<rstgen.html#mergeIndexes>`_. This section documents the file format in
|
||||
detail.
|
||||
|
||||
Index files are line oriented and tab separated (newline and tab characters
|
||||
have to be escaped). Each line represents a record with at least two fields,
|
||||
but can have up to four (additional columns are ignored). The content of these
|
||||
columns is:
|
||||
|
||||
1. Mandatory term being indexed. Terms can include quoting according to
|
||||
Nimrod's rules (eg. \`^\` like in `the actors module
|
||||
<actors.html#^,ptr.TChannel[T]>`_).
|
||||
2. Base filename plus anchor hyper link (eg.
|
||||
``algorithm.html#*,int,TSortOrder``).
|
||||
3. Optional human readable string to display as hyper link. If the value is not
|
||||
present or is the empty string, the hyper link will be rendered
|
||||
using the term. Prefix whitespace indicates that this entry is
|
||||
not for an API symbol but for a TOC entry.
|
||||
4. Optional title or description of the hyper link. Browsers usually display
|
||||
this as a tooltip after hovering a moment over the hyper link.
|
||||
|
||||
The index generation tools try to differentiate between documentation
|
||||
generated from ``.nim`` files and documentation generated from ``.txt`` or
|
||||
``.rst`` files. The former are always closely related to source code and
|
||||
consist mainly of API entries. The latter are generic documents meant for
|
||||
human reading.
|
||||
|
||||
To differentiate both types (documents and APIs), the index generator will add
|
||||
to the index of documents an entry with the title of the document. Since the
|
||||
title is the topmost element, it will be added with a second field containing
|
||||
just the filename without any HTML anchor. By convention this entry without
|
||||
anchor is the *title entry*, and since entries in the index file are added as
|
||||
they are scanned, the title entry will be the first line. The title for APIs
|
||||
is not present because it can be generated concatenating the name of the file
|
||||
to the word **Module**.
|
||||
|
||||
Normal symbols are added to the index with surrounding whitespaces removed. An
|
||||
exception to this are table of content (TOC) entries. TOC entries are added to
|
||||
the index file with their third column having as much prefix spaces as their
|
||||
level is in the TOC (at least 1 character). The prefix whitespace helps to
|
||||
filter TOC entries from API or text symbols. This is important because the
|
||||
amount of spaces is used to replicate the hiearchy for document TOCs in the
|
||||
final index, and TOC entries found in ``.nim`` files are discarded.
|
||||
|
||||
|
||||
Additional resources
|
||||
====================
|
||||
|
||||
|
||||
12
doc/endb.txt
12
doc/endb.txt
@@ -1,6 +1,6 @@
|
||||
===========================================
|
||||
Embedded Nimrod Debugger User Guide
|
||||
===========================================
|
||||
==============================================
|
||||
Embedded Nimrod Debugger (ENDB) User Guide
|
||||
==============================================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimrodversion|
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
Nimrod comes with a platform independent debugger -
|
||||
the `Embedded Nimrod Debugger`:idx: (`ENDB`:idx:). The debugger is
|
||||
the Embedded Nimrod Debugger (ENDB). The debugger is
|
||||
*embedded* into your executable if it has been
|
||||
compiled with the ``--debugger:on`` command line option.
|
||||
This also defines the conditional symbol ``ENDB`` for you.
|
||||
@@ -102,7 +102,7 @@ necessary: A special pragma has been defined for this:
|
||||
The ``breakpoint`` pragma
|
||||
-------------------------
|
||||
|
||||
The `breakpoint`:idx: pragma is syntactically a statement. It can be used
|
||||
The ``breakpoint`` pragma is syntactically a statement. It can be used
|
||||
to mark the *following line* as a breakpoint:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
@@ -122,7 +122,7 @@ debugging.
|
||||
The ``watchpoint`` pragma
|
||||
-------------------------
|
||||
|
||||
The `watchpoint`:idx: pragma is syntactically a statement. It can be used
|
||||
The ``watchpoint`` pragma is syntactically a statement. It can be used
|
||||
to mark a location as a watchpoint:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
============================================
|
||||
Embedded Stack Trace Profiler User Guide
|
||||
============================================
|
||||
===================================================
|
||||
Embedded Stack Trace Profiler (ESTP) User Guide
|
||||
===================================================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimrodversion|
|
||||
|
||||
|
||||
Nimrod comes with a platform independent profiler -
|
||||
the `Embedded Stack Trace Profiler`:idx: (`ESTP`:idx:). The profiler
|
||||
the Embedded Stack Trace Profiler (ESTP). The profiler
|
||||
is *embedded* into your executable. To activate the profiler you need to do:
|
||||
|
||||
* compile your program with the ``--profiler:on --stackTrace:on`` command
|
||||
|
||||
@@ -26,7 +26,7 @@ available parameters depend on the invoked filter.
|
||||
Pipe operator
|
||||
=============
|
||||
|
||||
Filters can be combined with the ``|`` `pipe operator`:idx:\ ::
|
||||
Filters can be combined with the ``|`` pipe operator::
|
||||
|
||||
#! strip(startswith="<") | stdtmpl
|
||||
#proc generateXML(name, age: string): string =
|
||||
@@ -46,7 +46,7 @@ after each filter application.
|
||||
Replace filter
|
||||
--------------
|
||||
|
||||
The `replace`:idx: filter replaces substrings in each line.
|
||||
The replace filter replaces substrings in each line.
|
||||
|
||||
Parameters and their defaults:
|
||||
|
||||
@@ -60,7 +60,7 @@ Parameters and their defaults:
|
||||
Strip filter
|
||||
------------
|
||||
|
||||
The `strip`:idx: filter simply removes leading and trailing whitespace from
|
||||
The strip filter simply removes leading and trailing whitespace from
|
||||
each line.
|
||||
|
||||
Parameters and their defaults:
|
||||
@@ -79,7 +79,7 @@ Parameters and their defaults:
|
||||
StdTmpl filter
|
||||
--------------
|
||||
|
||||
The `stdtmpl`:idx: filter provides a simple templating engine for Nimrod. The
|
||||
The stdtmpl filter provides a simple templating engine for Nimrod. The
|
||||
filter uses a line based parser: Lines prefixed with a *meta character*
|
||||
(default: ``#``) contain Nimrod code, other lines are verbatim. Because
|
||||
indentation-based parsing is not suited for a templating engine, control flow
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
Nimrod differs from many other compilers in that it is really fast,
|
||||
and being so fast makes it suited to provide external queries for
|
||||
text editors about the source code being written. Through the
|
||||
`idetools`:idx: command of `the compiler <nimrodc.html>`_, any IDE
|
||||
``idetools`` command of `the compiler <nimrodc.html>`_, any IDE
|
||||
can query a ``.nim`` source file and obtain useful information like
|
||||
definition of symbols or suggestions for completion.
|
||||
|
||||
@@ -169,7 +169,7 @@ clicks it and after a second or two the IDE displays where that
|
||||
symbol is defined. Such latencies would be terrible for features
|
||||
like symbol suggestion, plus why wait at all if we can avoid it?
|
||||
|
||||
The idetools command can be run as a compiler service (`caas`:idx:),
|
||||
The idetools command can be run as a compiler service (CAAS),
|
||||
where you first launch the compiler and it will stay online as a
|
||||
server, accepting queries in a telnet like fashion. The advantage
|
||||
of staying on is that for many queries the compiler can cache the
|
||||
|
||||
@@ -69,8 +69,10 @@ Coding Guidelines
|
||||
* Max line length is 80 characters.
|
||||
* Provide spaces around binary operators if that enhances readability.
|
||||
* Use a space after a colon, but not before it.
|
||||
* Start types with a capital ``T``, unless they are pointers/references which start
|
||||
with ``P``.
|
||||
* Start types with a capital ``T``, unless they are pointers/references which
|
||||
start with ``P``.
|
||||
|
||||
See also the `API naming design <apis.html>`_ document.
|
||||
|
||||
|
||||
Porting to new platforms
|
||||
@@ -156,7 +158,7 @@ generator.
|
||||
Compilation cache
|
||||
=================
|
||||
|
||||
The implementation of the `compilation cache`:idx: is tricky: There are lots
|
||||
The implementation of the compilation cache is tricky: There are lots
|
||||
of issues to be solved for the front- and backend. In the following
|
||||
sections *global* means *shared between modules* or *property of the whole
|
||||
program*.
|
||||
|
||||
220
doc/manual.txt
220
doc/manual.txt
@@ -152,7 +152,7 @@ statements (simplified example)::
|
||||
Comments
|
||||
--------
|
||||
|
||||
`Comments`:idx: start anywhere outside a string or character literal with the
|
||||
Comments start anywhere outside a string or character literal with the
|
||||
hash character ``#``.
|
||||
Comments consist of a concatenation of `comment pieces`:idx:. A comment piece
|
||||
starts with ``#`` and runs until the end of the line. The end of line characters
|
||||
@@ -188,7 +188,7 @@ which code snippet the comment refers to.
|
||||
Identifiers & Keywords
|
||||
----------------------
|
||||
|
||||
`Identifiers`:idx: in Nimrod can be any string of letters, digits
|
||||
Identifiers in Nimrod can be any string of letters, digits
|
||||
and underscores, beginning with a letter. Two immediate following
|
||||
underscores ``__`` are not allowed::
|
||||
|
||||
@@ -201,7 +201,7 @@ classified as a ``letter`` and may thus be part of an identifier but later
|
||||
versions of the language may assign some Unicode characters to belong to the
|
||||
operator characters instead.
|
||||
|
||||
The following `keywords`:idx: are reserved and cannot be used as identifiers:
|
||||
The following keywords are reserved and cannot be used as identifiers:
|
||||
|
||||
.. code-block:: nimrod
|
||||
:file: keywords.txt
|
||||
@@ -224,7 +224,7 @@ String literals
|
||||
|
||||
Terminal symbol in the grammar: ``STR_LIT``.
|
||||
|
||||
`String literals`:idx: can be delimited by matching double quotes, and can
|
||||
String literals can be delimited by matching double quotes, and can
|
||||
contain the following `escape sequences`:idx:\ :
|
||||
|
||||
================== ===================================================
|
||||
@@ -280,7 +280,7 @@ Raw string literals
|
||||
|
||||
Terminal symbol in the grammar: ``RSTR_LIT``.
|
||||
|
||||
There are also `raw string literals`:idx: that are preceded with the
|
||||
There are also raw string literals that are preceded with the
|
||||
letter ``r`` (or ``R``) and are delimited by matching double quotes (just
|
||||
like ordinary string literals) and do not interpret the escape sequences.
|
||||
This is especially convenient for regular expressions or Windows paths:
|
||||
@@ -313,7 +313,7 @@ Terminal symbols in the grammar: ``GENERALIZED_STR_LIT``,
|
||||
|
||||
The construct ``identifier"string literal"`` (without whitespace between the
|
||||
identifier and the opening quotation mark) is a
|
||||
`generalized raw string literal`:idx:. It is a shortcut for the construct
|
||||
generalized raw string literal. It is a shortcut for the construct
|
||||
``identifier(r"string literal")``, so it denotes a procedure call with a
|
||||
raw string literal as its only argument. Generalized raw string literals
|
||||
are especially convenient for embedding mini languages directly into Nimrod
|
||||
@@ -365,7 +365,7 @@ type is used for Unicode characters, it can represent any Unicode character.
|
||||
Numerical constants
|
||||
-------------------
|
||||
|
||||
`Numerical constants`:idx: are of a single type and have the form::
|
||||
Numerical constants are of a single type and have the form::
|
||||
|
||||
hexdigit = digit | 'A'..'F' | 'a'..'f'
|
||||
octdigit = '0'..'7'
|
||||
@@ -440,7 +440,7 @@ is approximately 1.72826e35 according to the IEEE floating point standard.
|
||||
Operators
|
||||
---------
|
||||
|
||||
In Nimrod one can define his own operators. An `operator`:idx: is any
|
||||
In Nimrod one can define his own operators. An operator is any
|
||||
combination of the following characters::
|
||||
|
||||
= + - * / < >
|
||||
@@ -587,7 +587,7 @@ The grammar's start symbol is ``module``.
|
||||
Types
|
||||
=====
|
||||
|
||||
All expressions have a `type`:idx: which is known at compile time. Nimrod
|
||||
All expressions have a type which is known at compile time. Nimrod
|
||||
is statically typed. One can declare new types, which is in essence defining
|
||||
an identifier that can be used to denote this custom type.
|
||||
|
||||
@@ -605,7 +605,7 @@ These are the major type classes:
|
||||
|
||||
Ordinal types
|
||||
-------------
|
||||
`Ordinal types`:idx: have the following characteristics:
|
||||
Ordinal types have the following characteristics:
|
||||
|
||||
- Ordinal types are countable and ordered. This property allows
|
||||
the operation of functions as ``Inc``, ``Ord``, ``Dec`` on ordinal types to
|
||||
@@ -705,7 +705,7 @@ For further details, see `Convertible relation`_.
|
||||
|
||||
Subrange types
|
||||
--------------
|
||||
A `subrange`:idx: type is a range of values from an ordinal type (the base
|
||||
A subrange type is a range of values from an ordinal type (the base
|
||||
type). To define a subrange type, one must specify it's limiting values: the
|
||||
lowest and highest value of the type:
|
||||
|
||||
@@ -806,7 +806,7 @@ the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
|
||||
|
||||
Boolean type
|
||||
------------
|
||||
The `boolean`:idx: type is named `bool`:idx: in Nimrod and can be one of the two
|
||||
The boolean type is named `bool`:idx: in Nimrod and can be one of the two
|
||||
pre-defined values ``true`` and ``false``. Conditions in while,
|
||||
if, elif, when statements need to be of type bool.
|
||||
|
||||
@@ -830,7 +830,7 @@ The size of the bool type is one byte.
|
||||
|
||||
Character type
|
||||
--------------
|
||||
The `character type`:idx: is named ``char`` in Nimrod. Its size is one byte.
|
||||
The character type is named ``char`` in Nimrod. Its size is one byte.
|
||||
Thus it cannot represent an UTF-8 character, but a part of it.
|
||||
The reason for this is efficiency: for the overwhelming majority of use-cases,
|
||||
the resulting programs will still handle UTF-8 properly as UTF-8 was specially
|
||||
@@ -845,7 +845,7 @@ character. ``TRune`` is declared in the `unicode module <unicode.html>`_.
|
||||
|
||||
Enumeration types
|
||||
-----------------
|
||||
`Enumeration`:idx: types define a new type whose values consist of the ones
|
||||
Enumeration types define a new type whose values consist of the ones
|
||||
specified. The values are ordered. Example:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -915,7 +915,7 @@ via ``TMyEnum.value``:
|
||||
|
||||
String type
|
||||
-----------
|
||||
All string literals are of the type `string`:idx:. A string in Nimrod is very
|
||||
All string literals are of the type ``string``. A string in Nimrod is very
|
||||
similar to a sequence of characters. However, strings in Nimrod are both
|
||||
zero-terminated and have a length field. One can retrieve the length with the
|
||||
builtin ``len`` procedure; the length never counts the terminating zero.
|
||||
@@ -942,7 +942,7 @@ i-th *unichar*. The iterator ``runes`` from the `unicode module
|
||||
|
||||
CString type
|
||||
------------
|
||||
The `cstring`:idx: type represents a pointer to a zero-terminated char array
|
||||
The ``cstring`` type represents a pointer to a zero-terminated char array
|
||||
compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
|
||||
interfacing with C. The index operation ``s[i]`` means the i-th *char* of
|
||||
``s``; however no bounds checking for ``cstring`` is performed making the
|
||||
@@ -976,20 +976,20 @@ string from a cstring:
|
||||
|
||||
Structured types
|
||||
----------------
|
||||
A variable of a `structured type`:idx: can hold multiple values at the same
|
||||
A variable of a structured type can hold multiple values at the same
|
||||
time. Structured types can be nested to unlimited levels. Arrays, sequences,
|
||||
tuples, objects and sets belong to the structured types.
|
||||
|
||||
Array and sequence types
|
||||
------------------------
|
||||
`Arrays`:idx: are a homogeneous type, meaning that each element in the array
|
||||
Arrays are a homogeneous type, meaning that each element in the array
|
||||
has the same type. Arrays always have a fixed length which is specified at
|
||||
compile time (except for open arrays). They can be indexed by any ordinal type.
|
||||
A parameter ``A`` may be an *open array*, in which case it is indexed by
|
||||
integers from 0 to ``len(A)-1``. An array expression may be constructed by the
|
||||
array constructor ``[]``.
|
||||
|
||||
`Sequences`:idx: are similar to arrays but of dynamic length which may change
|
||||
Sequences are similar to arrays but of dynamic length which may change
|
||||
during runtime (like strings). Sequences are implemented as growable arrays,
|
||||
allocating pieces of memory as items are added. A sequence ``S`` is always
|
||||
indexed by integers from 0 to ``len(S)-1`` and its bounds are checked.
|
||||
@@ -1046,7 +1046,7 @@ supported because this is seldom needed and cannot be done efficiently.
|
||||
Varargs
|
||||
-------
|
||||
|
||||
A `varargs`:idx: parameter is an openarray parameter that additionally
|
||||
A ``varargs`` parameter is an openarray parameter that additionally
|
||||
allows to pass a variable number of arguments to a procedure. The compiler
|
||||
converts the list of arguments to an array implicitly:
|
||||
|
||||
@@ -1081,7 +1081,7 @@ parameter ``a``. (Note that ``$`` applied to strings is a nop.)
|
||||
|
||||
Tuples and object types
|
||||
-----------------------
|
||||
A variable of a `tuple`:idx: or `object`:idx: type is a heterogeneous storage
|
||||
A variable of a tuple or object type is a heterogeneous storage
|
||||
container.
|
||||
A tuple or object defines various named *fields* of a type. A tuple also
|
||||
defines an *order* of the fields. Tuples are meant for heterogeneous storage
|
||||
@@ -1161,7 +1161,7 @@ For a ``ref object`` type ``system.new`` is invoked implicitly.
|
||||
Object variants
|
||||
---------------
|
||||
Often an object hierarchy is overkill in certain situations where simple
|
||||
`variant`:idx: types are needed.
|
||||
variant types are needed.
|
||||
|
||||
An example:
|
||||
|
||||
@@ -1219,7 +1219,7 @@ branch switch ``system.reset`` has to be used.
|
||||
|
||||
Set type
|
||||
--------
|
||||
The `set type`:idx: models the mathematical notion of a set. The set's
|
||||
The set type models the mathematical notion of a set. The set's
|
||||
basetype can only be an ordinal type. The reason is that sets are implemented
|
||||
as high performance bit vectors.
|
||||
|
||||
@@ -1254,7 +1254,7 @@ operation meaning
|
||||
|
||||
Reference and pointer types
|
||||
---------------------------
|
||||
References (similar to `pointers`:idx: in other programming languages) are a
|
||||
References (similar to pointers in other programming languages) are a
|
||||
way to introduce many-to-one relationships. This means different references can
|
||||
point to and modify the same location in memory (also called `aliasing`:idx:).
|
||||
|
||||
@@ -1352,7 +1352,7 @@ Not nil annotation
|
||||
------------------
|
||||
|
||||
All types for that ``nil`` is a valid value can be annotated to
|
||||
exclude ``nil`` as a valid value with the `not nil`:idx: annotation:
|
||||
exclude ``nil`` as a valid value with the ``not nil`` annotation:
|
||||
|
||||
.. code-block:: nimrod
|
||||
type
|
||||
@@ -1377,7 +1377,7 @@ here.
|
||||
Memory regions
|
||||
--------------
|
||||
|
||||
The types ``ref`` and ``ptr`` can get an optional `region`:idx: annotation.
|
||||
The types ``ref`` and ``ptr`` can get an optional ``region`` annotation.
|
||||
A region has to be an object type.
|
||||
|
||||
Regions are very useful to separate user space and kernel memory in the
|
||||
@@ -1436,7 +1436,7 @@ Future directions:
|
||||
|
||||
Procedural type
|
||||
---------------
|
||||
A `procedural type`:idx: is internally a pointer to a procedure. ``nil`` is
|
||||
A procedural type is internally a pointer to a procedure. ``nil`` is
|
||||
an allowed value for variables of a procedural type. Nimrod uses procedural
|
||||
types to achieve `functional`:idx: programming techniques.
|
||||
|
||||
@@ -1544,7 +1544,7 @@ accesses its environment. If it does so, it has the calling convention
|
||||
Distinct type
|
||||
-------------
|
||||
|
||||
A `distinct type`:idx: is new type derived from a `base type`:idx: that is
|
||||
A ``distinct`` type is new type derived from a `base type`:idx: that is
|
||||
incompatible with its base type. In particular, it is an essential property
|
||||
of a distinct type that it **does not** imply a subtype relation between it
|
||||
and its base type. Explicit type conversions from a distinct type to its
|
||||
@@ -1727,7 +1727,7 @@ modules like `db_sqlite <db_sqlite.html>`_.
|
||||
Void type
|
||||
---------
|
||||
|
||||
The `void`:idx: type denotes the absense of any type. Parameters of
|
||||
The ``void`` type denotes the absense of any type. Parameters of
|
||||
type ``void`` are treated as non-existent, ``void`` as a return type means that
|
||||
the procedure does not return a value:
|
||||
|
||||
@@ -1960,7 +1960,7 @@ To be written.
|
||||
Statements and expressions
|
||||
==========================
|
||||
|
||||
Nimrod uses the common statement/expression paradigm: `Statements`:idx: do not
|
||||
Nimrod uses the common statement/expression paradigm: Statements do not
|
||||
produce a value in contrast to expressions. However, some expressions are
|
||||
statements.
|
||||
|
||||
@@ -1977,7 +1977,7 @@ Statement list expression
|
||||
|
||||
Statements can also occur in an expression context that looks
|
||||
like ``(stmt1; stmt2; ...; ex)``. This is called
|
||||
an `statement list expression`:idx: or ``(;)``. The type
|
||||
an statement list expression or ``(;)``. The type
|
||||
of ``(stmt1; stmt2; ...; ex)`` is the type of ``ex``. All the other statements
|
||||
must be of type ``void``. (One can use ``discard`` to produce a ``void`` type.)
|
||||
``(;)`` does not introduce a new scope.
|
||||
@@ -1994,7 +1994,7 @@ Example:
|
||||
|
||||
discard p(3, 4) # discard the return value of `p`
|
||||
|
||||
The `discard`:idx: statement evaluates its expression for side-effects and
|
||||
The ``discard`` statement evaluates its expression for side-effects and
|
||||
throws the expression's resulting value away.
|
||||
|
||||
Ignoring the return value of a procedure without using a discard statement is
|
||||
@@ -2022,7 +2022,7 @@ An empty ``discard`` statement is often used as a null statement:
|
||||
Var statement
|
||||
-------------
|
||||
|
||||
`Var`:idx: statements declare new local and global variables and
|
||||
Var statements declare new local and global variables and
|
||||
initialize them. A comma separated list of variables can be used to specify
|
||||
variables of the same type:
|
||||
|
||||
@@ -2091,7 +2091,7 @@ initialized and does not rely on syntactic properties:
|
||||
let statement
|
||||
-------------
|
||||
|
||||
A `Let`:idx: statement declares new local and global `single assignment`:idx:
|
||||
A ``let`` statement declares new local and global `single assignment`:idx:
|
||||
variables and binds a value to them. The syntax is the of the ``var``
|
||||
statement, except that the keyword ``var`` is replaced by the keyword ``let``.
|
||||
Let variables are not l-values and can thus not be passed to ``var`` parameters
|
||||
@@ -2133,7 +2133,7 @@ they contain such a type.
|
||||
Static statement/expression
|
||||
---------------------------
|
||||
|
||||
A `static`:idx: statement/expression can be used to enforce compile
|
||||
A static statement/expression can be used to enforce compile
|
||||
time evaluation explicitly. Enforced compile time evaluation can even evaluate
|
||||
code that has side effects:
|
||||
|
||||
@@ -2167,7 +2167,7 @@ Example:
|
||||
else:
|
||||
echo("Boring name...")
|
||||
|
||||
The `if`:idx: statement is a simple way to make a branch in the control flow:
|
||||
The ``if`` statement is a simple way to make a branch in the control flow:
|
||||
The expression after the keyword ``if`` is evaluated, if it is true
|
||||
the corresponding statements after the ``:`` are executed. Otherwise
|
||||
the expression after the ``elif`` is evaluated (if there is an
|
||||
@@ -2213,7 +2213,7 @@ Example:
|
||||
else: echo("unknown command")
|
||||
|
||||
|
||||
The `case`:idx: statement is similar to the if statement, but it represents
|
||||
The ``case`` statement is similar to the if statement, but it represents
|
||||
a multi-branch selection. The expression after the keyword ``case`` is
|
||||
evaluated and if its value is in a *slicelist* the corresponding statements
|
||||
(after the ``of`` keyword) are executed. If the value is not in any
|
||||
@@ -2267,7 +2267,7 @@ Example:
|
||||
else:
|
||||
echo("cannot happen!")
|
||||
|
||||
The `when`:idx: statement is almost identical to the ``if`` statement with some
|
||||
The ``when`` statement is almost identical to the ``if`` statement with some
|
||||
exceptions:
|
||||
|
||||
* Each condition (``expr``) has to be a constant expression (of type ``bool``).
|
||||
@@ -2289,7 +2289,7 @@ Example:
|
||||
.. code-block:: nimrod
|
||||
return 40+2
|
||||
|
||||
The `return`:idx: statement ends the execution of the current procedure.
|
||||
The ``return`` statement ends the execution of the current procedure.
|
||||
It is only allowed in procedures. If there is an ``expr``, this is syntactic
|
||||
sugar for:
|
||||
|
||||
@@ -2316,7 +2316,7 @@ Example:
|
||||
.. code-block:: nimrod
|
||||
yield (1, 2, 3)
|
||||
|
||||
The `yield`:idx: statement is used instead of the ``return`` statement in
|
||||
The ``yield`` statement is used instead of the ``return`` statement in
|
||||
iterators. It is only valid in iterators. Execution is returned to the body
|
||||
of the for loop that called the iterator. Yield does not end the iteration
|
||||
process, but execution is passed back to the iterator if the next iteration
|
||||
@@ -2339,7 +2339,7 @@ Example:
|
||||
break myblock # leave the block, in this case both for-loops
|
||||
echo(found)
|
||||
|
||||
The block statement is a means to group statements to a (named) `block`:idx:.
|
||||
The block statement is a means to group statements to a (named) ``block``.
|
||||
Inside the block, the ``break`` statement is allowed to leave the block
|
||||
immediately. A ``break`` statement can contain a name of a surrounding
|
||||
block to specify which block is to leave.
|
||||
@@ -2353,7 +2353,7 @@ Example:
|
||||
.. code-block:: nimrod
|
||||
break
|
||||
|
||||
The `break`:idx: statement is used to leave a block immediately. If ``symbol``
|
||||
The ``break`` statement is used to leave a block immediately. If ``symbol``
|
||||
is given, it is the name of the enclosing block that is to leave. If it is
|
||||
absent, the innermost block is left.
|
||||
|
||||
@@ -2371,7 +2371,7 @@ Example:
|
||||
pw = readLine(stdin)
|
||||
|
||||
|
||||
The `while`:idx: statement is executed until the ``expr`` evaluates to false.
|
||||
The ``while`` statement is executed until the ``expr`` evaluates to false.
|
||||
Endless loops are no error. ``while`` statements open an `implicit block`,
|
||||
so that they can be left with a ``break`` statement.
|
||||
|
||||
@@ -2379,7 +2379,7 @@ so that they can be left with a ``break`` statement.
|
||||
Continue statement
|
||||
------------------
|
||||
|
||||
A `continue`:idx: statement leads to the immediate next iteration of the
|
||||
A ``continue`` statement leads to the immediate next iteration of the
|
||||
surrounding loop construct. It is only allowed within a loop. A continue
|
||||
statement is syntactic sugar for a nested block:
|
||||
|
||||
@@ -2402,7 +2402,7 @@ Is equivalent to:
|
||||
Assembler statement
|
||||
-------------------
|
||||
|
||||
The direct embedding of `assembler`:idx: code into Nimrod code is supported
|
||||
The direct embedding of assembler code into Nimrod code is supported
|
||||
by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to
|
||||
Nimrod identifiers shall be enclosed in a special character which can be
|
||||
specified in the statement's pragmas. The default special character is ``'`'``:
|
||||
@@ -2449,7 +2449,7 @@ Using statement
|
||||
|
||||
**Warning**: The ``using`` statement is highly experimental!
|
||||
|
||||
The `using statement`:idx: provides syntactic convenience for procs that
|
||||
The using statement provides syntactic convenience for procs that
|
||||
heavily use a single contextual parameter. When applied to a variable or a
|
||||
constant, it will instruct Nimrod to automatically consider the used symbol as
|
||||
a hidden leading parameter for any procedure calls, following the using
|
||||
@@ -2534,7 +2534,7 @@ the last expression as the result value, much like in an `expr` template.
|
||||
Table constructor
|
||||
-----------------
|
||||
|
||||
A `table constructor`:idx: is syntactic sugar for an array constructor:
|
||||
A table constructor is syntactic sugar for an array constructor:
|
||||
|
||||
.. code-block:: nimrod
|
||||
{"key1": "value1", "key2", "key3": "value2"}
|
||||
@@ -2581,7 +2581,7 @@ only needed for low-level programming and are inherently unsafe.
|
||||
|
||||
The addr operator
|
||||
-----------------
|
||||
The `addr`:idx: operator returns the address of an l-value. If the type of the
|
||||
The ``addr`` operator returns the address of an l-value. If the type of the
|
||||
location is ``T``, the `addr` operator result is of the type ``ptr T``. An
|
||||
address is always an untraced reference. Taking the address of an object that
|
||||
resides on the stack is **unsafe**, as the pointer may live longer than the
|
||||
@@ -2682,7 +2682,7 @@ For object oriented programming, the syntax ``obj.method(args)`` can be used
|
||||
instead of ``method(obj, args)``. The parentheses can be omitted if there are no
|
||||
remaining arguments: ``obj.len`` (instead of ``len(obj)``).
|
||||
|
||||
This `method call syntax`:idx: is not restricted to objects, it can be used
|
||||
This method call syntax is not restricted to objects, it can be used
|
||||
to supply any type of first argument for procedures:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -2727,7 +2727,7 @@ Command invocation syntax
|
||||
-------------------------
|
||||
|
||||
Routines can be invoked without the ``()`` if the call is syntatically
|
||||
a statement. This `command invocation syntax`:idx: also works for
|
||||
a statement. This command invocation syntax also works for
|
||||
expressions, but then only a single argument may follow. This restriction
|
||||
means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as
|
||||
``echo(f(1, f(2)))``. The method call syntax may be used to provide one
|
||||
@@ -2924,7 +2924,7 @@ The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
|
||||
Multi-methods
|
||||
=============
|
||||
|
||||
Procedures always use static dispatch. `Multi-methods`:idx: use dynamic
|
||||
Procedures always use static dispatch. Multi-methods use dynamic
|
||||
dispatch.
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -3177,7 +3177,7 @@ Example:
|
||||
line: int # the line the symbol was declared in
|
||||
code: PNode # the symbol's abstract syntax tree
|
||||
|
||||
A `type`:idx: section begins with the ``type`` keyword. It contains multiple
|
||||
A type section begins with the ``type`` keyword. It contains multiple
|
||||
type definitions. A type definition binds a type to a name. Type definitions
|
||||
can be recursive or even mutually recursive. Mutually recursive types are only
|
||||
possible within a single ``type`` section. Nominal types like ``objects``
|
||||
@@ -3214,7 +3214,7 @@ Example:
|
||||
close(f)
|
||||
|
||||
|
||||
The statements after the `try`:idx: are executed in sequential order unless
|
||||
The statements after the ``try`` are executed in sequential order unless
|
||||
an exception ``e`` is raised. If the exception type of ``e`` matches any
|
||||
listed in an ``except`` clause the corresponding statements are executed.
|
||||
The statements following the ``except`` clauses are called
|
||||
@@ -3236,7 +3236,7 @@ is not executed (if an exception occurs).
|
||||
Except and finally statements
|
||||
-----------------------------
|
||||
|
||||
`except`:idx: and `finally`:idx: can also be used as a stand-alone statements.
|
||||
``except`` and ``finally`` can also be used as a stand-alone statements.
|
||||
Any statements following them in the current block will be considered to be
|
||||
in an implicit try block:
|
||||
|
||||
@@ -3285,9 +3285,9 @@ exception (unless a raise hook has been provided).
|
||||
OnRaise builtin
|
||||
---------------
|
||||
|
||||
``system.onRaise`` can be used to override the behaviour of ``raise`` for a
|
||||
single ``try`` statement. `onRaise`:idx: has to be called within the ``try``
|
||||
statement that should be affected.
|
||||
`system.onRaise() <system.html#onRaise>`_ can be used to override the
|
||||
behaviour of ``raise`` for a single ``try`` statement. ``onRaise`` has to be
|
||||
called within the ``try`` statement that should be affected.
|
||||
|
||||
This allows for a Lisp-like `condition system`:idx:\:
|
||||
|
||||
@@ -3316,7 +3316,7 @@ Effect system
|
||||
Exception tracking
|
||||
------------------
|
||||
|
||||
Nimrod supports `exception tracking`:idx:. The `raises`:idx: pragma can be used
|
||||
Nimrod supports exception tracking. The `raises`:idx: pragma can be used
|
||||
to explicitly define which exceptions a proc/iterator/method/converter is
|
||||
allowed to raise. The compiler verifies this:
|
||||
|
||||
@@ -3424,7 +3424,7 @@ exception tracking.
|
||||
Effects pragma
|
||||
--------------
|
||||
|
||||
The `effects`:idx: pragma has been designed to assist the programmer with the
|
||||
The ``effects`` pragma has been designed to assist the programmer with the
|
||||
effects analysis. It is a statement that makes the compiler output all inferred
|
||||
effects up to the ``effects``'s position:
|
||||
|
||||
@@ -3493,7 +3493,7 @@ Example:
|
||||
for str in inorder(root):
|
||||
writeln(stdout, str)
|
||||
|
||||
`Generics`:idx: are Nimrod's means to parametrize procs, iterators or types with
|
||||
Generics are Nimrod's means to parametrize procs, iterators or types with
|
||||
`type parameters`:idx:. Depending on context, the brackets are used either to
|
||||
introduce type parameters or to instantiate a generic proc, iterator or type.
|
||||
|
||||
@@ -3501,7 +3501,7 @@ introduce type parameters or to instantiate a generic proc, iterator or type.
|
||||
Is operator
|
||||
-----------
|
||||
|
||||
The `is`:idx: operator checks for type equivalence at compile time. It is
|
||||
The ``is`` operator checks for type equivalence at compile time. It is
|
||||
therefore very useful for type specialization within generic code:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -3516,7 +3516,7 @@ therefore very useful for type specialization within generic code:
|
||||
Type operator
|
||||
-------------
|
||||
|
||||
The `type`:idx: (in many other languages called `typeof`:idx:) operator can
|
||||
The ``type`` (in many other languages called `typeof`:idx:) operator can
|
||||
be used to get the type of an expression:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -3539,7 +3539,7 @@ other interpretations:
|
||||
Type Classes
|
||||
------------
|
||||
|
||||
A `type class`:idx: is a special pseudo-type that can be used to match against
|
||||
A type class is a special pseudo-type that can be used to match against
|
||||
types in the context of overload resolution or the ``is`` operator.
|
||||
Nimrod supports the following built-in type classes:
|
||||
|
||||
@@ -3757,7 +3757,7 @@ A symbol can be forced to be open by a `mixin`:idx: declaration:
|
||||
Bind statement
|
||||
--------------
|
||||
|
||||
The `bind`:idx: statement is the counterpart to the ``mixin`` statement. It
|
||||
The ``bind`` statement is the counterpart to the ``mixin`` statement. It
|
||||
can be used to explicitly declare identifiers that should be bound early (i.e.
|
||||
the identifiers should be looked up in the scope of the template/generic
|
||||
definition):
|
||||
@@ -3785,7 +3785,7 @@ scope is the default.
|
||||
Templates
|
||||
=========
|
||||
|
||||
A `template`:idx: is a simple form of a macro: It is a simple substitution
|
||||
A template is a simple form of a macro: It is a simple substitution
|
||||
mechanism that operates on Nimrod's abstract syntax trees. It is processed in
|
||||
the semantic pass of the compiler.
|
||||
|
||||
@@ -3817,7 +3817,7 @@ expected.
|
||||
Ordinary vs immediate templates
|
||||
-------------------------------
|
||||
|
||||
There are two different kinds of templates: `immediate`:idx: templates and
|
||||
There are two different kinds of templates: immediate templates and
|
||||
ordinary templates. Ordinary templates take part in overloading resolution. As
|
||||
such their arguments need to be type checked before the template is invoked.
|
||||
So ordinary templates cannot receive undeclared identifiers:
|
||||
@@ -4012,7 +4012,7 @@ a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
|
||||
Macros
|
||||
======
|
||||
|
||||
A `macro`:idx: is a special kind of low level template. Macros can be used
|
||||
A macro is a special kind of low level template. Macros can be used
|
||||
to implement `domain specific languages`:idx:. Like templates, macros come in
|
||||
the 2 flavors *immediate* and *ordinary*.
|
||||
|
||||
@@ -4390,7 +4390,7 @@ This operator will be matched against assignments to missing fields.
|
||||
Term rewriting macros
|
||||
=====================
|
||||
|
||||
`Term rewriting macros`:idx: are macros or templates that have not only
|
||||
Term rewriting macros are macros or templates that have not only
|
||||
a *name* but also a *pattern* that is searched for after the semantic checking
|
||||
phase of the compiler: This means they provide an easy way to enhance the
|
||||
compilation pipeline with user defined optimizations:
|
||||
@@ -4726,7 +4726,7 @@ ordinary routines.
|
||||
Move optimization
|
||||
-----------------
|
||||
|
||||
The ``call`` constraint is particularly useful to implement a `move`:idx:
|
||||
The ``call`` constraint is particularly useful to implement a move
|
||||
optimization for types that have copying semantics:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -4752,7 +4752,7 @@ optimization for types that have copying semantics:
|
||||
|
||||
Modules
|
||||
=======
|
||||
Nimrod supports splitting a program into pieces by a `module`:idx: concept.
|
||||
Nimrod supports splitting a program into pieces by a module concept.
|
||||
Each module needs to be in its own file and has its own `namespace`:idx:.
|
||||
Modules enable `information hiding`:idx: and `separate compilation`:idx:.
|
||||
A module may gain access to symbols of another module by the `import`:idx:
|
||||
@@ -4795,7 +4795,7 @@ This is best illustrated by an example:
|
||||
Import statement
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
After the `import`:idx: statement a list of module names can follow or a single
|
||||
After the ``import`` statement a list of module names can follow or a single
|
||||
module name followed by an ``except`` to prevent some symbols to be imported:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -4838,7 +4838,7 @@ Likewise the following does not make sense as the name is ``strutils`` already:
|
||||
From import statement
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
After the `from`:idx: statement a module name follows followed by
|
||||
After the ``from`` statement a module name follows followed by
|
||||
an ``import`` to list the symbols one likes to use without explict
|
||||
full qualification:
|
||||
|
||||
@@ -4857,7 +4857,7 @@ in ``module``.
|
||||
Export statement
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
An `export`:idx: statement can be used for symbol fowarding so that client
|
||||
An ``export`` statement can be used for symbol fowarding so that client
|
||||
modules don't need to import a module's dependencies:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -4885,7 +4885,7 @@ Scope rules
|
||||
-----------
|
||||
Identifiers are valid from the point of their declaration until the end of
|
||||
the block in which the declaration occurred. The range where the identifier
|
||||
is known is the `scope`:idx: of the identifier. The exact scope of an
|
||||
is known is the scope of the identifier. The exact scope of an
|
||||
identifier depends on the way it was declared.
|
||||
|
||||
Block scope
|
||||
@@ -4958,7 +4958,7 @@ to access the feature becomes available.
|
||||
|
||||
noSideEffect pragma
|
||||
-------------------
|
||||
The `noSideEffect`:idx: pragma is used to mark a proc/iterator to have no side
|
||||
The ``noSideEffect`` pragma is used to mark a proc/iterator to have no side
|
||||
effects. This means that the proc/iterator only changes locations that are
|
||||
reachable from its parameters and the return value only depends on the
|
||||
arguments. If none of its parameters have the type ``var T``
|
||||
@@ -4980,7 +4980,7 @@ proc with no side effects:
|
||||
destructor pragma
|
||||
-----------------
|
||||
|
||||
The `destructor`:idx: pragma is used to mark a proc to act as a type destructor.
|
||||
The ``destructor`` pragma is used to mark a proc to act as a type destructor.
|
||||
The proc must have a single parameter with a concrete type (the name of a
|
||||
generic type is allowed too).
|
||||
|
||||
@@ -5040,25 +5040,25 @@ the ``finalizer`` parameter to ``new``.
|
||||
|
||||
procvar pragma
|
||||
--------------
|
||||
The `procvar`:idx: pragma is used to mark a proc that it can be passed to a
|
||||
The ``procvar`` pragma is used to mark a proc that it can be passed to a
|
||||
procedural variable.
|
||||
|
||||
|
||||
compileTime pragma
|
||||
------------------
|
||||
The `compileTime`:idx: pragma is used to mark a proc to be used at compile
|
||||
The ``compileTime`` pragma is used to mark a proc to be used at compile
|
||||
time only. No code will be generated for it. Compile time procs are useful
|
||||
as helpers for macros.
|
||||
|
||||
|
||||
noReturn pragma
|
||||
---------------
|
||||
The `noreturn`:idx: pragma is used to mark a proc that never returns.
|
||||
The ``noreturn`` pragma is used to mark a proc that never returns.
|
||||
|
||||
|
||||
Acyclic pragma
|
||||
--------------
|
||||
The `acyclic`:idx: pragma can be used for object types to mark them as acyclic
|
||||
The ``acyclic`` pragma can be used for object types to mark them as acyclic
|
||||
even though they seem to be cyclic. This is an **optimization** for the garbage
|
||||
collector to not consider objects of this type as part of a cycle:
|
||||
|
||||
@@ -5089,13 +5089,13 @@ memory, but nothing worse happens.
|
||||
|
||||
Final pragma
|
||||
------------
|
||||
The `final`:idx: pragma can be used for an object type to specify that it
|
||||
The ``final`` pragma can be used for an object type to specify that it
|
||||
cannot be inherited from.
|
||||
|
||||
|
||||
shallow pragma
|
||||
--------------
|
||||
The `shallow`:idx: pragma affects the semantics of a type: The compiler is
|
||||
The ``shallow`` pragma affects the semantics of a type: The compiler is
|
||||
allowed to make a shallow copy. This can cause serious semantic issues and
|
||||
break memory safety! However, it can speed up assignments considerably,
|
||||
because the semantics of Nimrod require deep copying of sequences and strings.
|
||||
@@ -5115,14 +5115,14 @@ structure:
|
||||
|
||||
Pure pragma
|
||||
-----------
|
||||
An object type can be marked with the `pure`:idx: pragma so that its type
|
||||
An object type can be marked with the ``pure`` pragma so that its type
|
||||
field which is used for runtime type identification is omitted. This is
|
||||
necessary for binary compatibility with other compiled languages.
|
||||
|
||||
|
||||
AsmNoStackFrame pragma
|
||||
----------------------
|
||||
A proc can be marked with the `AsmNoStackFrame`:idx: pragma to tell the compiler
|
||||
A proc can be marked with the ``AsmNoStackFrame`` pragma to tell the compiler
|
||||
it should not generate a stack frame for the proc. There are also no exit
|
||||
statements like ``return result;`` generated and the generated C function is
|
||||
declared as ``__declspec(naked)`` or ``__attribute__((naked))`` (depending on
|
||||
@@ -5133,7 +5133,7 @@ assembler statements.
|
||||
|
||||
error pragma
|
||||
------------
|
||||
The `error`:idx: pragma is used to make the compiler output an error message
|
||||
The ``error`` pragma is used to make the compiler output an error message
|
||||
with the given content. Compilation does not necessarily abort after an error
|
||||
though.
|
||||
|
||||
@@ -5149,7 +5149,7 @@ operation is valid due to overloading and type conversions:
|
||||
|
||||
fatal pragma
|
||||
------------
|
||||
The `fatal`:idx: pragma is used to make the compiler output an error message
|
||||
The ``fatal`` pragma is used to make the compiler output an error message
|
||||
with the given content. In contrast to the ``error`` pragma, compilation
|
||||
is guaranteed to be aborted by this pragma. Example:
|
||||
|
||||
@@ -5159,17 +5159,17 @@ is guaranteed to be aborted by this pragma. Example:
|
||||
|
||||
warning pragma
|
||||
--------------
|
||||
The `warning`:idx: pragma is used to make the compiler output a warning message
|
||||
The ``warning`` pragma is used to make the compiler output a warning message
|
||||
with the given content. Compilation continues after the warning.
|
||||
|
||||
hint pragma
|
||||
-----------
|
||||
The `hint`:idx: pragma is used to make the compiler output a hint message with
|
||||
The ``hint`` pragma is used to make the compiler output a hint message with
|
||||
the given content. Compilation continues after the hint.
|
||||
|
||||
line pragma
|
||||
-----------
|
||||
The `line`:idx: pragma can be used to affect line information of the annotated
|
||||
The ``line`` pragma can be used to affect line information of the annotated
|
||||
statement as seen in stack backtraces:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -5187,7 +5187,7 @@ If the ``line`` pragma is used with a parameter, the parameter needs be a
|
||||
|
||||
linearScanEnd pragma
|
||||
--------------------
|
||||
The `linearScanEnd`:idx: pragma can be used to tell the compiler how to
|
||||
The ``linearScanEnd`` pragma can be used to tell the compiler how to
|
||||
compile a Nimrod `case`:idx: statement. Syntactically it has to be used as a
|
||||
statement:
|
||||
|
||||
@@ -5215,7 +5215,7 @@ whole ``case`` statement, the whole ``case`` statement uses linear scanning.
|
||||
|
||||
computedGoto pragma
|
||||
-------------------
|
||||
The `computedGoto`:idx: pragma can be used to tell the compiler how to
|
||||
The ``computedGoto`` pragma can be used to tell the compiler how to
|
||||
compile a Nimrod `case`:idx: in a ``while true`` statement.
|
||||
Syntactically it has to be used as a statement inside the loop:
|
||||
|
||||
@@ -5260,7 +5260,7 @@ extension the pragma is simply ignored.
|
||||
|
||||
unroll pragma
|
||||
-------------
|
||||
The `unroll`:idx: pragma can be used to tell the compiler that it should unroll
|
||||
The ``unroll`` pragma can be used to tell the compiler that it should unroll
|
||||
a `for`:idx: or `while`:idx: loop for runtime efficiency:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -5339,7 +5339,7 @@ but are used to override the settings temporarily. Example:
|
||||
|
||||
register pragma
|
||||
---------------
|
||||
The `register`:idx: pragma is for variables only. It declares the variable as
|
||||
The ``register`` pragma is for variables only. It declares the variable as
|
||||
``register``, giving the compiler a hint that the variable should be placed
|
||||
in a hardware register for faster access. C compilers usually ignore this
|
||||
though and for good reasons: Often they do a better job without it anyway.
|
||||
@@ -5350,7 +5350,7 @@ example) it may provide benefits, though.
|
||||
|
||||
global pragma
|
||||
-------------
|
||||
The `global`:idx: pragma can be applied to a variable within a proc to instruct
|
||||
The ``global`` pragma can be applied to a variable within a proc to instruct
|
||||
the compiler to store it in a global location and initialize it once at program
|
||||
startup.
|
||||
|
||||
@@ -5367,7 +5367,7 @@ and before any variable in a module that imports it.
|
||||
|
||||
DeadCodeElim pragma
|
||||
-------------------
|
||||
The `deadCodeElim`:idx: pragma only applies to whole modules: It tells the
|
||||
The ``deadCodeElim`` pragma only applies to whole modules: It tells the
|
||||
compiler to activate (or deactivate) dead code elimination for the module the
|
||||
pragma appears in.
|
||||
|
||||
@@ -5385,7 +5385,7 @@ Example:
|
||||
..
|
||||
NoForward pragma
|
||||
----------------
|
||||
The `noforward`:idx: pragma can be used to turn on and off a special compilation
|
||||
The ``noforward`` pragma can be used to turn on and off a special compilation
|
||||
mode that to large extent eliminates the need for forward declarations. In this
|
||||
mode, the proc definitions may appear out of order and the compiler will postpone
|
||||
their semantic analysis and compilation until it actually needs to generate code
|
||||
@@ -5433,7 +5433,7 @@ Example:
|
||||
Pragma pragma
|
||||
-------------
|
||||
|
||||
The `pragma`:idx: pragma can be used to declare user defined pragmas. This is
|
||||
The ``pragma`` 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.
|
||||
@@ -5477,7 +5477,7 @@ are documented here.
|
||||
|
||||
Importc pragma
|
||||
--------------
|
||||
The `importc`:idx: pragma provides a means to import a proc or a variable
|
||||
The ``importc`` pragma provides a means to import a proc or a variable
|
||||
from C. The optional argument is a string containing the C identifier. If
|
||||
the argument is missing, the C name is the Nimrod identifier *exactly as
|
||||
spelled*:
|
||||
@@ -5491,7 +5491,7 @@ the same feature under the same name.
|
||||
|
||||
Exportc pragma
|
||||
--------------
|
||||
The `exportc`:idx: pragma provides a means to export a type, a variable, or a
|
||||
The ``exportc`` pragma provides a means to export a type, a variable, or a
|
||||
procedure to C. Enums and constants can't be exported. The optional argument
|
||||
is a string containing the C identifier. If the argument is missing, the C
|
||||
name is the Nimrod identifier *exactly as spelled*:
|
||||
@@ -5505,7 +5505,7 @@ the same feature under the same name.
|
||||
|
||||
Extern pragma
|
||||
-------------
|
||||
Like ``exportc`` or ``importc`` the `extern`:idx: pragma affects name
|
||||
Like ``exportc`` or ``importc``, the ``extern`` pragma affects name
|
||||
mangling. The string literal passed to ``extern`` can be a format string:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
@@ -5518,7 +5518,7 @@ In the example the external name of ``p`` is set to ``prefixp``.
|
||||
Bycopy pragma
|
||||
-------------
|
||||
|
||||
The `bycopy`:idx: pragma can be applied to an object or tuple type and
|
||||
The ``bycopy`` pragma can be applied to an object or tuple type and
|
||||
instructs the compiler to pass the type by value to procs:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -5530,13 +5530,13 @@ instructs the compiler to pass the type by value to procs:
|
||||
Byref pragma
|
||||
------------
|
||||
|
||||
The `byref`:idx: pragma can be applied to an object or tuple type and instructs
|
||||
The ``byref`` pragma can be applied to an object or tuple type and instructs
|
||||
the compiler to pass the type by reference (hidden pointer) to procs.
|
||||
|
||||
|
||||
Varargs pragma
|
||||
--------------
|
||||
The `varargs`:idx: pragma can be applied to procedures only (and procedure
|
||||
The ``varargs`` pragma can be applied to procedures only (and procedure
|
||||
types). It tells Nimrod that the proc can take a variable number of parameters
|
||||
after the last specified parameter. Nimrod string values will be converted to C
|
||||
strings automatically:
|
||||
@@ -5549,7 +5549,7 @@ strings automatically:
|
||||
|
||||
Union pragma
|
||||
------------
|
||||
The `union`:idx: pragma can be applied to any ``object`` type. It means all
|
||||
The ``union`` pragma can be applied to any ``object`` type. It means all
|
||||
of the object's fields are overlaid in memory. This produces a ``union``
|
||||
instead of a ``struct`` in the generated C/C++ code. The object declaration
|
||||
then must not use inheritance or any GC'ed memory but this is currently not
|
||||
@@ -5560,7 +5560,7 @@ should scan unions conservatively.
|
||||
|
||||
Packed pragma
|
||||
-------------
|
||||
The `packed`:idx: pragma can be applied to any ``object`` type. It ensures
|
||||
The ``packed`` pragma can be applied to any ``object`` type. It ensures
|
||||
that the fields of an object are packed back-to-back in memory. It is useful
|
||||
to store packets or messages from/to network or hardware drivers, and for
|
||||
interoperability with C. Combining packed pragma with inheritance is not
|
||||
@@ -5571,7 +5571,7 @@ compile-time error. Usage with inheritance should be defined and documented.
|
||||
|
||||
Unchecked pragma
|
||||
----------------
|
||||
The `unchecked`:idx: pragma can be used to mark a named array as ``unchecked``
|
||||
The ``unchecked`` pragma can be used to mark a named array as ``unchecked``
|
||||
meaning its bounds are not checked. This is often useful when one wishes to
|
||||
implement his own flexibly sized arrays. Additionally an unchecked array is
|
||||
translated into a C array of undetermined size:
|
||||
@@ -5606,7 +5606,7 @@ runtime size of the array.
|
||||
|
||||
Dynlib pragma for import
|
||||
------------------------
|
||||
With the `dynlib`:idx: pragma a procedure or a variable can be imported from
|
||||
With the ``dynlib`` pragma a procedure or a variable can be imported from
|
||||
a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX).
|
||||
The non-optional argument has to be the name of the dynamic library:
|
||||
|
||||
@@ -5696,7 +5696,7 @@ Thread pragma
|
||||
-------------
|
||||
|
||||
A proc that is executed as a new thread of execution should be marked by the
|
||||
`thread pragma`:idx:. The compiler checks procedures marked as ``thread`` for
|
||||
``thread`` pragma. The compiler checks procedures marked as ``thread`` for
|
||||
violations of the `no heap sharing restriction`:idx:\: This restriction implies
|
||||
that it is invalid to construct a data structure that consists of memory
|
||||
allocated from different (thread local) heaps.
|
||||
@@ -5737,7 +5737,7 @@ Future directions:
|
||||
Threadvar pragma
|
||||
----------------
|
||||
|
||||
A global variable can be marked with the `threadvar`:idx: pragma; it is
|
||||
A global variable can be marked with the ``threadvar`` pragma; it is
|
||||
a `thread-local`:idx: variable then:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -5789,7 +5789,7 @@ Taint mode
|
||||
==========
|
||||
|
||||
The Nimrod compiler and most parts of the standard library support
|
||||
a `taint mode`:idx:. Input strings are declared with the `TaintedString`:idx:
|
||||
a taint mode. Input strings are declared with the `TaintedString`:idx:
|
||||
string type declared in the ``system`` module.
|
||||
|
||||
If the taint mode is turned on (via the ``--taintMode:on`` command line
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
=================================
|
||||
nimgrep User's manual
|
||||
=================================
|
||||
=========================
|
||||
nimgrep User's manual
|
||||
=========================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: 0.9
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
=================================
|
||||
niminst User's manual
|
||||
=================================
|
||||
=========================
|
||||
niminst User's manual
|
||||
=========================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimrodversion|
|
||||
|
||||
@@ -116,7 +116,7 @@ The default build of a project is a `debug build`:idx:. To compile a
|
||||
Search path handling
|
||||
--------------------
|
||||
|
||||
Nimrod has the concept of a global `search path`:idx: (PATH) that is queried to
|
||||
Nimrod has the concept of a global search path (PATH) that is queried to
|
||||
determine where to find imported modules or include files. If multiple files are
|
||||
found an ambiguity error is produced.
|
||||
|
||||
@@ -174,7 +174,7 @@ is not shared between different projects.
|
||||
Cross compilation
|
||||
=================
|
||||
|
||||
To `cross compile`:idx:, use for example::
|
||||
To cross compile, use for example::
|
||||
|
||||
nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim
|
||||
|
||||
@@ -200,7 +200,7 @@ DLL generation
|
||||
|
||||
Nimrod 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 Nimrod `DLL`:idx: depends
|
||||
``nimrtl.dll``. This means that every generated Nimrod DLL depends
|
||||
on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command::
|
||||
|
||||
nimrod c -d:release lib/nimrtl.nim
|
||||
@@ -251,7 +251,7 @@ generator and are subject to change.
|
||||
|
||||
NoDecl pragma
|
||||
-------------
|
||||
The `noDecl`:idx: pragma can be applied to almost any symbol (variable, proc,
|
||||
The ``noDecl`` pragma can be applied to almost any symbol (variable, proc,
|
||||
type, etc.) and is sometimes useful for interoperability with C:
|
||||
It tells Nimrod that it should not generate a declaration for the symbol in
|
||||
the C code. For example:
|
||||
@@ -268,7 +268,7 @@ However, the ``header`` pragma is often the better alternative.
|
||||
|
||||
Header pragma
|
||||
-------------
|
||||
The `header`:idx: pragma is very similar to the ``noDecl`` pragma: It can be
|
||||
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``:
|
||||
|
||||
@@ -287,7 +287,7 @@ encloses the header file in ``""`` in the generated C code.
|
||||
|
||||
IncompleteStruct pragma
|
||||
-----------------------
|
||||
The `incompleteStruct`:idx: pragma tells the compiler to not use the
|
||||
The ``incompleteStruct`` pragma tells the compiler to not use the
|
||||
underlying C ``struct`` in a ``sizeof`` expression:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
@@ -298,7 +298,7 @@ underlying C ``struct`` in a ``sizeof`` expression:
|
||||
|
||||
Compile pragma
|
||||
--------------
|
||||
The `compile`:idx: pragma can be used to compile and link a C/C++ source file
|
||||
The ``compile`` pragma can be used to compile and link a C/C++ source file
|
||||
with the project:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
@@ -311,7 +311,7 @@ of the file.
|
||||
|
||||
Link pragma
|
||||
-----------
|
||||
The `link`:idx: pragma can be used to link an additional file with the project:
|
||||
The ``link`` pragma can be used to link an additional file with the project:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
{.link: "myfile.o".}
|
||||
@@ -319,7 +319,7 @@ The `link`:idx: pragma can be used to link an additional file with the project:
|
||||
|
||||
PassC pragma
|
||||
------------
|
||||
The `passC`:idx: pragma can be used to pass additional parameters to the C
|
||||
The ``passC`` pragma can be used to pass additional parameters to the C
|
||||
compiler like you would using the commandline switch ``--passC``:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
@@ -333,7 +333,7 @@ embed parameters from an external command at compile time:
|
||||
|
||||
PassL pragma
|
||||
------------
|
||||
The `passL`:idx: pragma can be used to pass additional parameters to the linker
|
||||
The ``passL`` pragma can be used to pass additional parameters to the linker
|
||||
like you would using the commandline switch ``--passL``:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
@@ -348,7 +348,7 @@ embed parameters from an external command at compile time:
|
||||
|
||||
Emit pragma
|
||||
-----------
|
||||
The `emit`:idx: pragma can be used to directly affect the output of the
|
||||
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.
|
||||
@@ -370,7 +370,7 @@ Example:
|
||||
|
||||
ImportCpp pragma
|
||||
----------------
|
||||
The `importcpp`:idx: pragma can be used to import `C++`:idx: methods. The
|
||||
The ``importcpp`` pragma can be used to import `C++`:idx: methods. The
|
||||
generated code then uses the C++ method calling syntax: ``obj->method(arg)``.
|
||||
In addition with the ``header`` and ``emit`` pragmas this allows *sloppy*
|
||||
interfacing with libraries written in C++:
|
||||
@@ -408,7 +408,7 @@ emits C++ code.
|
||||
|
||||
ImportObjC pragma
|
||||
-----------------
|
||||
The `importobjc`:idx: pragma can be used to import `Objective C`:idx: methods.
|
||||
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*
|
||||
@@ -458,7 +458,7 @@ emits Objective C code.
|
||||
CodegenDecl pragma
|
||||
------------------
|
||||
|
||||
The `codegenDecl`:idx: pragma can be used to directly influence Nimrod's code
|
||||
The ``codegenDecl`` pragma can be used to directly influence Nimrod's code
|
||||
generator. It receives a format string that determines how the variable or
|
||||
proc is declared in the generated code:
|
||||
|
||||
@@ -473,7 +473,7 @@ proc is declared in the generated code:
|
||||
InjectStmt pragma
|
||||
-----------------
|
||||
|
||||
The `injectStmt`:idx: pragma can be used to inject a statement before every
|
||||
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:
|
||||
|
||||
@@ -485,28 +485,28 @@ debugging:
|
||||
|
||||
LineDir option
|
||||
--------------
|
||||
The `lineDir`:idx: option can be turned on or off. If turned on the
|
||||
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`:idx: option is turned on, the generated C contains code to
|
||||
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`:idx: option implies the ``stackTrace`` option. If turned on,
|
||||
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`:idx: option enables or disables the *Embedded Nimrod Debugger*.
|
||||
The ``debugger`` option enables or disables the *Embedded Nimrod Debugger*.
|
||||
See the documentation of endb_ for further information.
|
||||
|
||||
|
||||
@@ -518,7 +518,7 @@ ENDB. See the documentation of `endb <endb.html>`_ for further information.
|
||||
|
||||
Volatile pragma
|
||||
---------------
|
||||
The `volatile`:idx: pragma is for variables only. It declares the variable as
|
||||
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++).
|
||||
|
||||
@@ -530,7 +530,7 @@ DynlibOverride
|
||||
|
||||
By default Nimrod's ``dynlib`` pragma causes the compiler to generate
|
||||
``GetProcAddress`` (or their Unix counterparts)
|
||||
calls to bind to a DLL. With the `dynlibOverride`:idx: command line switch this
|
||||
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
|
||||
against. For instance, to link statically against Lua this command might work
|
||||
on Linux::
|
||||
@@ -556,7 +556,7 @@ for further information.
|
||||
Nimrod interactive mode
|
||||
=======================
|
||||
|
||||
The Nimrod compiler supports an `interactive mode`:idx:. This is also known as
|
||||
The Nimrod compiler supports an interactive mode. This is also known as
|
||||
a `REPL`:idx: (*read eval print loop*). If Nimrod has been built with the
|
||||
``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal
|
||||
input management. To start Nimrod in interactive mode use the command
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
================================
|
||||
Substitution Expressions (subex)
|
||||
================================
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
=====
|
||||
Tools
|
||||
=====
|
||||
===========================
|
||||
Tools available with Nimrod
|
||||
===========================
|
||||
|
||||
The standard distribution ships with the following tools:
|
||||
|
||||
|
||||
32
doc/tut1.txt
32
doc/tut1.txt
@@ -110,7 +110,7 @@ useful for embedding HTML code templates for example.
|
||||
Comments
|
||||
--------
|
||||
|
||||
`Comments`:idx: start anywhere outside a string or character literal with the
|
||||
Comments start anywhere outside a string or character literal with the
|
||||
hash character ``#``. Documentation comments start with ``##``. Multiline
|
||||
comments need to be aligned at the same column:
|
||||
|
||||
@@ -224,7 +224,7 @@ different values! For safety use only constant values.
|
||||
Constants
|
||||
=========
|
||||
|
||||
`Constants`:idx: are symbols which are bound to a value. The constant's value
|
||||
Constants are symbols which are bound to a value. The constant's value
|
||||
cannot change. The compiler must be able to evaluate the expression in a
|
||||
constant declaration at compile time:
|
||||
|
||||
@@ -369,7 +369,7 @@ he types in nothing (only presses RETURN).
|
||||
For statement
|
||||
-------------
|
||||
|
||||
The `for`:idx: statement is a construct to loop over any element an *iterator*
|
||||
The ``for`` statement is a construct to loop over any element an *iterator*
|
||||
provides. The example uses the built-in ``countup`` iterator:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -481,7 +481,7 @@ Example:
|
||||
else:
|
||||
echo("unknown operating system")
|
||||
|
||||
The `when`:idx: statement is almost identical to the ``if`` statement with some
|
||||
The ``when`` statement is almost identical to the ``if`` statement with some
|
||||
differences:
|
||||
|
||||
* Each condition has to be a constant expression since it is evaluated by the
|
||||
@@ -791,7 +791,7 @@ However, this cannot be done for mutually recursive procedures:
|
||||
|
||||
Here ``odd`` depends on ``even`` and vice versa. Thus ``even`` needs to be
|
||||
introduced to the compiler before it is completely defined. The syntax for
|
||||
such a `forward declaration`:idx: is simple: just omit the ``=`` and the
|
||||
such a forward declaration is simple: just omit the ``=`` and the
|
||||
procedure's body.
|
||||
|
||||
Later versions of the language may get rid of the need for forward
|
||||
@@ -863,7 +863,7 @@ that are available for them in detail.
|
||||
Booleans
|
||||
--------
|
||||
|
||||
The `boolean`:idx: type is named ``bool`` in Nimrod and consists of the two
|
||||
The boolean type is named ``bool`` in Nimrod and consists of the two
|
||||
pre-defined values ``true`` and ``false``. Conditions in while,
|
||||
if, elif, when statements need to be of type bool.
|
||||
|
||||
@@ -1030,7 +1030,7 @@ Enumeration and object types cannot be defined on the fly, but only within a
|
||||
|
||||
Enumerations
|
||||
------------
|
||||
A variable of an `enumeration`:idx: type can only be assigned a value of a
|
||||
A variable of an enumeration type can only be assigned a value of a
|
||||
limited set. This set consists of ordered symbols. Each symbol is mapped
|
||||
to an integer value internally. The first symbol is represented
|
||||
at runtime by 0, the second by 1 and so on. Example:
|
||||
@@ -1069,7 +1069,7 @@ An explicit ordered enum can have *holes*:
|
||||
Ordinal types
|
||||
-------------
|
||||
Enumerations without holes, integer types, ``char`` and ``bool`` (and
|
||||
subranges) are called `ordinal`:idx: types. Ordinal types have quite
|
||||
subranges) are called ordinal types. Ordinal types have quite
|
||||
a few special operations:
|
||||
|
||||
----------------- --------------------------------------------------------
|
||||
@@ -1094,7 +1094,7 @@ checks turned on.)
|
||||
|
||||
Subranges
|
||||
---------
|
||||
A `subrange`:idx: type is a range of values from an integer or enumeration type
|
||||
A subrange type is a range of values from an integer or enumeration type
|
||||
(the base type). Example:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -1117,7 +1117,7 @@ avoid this common programming error.
|
||||
|
||||
Sets
|
||||
----
|
||||
The `set type`:idx: models the mathematical notion of a set. The set's
|
||||
The set type models the mathematical notion of a set. The set's
|
||||
basetype can only be an ordinal type. The reason is that sets are implemented
|
||||
as high performance bit vectors.
|
||||
|
||||
@@ -1161,7 +1161,7 @@ constants that should be ``or``'ed together.
|
||||
|
||||
Arrays
|
||||
------
|
||||
An `array`:idx: is a simple fixed length container. Each element in
|
||||
An array is a simple fixed length container. Each element in
|
||||
the array has the same type. The array's index type can be any ordinal type.
|
||||
|
||||
Arrays can be constructed via ``[]``:
|
||||
@@ -1253,7 +1253,7 @@ to specify a range from zero to the specified index minus one:
|
||||
|
||||
Sequences
|
||||
---------
|
||||
`Sequences`:idx: are similar to arrays but of dynamic length which may change
|
||||
Sequences are similar to arrays but of dynamic length which may change
|
||||
during runtime (like strings). Since sequences are resizable they are always
|
||||
allocated on the heap and garbage collected.
|
||||
|
||||
@@ -1471,7 +1471,7 @@ won't compile:
|
||||
|
||||
Reference and pointer types
|
||||
---------------------------
|
||||
References (similar to `pointers`:idx: in other programming languages) are a
|
||||
References (similar to pointers in other programming languages) are a
|
||||
way to introduce many-to-one relationships. This means different references can
|
||||
point to and modify the same location in memory.
|
||||
|
||||
@@ -1513,7 +1513,7 @@ If a reference points to *nothing*, it has the value ``nil``.
|
||||
|
||||
Procedural type
|
||||
---------------
|
||||
A `procedural type`:idx: is a (somewhat abstract) pointer to a procedure.
|
||||
A procedural type is a (somewhat abstract) pointer to a procedure.
|
||||
``nil`` is an allowed value for a variable of a procedural type.
|
||||
Nimrod uses procedural types to achieve `functional`:idx: programming
|
||||
techniques.
|
||||
@@ -1543,7 +1543,7 @@ listed in the `manual <manual.html>`_.
|
||||
|
||||
Modules
|
||||
=======
|
||||
Nimrod supports splitting a program into pieces with a `module`:idx: concept.
|
||||
Nimrod supports splitting a program into pieces with a module concept.
|
||||
Each module is in its own file. Modules enable `information hiding`:idx: and
|
||||
`separate compilation`:idx:. A module may gain access to symbols of another
|
||||
module by the `import`:idx: statement. Only top-level symbols that are marked
|
||||
@@ -1698,7 +1698,7 @@ define a shorter alias to use when qualifying symbols.
|
||||
|
||||
Include statement
|
||||
-----------------
|
||||
The `include`:idx: statement does something fundamentally different than
|
||||
The ``include`` statement does something fundamentally different than
|
||||
importing a module: it merely includes the contents of a file. The ``include``
|
||||
statement is useful to split up a large module into several files:
|
||||
|
||||
|
||||
16
doc/tut2.txt
16
doc/tut2.txt
@@ -135,7 +135,7 @@ The ``EInvalidObjectConversion`` exception is raised if ``x`` is not a
|
||||
Object variants
|
||||
---------------
|
||||
Often an object hierarchy is overkill in certain situations where simple
|
||||
`variant`:idx: types are needed.
|
||||
variant types are needed.
|
||||
|
||||
An example:
|
||||
|
||||
@@ -182,7 +182,7 @@ bound to a class. This has disadvantages:
|
||||
``join`` a string method or an array method?
|
||||
|
||||
Nimrod avoids these problems by not assigning methods to a class. All methods
|
||||
in Nimrod are `multi-methods`:idx:. As we will see later, multi-methods are
|
||||
in Nimrod are multi-methods. As we will see later, multi-methods are
|
||||
distinguished from procs only for dynamic binding purposes.
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ The syntax ``obj.method(args)`` can be used instead of ``method(obj, args)``.
|
||||
If there are no remaining arguments, the parentheses can be omitted:
|
||||
``obj.len`` (instead of ``len(obj)``).
|
||||
|
||||
This `method call syntax`:idx: is not restricted to objects, it can be used
|
||||
This method call syntax is not restricted to objects, it can be used
|
||||
for any type:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -343,7 +343,7 @@ evaluation or dead code elimination do not work with methods.
|
||||
Exceptions
|
||||
==========
|
||||
|
||||
In Nimrod `exceptions`:idx: are objects. By convention, exception types are
|
||||
In Nimrod exceptions are objects. By convention, exception types are
|
||||
prefixed with an 'E', not 'T'. The `system <system.html>`_ module defines an
|
||||
exception hierarchy that you might want to stick to. Exceptions derive from
|
||||
E_Base, which provides the common interface.
|
||||
@@ -380,7 +380,7 @@ the template ``newException`` in the ``system`` module can be used:
|
||||
Try statement
|
||||
-------------
|
||||
|
||||
The `try`:idx: statement handles exceptions:
|
||||
The ``try`` statement handles exceptions:
|
||||
|
||||
.. code-block:: nimrod
|
||||
# read the first two lines of a text file that should contain numbers
|
||||
@@ -513,7 +513,7 @@ procs with the list of raised exceptions. You can read more about Nimrod's
|
||||
Generics
|
||||
========
|
||||
|
||||
`Generics`:idx: are Nimrod's means to parametrize procs, iterators or types
|
||||
Generics are Nimrod's means to parametrize procs, iterators or types
|
||||
with `type parameters`:idx:. They are most useful for efficient type safe
|
||||
containers:
|
||||
|
||||
@@ -714,9 +714,9 @@ know how the Nimrod concrete syntax is converted to an abstract syntax tree
|
||||
(AST). The AST is documented in the `macros <macros.html>`_ module.
|
||||
|
||||
Once your macro is finished, there are two ways to invoke it:
|
||||
(1) invoking a macro like a procedure call (`expression macros`:idx:)
|
||||
(1) invoking a macro like a procedure call (expression macros)
|
||||
(2) invoking a macro with the special ``macrostmt``
|
||||
syntax (`statement macros`:idx:)
|
||||
syntax (statement macros)
|
||||
|
||||
|
||||
Expression Macros
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
## many options and tweaking, but you are not limited to snippets and can
|
||||
## generate `LaTeX documents <https://en.wikipedia.org/wiki/LaTeX>`_ too.
|
||||
|
||||
import strutils, os, hashes, strtabs, rstast, rst, highlite
|
||||
import strutils, os, hashes, strtabs, rstast, rst, highlite, tables, sequtils,
|
||||
algorithm
|
||||
|
||||
const
|
||||
HtmlExt = "html"
|
||||
@@ -56,6 +57,9 @@ type
|
||||
currentSection: string ## \
|
||||
## Stores the empty string or the last headline/overline found in the rst
|
||||
## document, so it can be used as a prettier name for term index generation.
|
||||
seenIndexTerms: TTable[string, int] ## \
|
||||
## Keeps count of same text index terms to generate different identifiers
|
||||
## for hyperlinks. See renderIndexTerm proc for details.
|
||||
|
||||
PDoc = var TRstGenerator ## Alias to type less.
|
||||
|
||||
@@ -68,10 +72,16 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
|
||||
##
|
||||
## You need to call this before using a ``TRstGenerator`` with any other
|
||||
## procs in this module. Pass a non ``nil`` ``PStringTable`` value as
|
||||
## ``config`` with parameters used by the HTML output generator. If you
|
||||
## don't know what to use, pass the results of the ``defaultConfig()`` proc.
|
||||
## The ``filename`` is symbolic and used only for error reporting, you can
|
||||
## pass any non ``nil`` string here.
|
||||
## `config` with parameters used by the HTML output generator. If you don't
|
||||
## know what to use, pass the results of the `defaultConfig()
|
||||
## <#defaultConfig>_` proc.
|
||||
##
|
||||
## The `filename` parameter will be used for error reporting and creating
|
||||
## index hyperlinks to the file, but you can pass an empty string here if you
|
||||
## are parsing a stream in memory. If `filename` ends with the ``.nim``
|
||||
## extension, the title for the document will be set by default to ``Module
|
||||
## filename``. This default title can be overriden by the embedded rst, but
|
||||
## it helps to prettify the generated index if no title is found.
|
||||
##
|
||||
## The ``TRstParseOptions``, ``TFindFileHandler`` and ``TMsgHandler`` types
|
||||
## are defined in the the `packages/docutils/rst module <rst.html>`_.
|
||||
@@ -111,6 +121,10 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
|
||||
g.options = options
|
||||
g.findFile = findFile
|
||||
g.currentSection = ""
|
||||
let fileParts = filename.splitFile
|
||||
if fileParts.ext == ".nim":
|
||||
g.currentSection = "Module " & fileParts.name
|
||||
g.seenIndexTerms = initTable[string, int]()
|
||||
g.msgHandler = msgHandler
|
||||
|
||||
let s = config["split.item.toc"]
|
||||
@@ -120,8 +134,8 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
|
||||
proc writeIndexFile*(g: var TRstGenerator, outfile: string) =
|
||||
## Writes the current index buffer to the specified output file.
|
||||
##
|
||||
## You previously need to add entries to the index with the ``setIndexTerm``
|
||||
## proc. If the index is empty the file won't be created.
|
||||
## You previously need to add entries to the index with the `setIndexTerm()
|
||||
## <#setIndexTerm>`_ proc. If the index is empty the file won't be created.
|
||||
if g.theIndex.len > 0: writeFile(outfile, g.theIndex)
|
||||
|
||||
proc addXmlChar(dest: var string, c: char) =
|
||||
@@ -207,6 +221,9 @@ proc dispA(target: TOutputTarget, dest: var string,
|
||||
if target != outLatex: addf(dest, xml, args)
|
||||
else: addf(dest, tex, args)
|
||||
|
||||
proc `or`(x, y: string): string {.inline.} =
|
||||
result = if x.isNil: y else: x
|
||||
|
||||
proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string)
|
||||
## Writes into ``result`` the rst ast ``n`` using the ``d`` configuration.
|
||||
##
|
||||
@@ -224,7 +241,7 @@ proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string)
|
||||
proc renderAux(d: PDoc, n: PRstNode, result: var string) =
|
||||
for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], result)
|
||||
|
||||
proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) =
|
||||
proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) =
|
||||
var tmp = ""
|
||||
for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], tmp)
|
||||
if d.target != outLatex:
|
||||
@@ -254,25 +271,45 @@ proc setIndexTerm*(d: var TRstGenerator, id, term: string,
|
||||
linkTitle, linkDesc = "") =
|
||||
## Adds a `term` to the index using the specified hyperlink identifier.
|
||||
##
|
||||
## The ``d.theIndex`` string will be used to append the term in the format
|
||||
## ``term<tab>file#id``. The anchor will be the based on the name of the file
|
||||
## currently being parsed plus the `id`, which will be appended after a hash.
|
||||
## A new entry will be added to the index using the format
|
||||
## ``term<tab>file#id``. The file part will come from the `filename`
|
||||
## parameter used in a previous call to the `initRstGenerator()
|
||||
## <#initRstGenerator>`_ proc.
|
||||
##
|
||||
## The `id` will be appended with a hash character only if its length is not
|
||||
## zero, otherwise no specific anchor will be generated. In general you
|
||||
## should only pass an empty `id` value for the title of standalone rst
|
||||
## documents (they are special for the `mergeIndexes() <#mergeIndexes>`_
|
||||
## proc, see `Index (idx) file format <docgen.html#index-idx-file-format>`_
|
||||
## for more information). Unlike other index terms, title entries are
|
||||
## inserted at the beginning of the accumulated buffer to maintain a logical
|
||||
## order of entries.
|
||||
##
|
||||
## If `linkTitle` or `linkDesc` are not the empty string, two additional
|
||||
## columns with their contents will be added.
|
||||
##
|
||||
## The index won't be written to disk unless you call ``writeIndexFile``. The
|
||||
## purpose of the index is documented in the `docgen tools guide
|
||||
## <docgen.html#index-switch>`_.
|
||||
d.theIndex.add(term)
|
||||
d.theIndex.add('\t')
|
||||
## The index won't be written to disk unless you call `writeIndexFile()
|
||||
## <#writeIndexFile>`_. The purpose of the index is documented in the `docgen
|
||||
## tools guide <docgen.html#index-switch>`_.
|
||||
assert(not d.theIndex.isNil)
|
||||
var
|
||||
entry = term
|
||||
isTitle = false
|
||||
entry.add('\t')
|
||||
let htmlFile = changeFileExt(extractFilename(d.filename), HtmlExt)
|
||||
d.theIndex.add(htmlFile)
|
||||
d.theIndex.add('#')
|
||||
d.theIndex.add(id)
|
||||
entry.add(htmlFile)
|
||||
if id.len > 0:
|
||||
entry.add('#')
|
||||
entry.add(id)
|
||||
else:
|
||||
isTitle = true
|
||||
if linkTitle.len > 0 or linkDesc.len > 0:
|
||||
d.theIndex.add('\t' & linkTitle.quoteIndexColumn)
|
||||
d.theIndex.add('\t' & linkDesc.quoteIndexColumn)
|
||||
d.theIndex.add("\n")
|
||||
entry.add('\t' & linkTitle.quoteIndexColumn)
|
||||
entry.add('\t' & linkDesc.quoteIndexColumn)
|
||||
entry.add("\n")
|
||||
|
||||
if isTitle: d.theIndex.insert(entry)
|
||||
else: d.theIndex.add(entry)
|
||||
|
||||
proc hash(n: PRstNode): int =
|
||||
if n.kind == rnLeaf:
|
||||
@@ -283,8 +320,20 @@ proc hash(n: PRstNode): int =
|
||||
result = result !& hash(n.sons[i])
|
||||
result = !$result
|
||||
|
||||
proc renderIndexTerm(d: PDoc, n: PRstNode, result: var string) =
|
||||
let id = rstnodeToRefname(n) & '_' & $abs(hash(n))
|
||||
proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) =
|
||||
## Renders the string decorated within \`foobar\`\:idx\: markers.
|
||||
##
|
||||
## Additionally adds the encosed text to the index as a term. Since we are
|
||||
## interested in different instances of the same term to have different
|
||||
## entries, a table is used to keep track of the amount of times a term has
|
||||
## previously appeared to give a different identifier value for each.
|
||||
let refname = n.rstnodeToRefname
|
||||
if d.seenIndexTerms.hasKey(refname):
|
||||
d.seenIndexTerms[refname] = d.seenIndexTerms[refname] + 1
|
||||
else:
|
||||
d.seenIndexTerms[refname] = 1
|
||||
let id = refname & '_' & $d.seenIndexTerms[refname]
|
||||
|
||||
var term = ""
|
||||
renderAux(d, n, term)
|
||||
setIndexTerm(d, id, term, d.currentSection)
|
||||
@@ -298,12 +347,34 @@ type
|
||||
linkTitle: string ## If not nil, contains a prettier text for the href
|
||||
linkDesc: string ## If not nil, the title attribute of the final href
|
||||
|
||||
TIndexedDocs {.pure, final.} = TTable[TIndexEntry, seq[TIndexEntry]] ## \
|
||||
## Contains the index sequences for doc types.
|
||||
##
|
||||
## The key is a *fake* TIndexEntry which will contain the title of the
|
||||
## document in the `keyword` field and `link` will contain the html
|
||||
## filename for the document. `linkTitle` and `linkDesc` will be nil.
|
||||
##
|
||||
## The value indexed by this TIndexEntry is a sequence with the real index
|
||||
## entries found in the ``.idx`` file.
|
||||
|
||||
|
||||
proc cmp(a, b: TIndexEntry): int =
|
||||
## Sorts two ``TIndexEntry`` first by `keyword` field, then by `link`.
|
||||
result = cmpIgnoreStyle(a.keyword, b.keyword)
|
||||
if result == 0:
|
||||
result = cmpIgnoreStyle(a.link, b.link)
|
||||
|
||||
proc hash(x: TIndexEntry): THash =
|
||||
## Returns the hash for the combined fields of the type.
|
||||
##
|
||||
## The hash is computed as the chained hash of the individual string hashes.
|
||||
assert(not x.keyword.isNil)
|
||||
assert(not x.link.isNil)
|
||||
result = x.keyword.hash !& x.link.hash
|
||||
result = result !& (x.linkTitle or "").hash
|
||||
result = result !& (x.linkDesc or "").hash
|
||||
result = !$result
|
||||
|
||||
proc `<-`(a: var TIndexEntry, b: TIndexEntry) =
|
||||
shallowCopy a.keyword, b.keyword
|
||||
shallowCopy a.link, b.link
|
||||
@@ -332,43 +403,18 @@ proc sortIndex(a: var openArray[TIndexEntry]) =
|
||||
a[j] <- v
|
||||
if h == 1: break
|
||||
|
||||
proc mergeIndexes*(dir: string): string =
|
||||
## merges all index files in `dir` and returns the generated index as HTML.
|
||||
## The result is no full HTML for flexibility.
|
||||
var a: seq[TIndexEntry]
|
||||
newSeq(a, 15_000)
|
||||
setLen(a, 0)
|
||||
var L = 0
|
||||
for kind, path in walkDir(dir):
|
||||
if kind == pcFile and path.endsWith(IndexExt):
|
||||
for line in lines(path):
|
||||
let s = line.find('\t')
|
||||
if s < 0: continue
|
||||
setLen(a, L+1)
|
||||
a[L].keyword = line.substr(0, s-1)
|
||||
a[L].link = line.substr(s+1)
|
||||
if a[L].link.find('\t') > 0:
|
||||
let extraCols = a[L].link.split('\t')
|
||||
a[L].link = extraCols[0]
|
||||
assert extraCols.len == 3
|
||||
a[L].linkTitle = extraCols[1].unquoteIndexColumn
|
||||
a[L].linkDesc = extraCols[2].unquoteIndexColumn
|
||||
else:
|
||||
a[L].linkTitle = nil
|
||||
a[L].linkDesc = nil
|
||||
inc L
|
||||
sortIndex(a)
|
||||
proc generateSymbolIndex(symbols: seq[TIndexEntry]): string =
|
||||
result = ""
|
||||
var i = 0
|
||||
while i < L:
|
||||
result.addf("<dt><span>$1</span></dt><ul class=\"simple\"><dd>\n",
|
||||
[a[i].keyword])
|
||||
while i < symbols.len:
|
||||
result.addf("<dt><span>$1:</span></dt><ul class=\"simple\"><dd>\n",
|
||||
[symbols[i].keyword])
|
||||
var j = i
|
||||
while j < L and a[i].keyword == a[j].keyword:
|
||||
while j < symbols.len and symbols[i].keyword == symbols[j].keyword:
|
||||
let
|
||||
url = a[j].link
|
||||
text = if not a[j].linkTitle.isNil: a[j].linkTitle else: url
|
||||
desc = if not a[j].linkDesc.isNil: a[j].linkDesc else: ""
|
||||
url = symbols[j].link
|
||||
text = if not symbols[j].linkTitle.isNil: symbols[j].linkTitle else: url
|
||||
desc = if not symbols[j].linkDesc.isNil: symbols[j].linkDesc else: ""
|
||||
if desc.len > 0:
|
||||
result.addf("""<li><a class="reference external"
|
||||
title="$3" href="$1">$2</a></li>
|
||||
@@ -379,9 +425,246 @@ proc mergeIndexes*(dir: string): string =
|
||||
inc j
|
||||
result.add("</ul></dd>\n")
|
||||
i = j
|
||||
|
||||
proc isDocumentationTitle(hyperlink: string): bool =
|
||||
## Returns true if the hyperlink is actually a documentation title.
|
||||
##
|
||||
## Documentation titles lack the hash. See `mergeIndexes() <#mergeIndexes>`_
|
||||
## for a more detailed explanation.
|
||||
result = hyperlink.find('#') < 0
|
||||
|
||||
proc stripTOCLevel(s: string): tuple[level: int, text: string] =
|
||||
## Returns the *level* of the toc along with the text without it.
|
||||
for c in 0 .. <s.len:
|
||||
result.level = c
|
||||
if s[c] != ' ': break
|
||||
result.text = s[result.level .. <s.len]
|
||||
|
||||
proc indentToLevel(level: var int, newLevel: int): string =
|
||||
## Returns the sequence of <ul>|</ul> characters to switch to `newLevel`.
|
||||
##
|
||||
## The amount of lists added/removed will be based on the `level` variable,
|
||||
## which will be reset to `newLevel` at the end of the proc.
|
||||
result = ""
|
||||
if level == newLevel:
|
||||
return
|
||||
if newLevel > level:
|
||||
result = repeatStr(newLevel - level, "<ul>")
|
||||
else:
|
||||
result = repeatStr(level - newLevel, "</ul>")
|
||||
level = newLevel
|
||||
|
||||
proc generateDocumentationTOC(entries: seq[TIndexEntry]): string =
|
||||
## Returns the sequence of index entries in an HTML hierarchical list.
|
||||
result = ""
|
||||
# Build a list of levels and extracted titles to make processing easier.
|
||||
var
|
||||
titleRef: string
|
||||
levels: seq[tuple[level: int, text: string]]
|
||||
L = 0
|
||||
level = 1
|
||||
levels.newSeq(entries.len)
|
||||
for entry in entries:
|
||||
let (rawLevel, rawText) = stripTOCLevel(entry.linkTitle or entry.keyword)
|
||||
if rawLevel < 1:
|
||||
# This is a normal symbol, push it *inside* one level from the last one.
|
||||
levels[L].level = level + 1
|
||||
# Also, ignore the linkTitle and use directly the keyword.
|
||||
levels[L].text = entry.keyword
|
||||
else:
|
||||
# The level did change, update the level indicator.
|
||||
level = rawLevel
|
||||
levels[L].level = rawLevel
|
||||
levels[L].text = rawText
|
||||
inc L
|
||||
|
||||
# Now generate hierarchical lists based on the precalculated levels.
|
||||
result = "<ul>\n"
|
||||
level = 1
|
||||
L = 0
|
||||
while L < entries.len:
|
||||
let link = entries[L].link
|
||||
if link.isDocumentationTitle:
|
||||
titleRef = link
|
||||
else:
|
||||
result.add(level.indentToLevel(levels[L].level))
|
||||
result.add("<li><a href=\"" & link & "\">" &
|
||||
levels[L].text & "</a>\n")
|
||||
inc L
|
||||
result.add(level.indentToLevel(1) & "</ul>\n")
|
||||
assert(not titleRef.isNil,
|
||||
"Can't use this proc on an API index, docs always have a title entry")
|
||||
|
||||
proc generateDocumentationIndex(docs: TIndexedDocs): string =
|
||||
## Returns all the documentation TOCs in an HTML hierarchical list.
|
||||
result = ""
|
||||
|
||||
# Sort the titles to generate their toc in alphabetical order.
|
||||
var titles = toSeq(keys[TIndexEntry, seq[TIndexEntry]](docs))
|
||||
sort(titles, cmp)
|
||||
|
||||
for title in titles:
|
||||
let tocList = generateDocumentationTOC(docs[title])
|
||||
result.add("<ul><li><a href=\"" &
|
||||
title.link & "\">" & title.keyword & "</a>\n" & tocList & "</ul>\n")
|
||||
|
||||
proc generateDocumentationJumps(docs: TIndexedDocs): string =
|
||||
## Returns a plain list of hyperlinks to documentation TOCs in HTML.
|
||||
result = "Documents: "
|
||||
|
||||
# Sort the titles to generate their toc in alphabetical order.
|
||||
var titles = toSeq(keys[TIndexEntry, seq[TIndexEntry]](docs))
|
||||
sort(titles, cmp)
|
||||
|
||||
var chunks: seq[string] = @[]
|
||||
for title in titles:
|
||||
chunks.add("<a href=\"" & title.link & "\">" & title.keyword & "</a>")
|
||||
|
||||
result.add(chunks.join(", ") & ".<br>")
|
||||
|
||||
proc generateModuleJumps(modules: seq[string]): string =
|
||||
## Returns a plain list of hyperlinks to the list of modules.
|
||||
result = "Modules: "
|
||||
|
||||
var chunks: seq[string] = @[]
|
||||
for name in modules:
|
||||
chunks.add("<a href=\"" & name & ".html\">" & name & "</a>")
|
||||
|
||||
result.add(chunks.join(", ") & ".<br>")
|
||||
|
||||
proc readIndexDir(dir: string):
|
||||
tuple[modules: seq[string], symbols: seq[TIndexEntry], docs: TIndexedDocs] =
|
||||
## Walks `dir` reading ``.idx`` files converting them in TIndexEntry items.
|
||||
##
|
||||
## Returns the list of found module names, the list of free symbol entries
|
||||
## and the different documentation indexes. The list of modules is sorted.
|
||||
## See the documentation of ``mergeIndexes`` for details.
|
||||
result.modules = @[]
|
||||
result.docs = initTable[TIndexEntry, seq[TIndexEntry]](32)
|
||||
newSeq(result.symbols, 15_000)
|
||||
setLen(result.symbols, 0)
|
||||
var L = 0
|
||||
# Scan index files and build the list of symbols.
|
||||
for kind, path in walkDir(dir):
|
||||
if kind == pcFile and path.endsWith(IndexExt):
|
||||
var
|
||||
fileEntries: seq[TIndexEntry]
|
||||
title: TIndexEntry
|
||||
F = 0
|
||||
newSeq(fileEntries, 500)
|
||||
setLen(fileEntries, 0)
|
||||
for line in lines(path):
|
||||
let s = line.find('\t')
|
||||
if s < 0: continue
|
||||
setLen(fileEntries, F+1)
|
||||
fileEntries[F].keyword = line.substr(0, s-1)
|
||||
fileEntries[F].link = line.substr(s+1)
|
||||
# See if we detect a title, a link without a `#foobar` trailing part.
|
||||
if title.keyword.isNil and fileEntries[F].link.isDocumentationTitle:
|
||||
title.keyword = fileEntries[F].keyword
|
||||
title.link = fileEntries[F].link
|
||||
|
||||
if fileEntries[F].link.find('\t') > 0:
|
||||
let extraCols = fileEntries[F].link.split('\t')
|
||||
fileEntries[F].link = extraCols[0]
|
||||
assert extraCols.len == 3
|
||||
fileEntries[F].linkTitle = extraCols[1].unquoteIndexColumn
|
||||
fileEntries[F].linkDesc = extraCols[2].unquoteIndexColumn
|
||||
else:
|
||||
fileEntries[F].linkTitle = nil
|
||||
fileEntries[F].linkDesc = nil
|
||||
inc F
|
||||
# Depending on type add this to the list of symbols or table of APIs.
|
||||
if title.keyword.isNil:
|
||||
for i in 0 .. <F:
|
||||
# Don't add to symbols TOC entries (they start with a whitespace).
|
||||
let toc = fileEntries[i].linkTitle
|
||||
if not toc.isNil and toc.len > 0 and toc[0] == ' ':
|
||||
continue
|
||||
# Ok, non TOC entry, add it.
|
||||
setLen(result.symbols, L + 1)
|
||||
result.symbols[L] = fileEntries[i]
|
||||
inc L
|
||||
result.modules.add(path.splitFile.name)
|
||||
else:
|
||||
# Generate the symbolic anchor for index quickjumps.
|
||||
title.linkTitle = "doc_toc_" & $result.docs.len
|
||||
result.docs[title] = fileEntries
|
||||
|
||||
sort(result.modules, system.cmp)
|
||||
|
||||
proc mergeIndexes*(dir: string): string =
|
||||
## Merges all index files in `dir` and returns the generated index as HTML.
|
||||
##
|
||||
## This proc will first scan `dir` for index files with the ``.idx``
|
||||
## extension previously created by commands like ``nimrod doc|rst2html``
|
||||
## which use the ``--index:on`` switch. These index files are the result of
|
||||
## calls to `setIndexTerm() <#setIndexTerm>`_ and `writeIndexFile()
|
||||
## <#writeIndexFile>`_, so they are simple tab separated files.
|
||||
##
|
||||
## As convention this proc will split index files into two categories:
|
||||
## documentation and API. API indices will be all joined together into a
|
||||
## single big sorted index, making the bulk of the final index. This is good
|
||||
## for API documentation because many symbols are repated in different
|
||||
## modules. On the other hand, documentation indices are essentially table of
|
||||
## contents plus a few special markers. These documents will be rendered in a
|
||||
## separate section which tries to maintain the order and hierarchy of the
|
||||
## symbols in the index file.
|
||||
##
|
||||
## To differentiate between a documentation and API file a convention is
|
||||
## used: indices which contain one entry without the HTML hash character (#)
|
||||
## will be considered `documentation`, since this hash-less entry is the
|
||||
## explicit title of the document. Indices without this explicit entry will
|
||||
## be considered `generated API` extracted out of a source ``.nim`` file.
|
||||
##
|
||||
## Returns the merged and sorted indices into a single HTML block which can
|
||||
## be further embedded into nimdoc templates.
|
||||
var (modules, symbols, docs) = readIndexDir(dir)
|
||||
assert(not symbols.isNil)
|
||||
|
||||
result = ""
|
||||
# Generate a quick jump list of documents.
|
||||
if docs.len > 0:
|
||||
result.add(generateDocumentationJumps(docs))
|
||||
result.add("<p />")
|
||||
|
||||
# Generate hyperlinks to all the linked modules.
|
||||
if modules.len > 0:
|
||||
result.add(generateModuleJumps(modules))
|
||||
result.add("<p />")
|
||||
|
||||
# Generate the HTML block with API documents.
|
||||
if docs.len > 0:
|
||||
result.add("<h2>Documentation files</h2>\n")
|
||||
result.add(generateDocumentationIndex(docs))
|
||||
|
||||
# Generate the HTML block with symbols.
|
||||
if symbols.len > 0:
|
||||
sortIndex(symbols)
|
||||
result.add("<h2>API symbols</h2>\n")
|
||||
result.add(generateSymbolIndex(symbols))
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
proc stripTOCHTML(s: string): string =
|
||||
## Ugly quick hack to remove HTML tags from TOC titles.
|
||||
##
|
||||
## A TTocEntry.header field already contains rendered HTML tags. Instead of
|
||||
## implementing a proper version of renderRstToOut() which recursively
|
||||
## renders an rst tree to plain text, we simply remove text found between
|
||||
## angled brackets. Given the limited possibilities of rst inside TOC titles
|
||||
## this should be enough.
|
||||
result = s
|
||||
var first = result.find('<')
|
||||
while first >= 0:
|
||||
let last = result.find('>', first)
|
||||
if last < 0:
|
||||
# Abort, since we didn't found a closing angled bracket.
|
||||
return
|
||||
result.delete(first, last)
|
||||
first = result.find('<', first)
|
||||
|
||||
proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
|
||||
var tmp = ""
|
||||
for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp)
|
||||
@@ -393,27 +676,30 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
|
||||
d.tocPart[length].refname = refname
|
||||
d.tocPart[length].n = n
|
||||
d.tocPart[length].header = tmp
|
||||
|
||||
dispA(d.target, result,
|
||||
"\n<h$1><a class=\"toc-backref\" id=\"$2\" href=\"#$2_toc\">$3</a></h$1>",
|
||||
"\\rsth$4{$3}\\label{$2}\n", [$n.level,
|
||||
d.tocPart[length].refname, tmp,
|
||||
$chr(n.level - 1 + ord('A'))])
|
||||
|
||||
dispA(d.target, result, "\n<h$1><a class=\"toc-backref\" " &
|
||||
"id=\"$2\" href=\"#$2_toc\">$3</a></h$1>", "\\rsth$4{$3}\\label{$2}\n",
|
||||
[$n.level, d.tocPart[length].refname, tmp, $chr(n.level - 1 + ord('A'))])
|
||||
else:
|
||||
dispA(d.target, result, "\n<h$1 id=\"$2\">$3</h$1>",
|
||||
"\\rsth$4{$3}\\label{$2}\n", [
|
||||
$n.level, refname, tmp,
|
||||
$chr(n.level - 1 + ord('A'))])
|
||||
|
||||
|
||||
# Generate index entry using spaces to indicate TOC level for the output HTML.
|
||||
assert n.level >= 0
|
||||
setIndexTerm(d, refname, tmp.stripTOCHTML,
|
||||
repeatChar(max(0, n.level), ' ') & tmp)
|
||||
|
||||
proc renderOverline(d: PDoc, n: PRstNode, result: var string) =
|
||||
if d.meta[metaTitle].len == 0:
|
||||
d.currentSection = d.meta[metaTitle]
|
||||
for i in countup(0, len(n)-1):
|
||||
renderRstToOut(d, n.sons[i], d.meta[metaTitle])
|
||||
d.currentSection = d.meta[metaTitle]
|
||||
elif d.meta[metaSubtitle].len == 0:
|
||||
d.currentSection = d.meta[metaSubtitle]
|
||||
for i in countup(0, len(n)-1):
|
||||
renderRstToOut(d, n.sons[i], d.meta[metaSubtitle])
|
||||
d.currentSection = d.meta[metaSubtitle]
|
||||
else:
|
||||
var tmp = ""
|
||||
for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp)
|
||||
@@ -428,7 +714,8 @@ proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) =
|
||||
"<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>\n",
|
||||
"\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header])
|
||||
|
||||
proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, result: var string) =
|
||||
proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int,
|
||||
result: var string) =
|
||||
var tmp = ""
|
||||
while j <= high(d.tocPart):
|
||||
var a = abs(d.tocPart[j].n.level)
|
||||
@@ -572,7 +859,8 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
|
||||
[tmp])
|
||||
of rnField: renderField(d, n, result)
|
||||
of rnFieldName:
|
||||
renderAux(d, n, "<th class=\"docinfo-name\">$1:</th>", "\\item[$1:]", result)
|
||||
renderAux(d, n, "<th class=\"docinfo-name\">$1:</th>",
|
||||
"\\item[$1:]", result)
|
||||
of rnFieldBody:
|
||||
renderAux(d, n, "<td>$1</td>", " $1\n", result)
|
||||
of rnIndex:
|
||||
@@ -631,8 +919,9 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
|
||||
of rnRef:
|
||||
var tmp = ""
|
||||
renderAux(d, n, tmp)
|
||||
dispA(d.target, result, "<a class=\"reference external\" href=\"#$2\">$1</a>",
|
||||
"$1\\ref{$2}", [tmp, rstnodeToRefname(n)])
|
||||
dispA(d.target, result,
|
||||
"<a class=\"reference external\" href=\"#$2\">$1</a>",
|
||||
"$1\\ref{$2}", [tmp, rstnodeToRefname(n)])
|
||||
of rnStandaloneHyperlink:
|
||||
renderAux(d, n,
|
||||
"<a class=\"reference external\" href=\"$1\">$1</a>",
|
||||
@@ -642,9 +931,9 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
|
||||
var tmp1 = ""
|
||||
renderRstToOut(d, n.sons[0], tmp0)
|
||||
renderRstToOut(d, n.sons[1], tmp1)
|
||||
dispA(d.target, result, "<a class=\"reference external\" href=\"$2\">$1</a>",
|
||||
"\\href{$2}{$1}",
|
||||
[tmp0, tmp1])
|
||||
dispA(d.target, result,
|
||||
"<a class=\"reference external\" href=\"$2\">$1</a>",
|
||||
"\\href{$2}{$1}", [tmp0, tmp1])
|
||||
of rnDirArg, rnRaw: renderAux(d, n, result)
|
||||
of rnRawHtml:
|
||||
if d.target != outLatex:
|
||||
|
||||
Reference in New Issue
Block a user