mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-15 07:43:26 +00:00
preparations for 0.8.12
This commit is contained in:
@@ -33,7 +33,11 @@ Core
|
||||
|
||||
* `threads <threads.html>`_
|
||||
Nimrod thread support. **Note**: This is part of the system module. Do not
|
||||
import it directly.
|
||||
import it explicitely.
|
||||
|
||||
* `inboxes <inboxes.html>`_
|
||||
Nimrod message passing support for threads. **Note**: This is part of the
|
||||
system module. Do not import it explicitely.
|
||||
|
||||
* `macros <macros.html>`_
|
||||
Contains the AST API and documentation of Nimrod for writing macros.
|
||||
|
||||
184
doc/manual.txt
184
doc/manual.txt
@@ -473,10 +473,9 @@ Pre-defined integer types
|
||||
These integer types are pre-defined:
|
||||
|
||||
``int``
|
||||
the generic signed integer type; its size is platform dependent
|
||||
(the compiler chooses the processor's fastest integer type).
|
||||
This type should be used in general. An integer literal that has no type
|
||||
suffix is of this type.
|
||||
the generic signed integer type; its size is platform dependent and has the
|
||||
same size as a pointer. This type should be used in general. An integer
|
||||
literal that has no type suffix is of this type.
|
||||
|
||||
intXX
|
||||
additional signed integer types of XX bits use this naming scheme
|
||||
@@ -581,7 +580,7 @@ the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
|
||||
|
||||
Boolean type
|
||||
~~~~~~~~~~~~
|
||||
The `boolean`:idx: type is named ``bool`` in Nimrod and can be one of the two
|
||||
The `boolean`:idx: 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.
|
||||
|
||||
@@ -670,7 +669,7 @@ use explicitely:
|
||||
valueD = (3, "abc")
|
||||
|
||||
As can be seen from the example, it is possible to both specify a field's
|
||||
ordinal value and its string value by using a tuple construction. It is also
|
||||
ordinal value and its string value by using a tuple. It is also
|
||||
possible to only specify one of them.
|
||||
|
||||
|
||||
@@ -930,7 +929,7 @@ Reference and pointer types
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
References (similar to `pointers`:idx: 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.
|
||||
point to and modify the same location in memory (also called `aliasing`:idx:).
|
||||
|
||||
Nimrod distinguishes between `traced`:idx: and `untraced`:idx: references.
|
||||
Untraced references are also called *pointers*. Traced references point to
|
||||
@@ -1002,7 +1001,7 @@ pointer) as if it would have the type ``ptr TData``. Casting should only be
|
||||
done if it is unavoidable: it breaks type safety and bugs can lead to
|
||||
mysterious crashes.
|
||||
|
||||
**Note**: The example only works because the memory is initialized with zero
|
||||
**Note**: The example only works because the memory is initialized to zero
|
||||
(``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to
|
||||
``nil`` which the string assignment can handle. You need to know low level
|
||||
details like this when mixing garbage collected data with unmanaged memory.
|
||||
@@ -1055,7 +1054,7 @@ each other:
|
||||
`inline`:idx:
|
||||
The inline convention means the the caller should not call the procedure,
|
||||
but inline its code directly. Note that Nimrod does not inline, but leaves
|
||||
this to the C compiler. Thus it generates ``__inline`` procedures. This is
|
||||
this to the C compiler; it generates ``__inline`` procedures. This is
|
||||
only a hint for the compiler: it may completely ignore it and
|
||||
it may inline procedures that are not marked as ``inline``.
|
||||
|
||||
@@ -1069,8 +1068,7 @@ each other:
|
||||
|
||||
`closure`:idx:
|
||||
indicates that the procedure expects a context, a closure that needs
|
||||
to be passed to the procedure. The calling convention ``nimcall`` is
|
||||
compatible to ``closure``.
|
||||
to be passed to the procedure.
|
||||
|
||||
`syscall`:idx:
|
||||
The syscall convention is the same as ``__syscall`` in C. It is used for
|
||||
@@ -1311,7 +1309,8 @@ algorithm returns true:
|
||||
if b.kind == distinct and typeEquals(b.baseType, a): return true
|
||||
return false
|
||||
|
||||
You can, however, define your own implicit converters:
|
||||
The convertible relation can be relaxed by a user-defined type
|
||||
`converter`:idx:.
|
||||
|
||||
.. code-block:: nimrod
|
||||
converter toInt(x: char): int = result = ord(x)
|
||||
@@ -1527,27 +1526,27 @@ given, control passes after the ``case`` statement.
|
||||
To suppress the static error in the ordinal case an ``else`` part with a ``nil``
|
||||
statement can be used.
|
||||
|
||||
As a special semantic extension, an expression in an ``of`` branch of a case
|
||||
statement may evaluate to a set constructor; the set is then expanded into
|
||||
a list of its elements:
|
||||
|
||||
.. code-block:: nimrod
|
||||
const
|
||||
SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
|
||||
|
||||
proc classify(s: string) =
|
||||
case s[0]
|
||||
of SymChars, '_': echo "an identifier"
|
||||
of '0'..'9': echo "a number"
|
||||
else: echo "other"
|
||||
|
||||
# is equivalent to:
|
||||
proc classify(s: string) =
|
||||
case s[0]
|
||||
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_': echo "an identifier"
|
||||
of '0'..'9': echo "a number"
|
||||
else: echo "other"
|
||||
|
||||
As a special semantic extension, an expression in an ``of`` branch of a case
|
||||
statement may evaluate to a set constructor; the set is then expanded into
|
||||
a list of its elements:
|
||||
|
||||
.. code-block:: nimrod
|
||||
const
|
||||
SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
|
||||
|
||||
proc classify(s: string) =
|
||||
case s[0]
|
||||
of SymChars, '_': echo "an identifier"
|
||||
of '0'..'9': echo "a number"
|
||||
else: echo "other"
|
||||
|
||||
# is equivalent to:
|
||||
proc classify(s: string) =
|
||||
case s[0]
|
||||
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_': echo "an identifier"
|
||||
of '0'..'9': echo "a number"
|
||||
else: echo "other"
|
||||
|
||||
|
||||
When statement
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -2036,7 +2035,7 @@ Overloading of the subscript operator
|
||||
The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
|
||||
Overloading support is only possible if the first parameter has no type that
|
||||
already supports the built-in ``[]`` notation. Currently the compiler
|
||||
does not check this. XXX Multiple indexes
|
||||
does not check this restriction.
|
||||
|
||||
|
||||
Multi-methods
|
||||
@@ -2612,8 +2611,8 @@ iterator in which case the overloading resolution takes place:
|
||||
write(stdout, x) # not ambiguous: uses the module C's x
|
||||
|
||||
|
||||
Messages
|
||||
========
|
||||
Compiler Messages
|
||||
=================
|
||||
|
||||
The Nimrod compiler emits different kinds of messages: `hint`:idx:,
|
||||
`warning`:idx:, and `error`:idx: messages. An *error* message is emitted if
|
||||
@@ -3045,3 +3044,116 @@ This is only useful if the program is compiled as a dynamic library via the
|
||||
``--app:lib`` command line option.
|
||||
|
||||
|
||||
Threads
|
||||
=======
|
||||
|
||||
Even though Nimrod's `thread`:idx: support and semantics are preliminary,
|
||||
they should be quite usable already. To enable thread support
|
||||
the ``--threads:on`` command line switch needs to be used. The ``system``
|
||||
module then contains several threading primitives.
|
||||
See the `threads <threads.html>`_ and `inboxes <inboxes.html>`_ modules
|
||||
for the thread API.
|
||||
|
||||
Nimrod's memory model for threads is quite different than that of other common
|
||||
programming languages (C, Pascal, Java): Each thread has its own (garbage
|
||||
collected) heap and sharing of memory is restricted to global variables. This
|
||||
helps to prevent race conditions. GC efficiency is improved quite a lot,
|
||||
because the GC never has to stop other threads and see what they reference.
|
||||
Memory allocation requires no lock at all! This design easily scales to massive
|
||||
multicore processors that will become the norm in the future.
|
||||
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Since the semantic checking of threads requires a whole program analysis,
|
||||
it is quite expensive and can be turned off with ``--threadanalysis:off`` to
|
||||
improve compile times.
|
||||
|
||||
A thread proc is passed to ``createThread`` and invoked indirectly; so the
|
||||
``thread`` pragma implies ``procvar``.
|
||||
|
||||
|
||||
Actor model
|
||||
-----------
|
||||
|
||||
Nimrod supports the `actor model`:idx: of concurrency natively:
|
||||
|
||||
.. code-block:: nimrod
|
||||
type
|
||||
TMsgKind = enum
|
||||
mLine, mEof
|
||||
TMsg = object {.pure, final.}
|
||||
case k: TMsgKind
|
||||
of mEof: nil
|
||||
of mLine: data: string
|
||||
|
||||
var
|
||||
thr: TThread[TMsg]
|
||||
printedLines = 0
|
||||
m: TMsg
|
||||
|
||||
proc print() {.thread.} =
|
||||
while true:
|
||||
var x = recv[TMsg]()
|
||||
if x.k == mEof: break
|
||||
echo x.data
|
||||
discard atomicInc(printedLines)
|
||||
|
||||
createThread(thr, print)
|
||||
|
||||
var input = open("readme.txt")
|
||||
while not endOfFile(input):
|
||||
m.data = input.readLine()
|
||||
thr.send(m)
|
||||
close(input)
|
||||
m.k = mEof
|
||||
thr.send(m)
|
||||
joinThread(thr)
|
||||
|
||||
echo printedLines
|
||||
|
||||
In the actor model threads communicate only over sending messages (`send`:idx:
|
||||
and `recv`:idx: built-ins), not by sharing memory. Every thread has
|
||||
an `inbox`:idx: that keeps incoming messages until the thread requests a new
|
||||
message via the ``recv`` operation. The inbox is an unlimited FIFO queue.
|
||||
|
||||
In the above example the ``print`` thread also communicates with its
|
||||
parent thread over the ``printedLines`` global variable. In general, it is
|
||||
highly advisable to only read from globals, but not to write to them. In fact
|
||||
a write to a global that contains GC'ed memory is always wrong, because it
|
||||
violates the *no heap sharing restriction*:
|
||||
|
||||
.. code-block:: nimrod
|
||||
var
|
||||
global: string
|
||||
t: TThread[string]
|
||||
|
||||
proc horrible() {.thread.} =
|
||||
global = "string in thread local heap!"
|
||||
|
||||
createThread(t, horrible)
|
||||
joinThread(t)
|
||||
|
||||
For the above code the compiler procudes "Warning: write to foreign heap". This
|
||||
warning might become an error message in future versions of the compiler.
|
||||
|
||||
Creating a thread is an expensive operation, because a new stack and heap needs
|
||||
to be created for the thread. It is therefore highly advisable that a thread
|
||||
handles a large amount of work. Nimrod prefers *coarse grained*
|
||||
over *fine grained* concurrency.
|
||||
|
||||
|
||||
Threads and exceptions
|
||||
----------------------
|
||||
|
||||
The interaction between threads and exception is simple: A *handled* exception
|
||||
in one thread cannot affect any other thread. However, an *unhandled*
|
||||
exception in one thread terminates the whole *process*!
|
||||
|
||||
|
||||
184
doc/nimrodc.txt
184
doc/nimrodc.txt
@@ -28,7 +28,7 @@ Compiler Usage
|
||||
|
||||
Command line switches
|
||||
---------------------
|
||||
Basis command line switches are:
|
||||
Basic command line switches are:
|
||||
|
||||
.. include:: basicopt.txt
|
||||
|
||||
@@ -57,11 +57,11 @@ configuration file that is read automatically. This specific file has to
|
||||
be in the same directory as the project and be of the same name, except
|
||||
that its extension should be ``.cfg``.
|
||||
|
||||
Command line settings have priority over configuration file settings.
|
||||
|
||||
The default build of a project is a `debug build`:idx:. To compile a
|
||||
`release build`:idx: define the ``release`` symbol::
|
||||
|
||||
Command line settings have priority over configuration file settings.
|
||||
|
||||
The default build of a project is a `debug build`:idx:. To compile a
|
||||
`release build`:idx: define the ``release`` symbol::
|
||||
|
||||
nimrod c -d:release myproject.nim
|
||||
|
||||
|
||||
@@ -75,17 +75,17 @@ However, the generated C code is not platform independent. C code generated for
|
||||
Linux does not compile on Windows, for instance. The comment on top of the
|
||||
C file lists the OS, CPU and CC the file has been compiled for.
|
||||
|
||||
|
||||
Cross compilation
|
||||
=================
|
||||
|
||||
To `cross compile`:idx:, use for example::
|
||||
|
||||
nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim
|
||||
|
||||
Then move the C code and the compile script ``compile_myproject.sh`` to your
|
||||
Linux i386 machine and run the script.
|
||||
|
||||
|
||||
Cross compilation
|
||||
=================
|
||||
|
||||
To `cross compile`:idx:, use for example::
|
||||
|
||||
nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim
|
||||
|
||||
Then move the C code and the compile script ``compile_myproject.sh`` to your
|
||||
Linux i386 machine and run the script.
|
||||
|
||||
|
||||
DLL generation
|
||||
==============
|
||||
@@ -101,6 +101,8 @@ To link against ``nimrtl.dll`` use the command::
|
||||
|
||||
nimrod c -d:useNimRtl myprog.nim
|
||||
|
||||
**Note**: Currently the creation of ``nimrtl.dll`` with thread support has
|
||||
never been tested and is unlikely to work!
|
||||
|
||||
|
||||
Additional Features
|
||||
@@ -146,49 +148,49 @@ encloses the header file in ``""`` in the generated C code.
|
||||
|
||||
**Note**: This will not work for the LLVM backend.
|
||||
|
||||
|
||||
Compile pragma
|
||||
--------------
|
||||
The `compile`:idx: pragma can be used to compile and link a C/C++ source file
|
||||
with the project:
|
||||
|
||||
|
||||
Compile pragma
|
||||
--------------
|
||||
The `compile`:idx: pragma can be used to compile and link a C/C++ source file
|
||||
with the project:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
{.compile: "myfile.cpp".}
|
||||
|
||||
**Note**: Nimrod computes a CRC checksum and only recompiles the file if it
|
||||
has changed. You can use the ``-f`` command line option to force recompilation
|
||||
of the file.
|
||||
|
||||
|
||||
Link pragma
|
||||
-----------
|
||||
The `link`:idx: pragma can be used to link an additional file with the project:
|
||||
|
||||
{.compile: "myfile.cpp".}
|
||||
|
||||
**Note**: Nimrod computes a CRC checksum and only recompiles the file if it
|
||||
has changed. You can use the ``-f`` command line option to force recompilation
|
||||
of the file.
|
||||
|
||||
|
||||
Link pragma
|
||||
-----------
|
||||
The `link`:idx: pragma can be used to link an additional file with the project:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
{.link: "myfile.o".}
|
||||
|
||||
|
||||
Emit pragma
|
||||
-----------
|
||||
The `emit`:idx: 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++ or Objective C code.
|
||||
|
||||
Example:
|
||||
|
||||
{.link: "myfile.o".}
|
||||
|
||||
|
||||
Emit pragma
|
||||
-----------
|
||||
The `emit`:idx: 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++ or Objective C code.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
{.emit: """
|
||||
static int cvariable = 420;
|
||||
""".}
|
||||
|
||||
proc embedsC() {.pure.} =
|
||||
var nimrodVar = 89
|
||||
# use backticks to access Nimrod symbols within an emit section:
|
||||
{.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimrodVar`);""".}
|
||||
|
||||
embedsC()
|
||||
|
||||
{.emit: """
|
||||
static int cvariable = 420;
|
||||
""".}
|
||||
|
||||
proc embedsC() {.pure.} =
|
||||
var nimrodVar = 89
|
||||
# use backticks to access Nimrod symbols within an emit section:
|
||||
{.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimrodVar`);""".}
|
||||
|
||||
embedsC()
|
||||
|
||||
|
||||
LineDir option
|
||||
--------------
|
||||
@@ -229,22 +231,22 @@ The `volatile`:idx: pragma is for variables only. It declares the variable as
|
||||
``volatile``, whatever that means in C/C++.
|
||||
|
||||
**Note**: This pragma will not exist for the LLVM backend.
|
||||
|
||||
|
||||
Nimrod interactive mode
|
||||
=======================
|
||||
|
||||
The Nimrod compiler supports an `interactive mode`:idx:. 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
|
||||
``nimrod i``. To quit use the ``quit()`` command. To determine whether an input
|
||||
line is an incomplete statement to be continued these rules are used:
|
||||
|
||||
1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$``.
|
||||
2. The line starts with a space (indentation).
|
||||
3. The line is within a triple quoted string literal. However, the detection
|
||||
does not work if the line contains more than one ``"""``.
|
||||
|
||||
|
||||
Nimrod interactive mode
|
||||
=======================
|
||||
|
||||
The Nimrod compiler supports an `interactive mode`:idx:. 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
|
||||
``nimrod i``. To quit use the ``quit()`` command. To determine whether an input
|
||||
line is an incomplete statement to be continued these rules are used:
|
||||
|
||||
1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$``.
|
||||
2. The line starts with a space (indentation).
|
||||
3. The line is within a triple quoted string literal. However, the detection
|
||||
does not work if the line contains more than one ``"""``.
|
||||
|
||||
|
||||
Debugging with Nimrod
|
||||
@@ -294,24 +296,24 @@ However it is not efficient to do:
|
||||
var s = varA # assignment has to copy the whole string into a new buffer!
|
||||
|
||||
The compiler optimizes string case statements: A hashing scheme is used for them
|
||||
if several different string constants are used. So code like this is reasonably
|
||||
efficient:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
case normalize(k.key)
|
||||
of "name": c.name = v
|
||||
of "displayname": c.displayName = v
|
||||
of "version": c.version = v
|
||||
of "os": c.oses = split(v, {';'})
|
||||
of "cpu": c.cpus = split(v, {';'})
|
||||
of "authors": c.authors = split(v, {';'})
|
||||
of "description": c.description = v
|
||||
of "app":
|
||||
case normalize(v)
|
||||
of "console": c.app = appConsole
|
||||
of "gui": c.app = appGUI
|
||||
else: quit(errorStr(p, "expected: console or gui"))
|
||||
of "license": c.license = UnixToNativePath(k.value)
|
||||
if several different string constants are used. So code like this is reasonably
|
||||
efficient:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
case normalize(k.key)
|
||||
of "name": c.name = v
|
||||
of "displayname": c.displayName = v
|
||||
of "version": c.version = v
|
||||
of "os": c.oses = split(v, {';'})
|
||||
of "cpu": c.cpus = split(v, {';'})
|
||||
of "authors": c.authors = split(v, {';'})
|
||||
of "description": c.description = v
|
||||
of "app":
|
||||
case normalize(v)
|
||||
of "console": c.app = appConsole
|
||||
of "gui": c.app = appGUI
|
||||
else: quit(errorStr(p, "expected: console or gui"))
|
||||
of "license": c.license = UnixToNativePath(k.value)
|
||||
else: quit(errorStr(p, "unknown variable: " & k.key))
|
||||
|
||||
|
||||
|
||||
2295
doc/theindex.txt
2295
doc/theindex.txt
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user