added tools and web dirs

This commit is contained in:
Andreas Rumpf 2009-09-15 23:22:22 +02:00
commit 66a7e3d37c
489 changed files with 4593 additions and 9878 deletions

8
doc/abstypes.txt Normal file → Executable file
View file

@ -91,7 +91,7 @@ we define our own ``+`` for dollars:
result = TDollar(int(x) + int(y))
It does not make sense to multiply a dollar with a dollar, but with a
unit-less number; and the same holds for division:
number without unit; and the same holds for division:
.. code-block::
proc `*` (x: TDollar, y: int): TDollar =
@ -121,7 +121,7 @@ But it seems we still have to repeat all this boilerplate code for
the ``TEuro`` currency. Fortunately, Nimrod has a template mechanism:
.. code-block:: nimrod
template Additive(typ: typeExpr): stmt =
template Additive(typ: typeDesc): stmt =
proc `+` *(x, y: typ): typ {.borrow.}
proc `-` *(x, y: typ): typ {.borrow.}
@ -129,13 +129,13 @@ the ``TEuro`` currency. Fortunately, Nimrod has a template mechanism:
proc `+` *(x: typ): typ {.borrow.}
proc `-` *(x: typ): typ {.borrow.}
template Multiplicative(typ, base: typeExpr): stmt =
template Multiplicative(typ, base: typeDesc): stmt =
proc `*` *(x: typ, y: base): typ {.borrow.}
proc `*` *(x: base, y: typ): typ {.borrow.}
proc `div` *(x: typ, y: base): typ {.borrow.}
proc `mod` *(x: typ, y: base): typ {.borrow.}
template Comparable(typ: typeExpr): stmt =
template Comparable(typ: typeDesc): stmt =
proc `<` * (x, y: typ): bool {.borrow.}
proc `<=` * (x, y: typ): bool {.borrow.}
proc `==` * (x, y: typ): bool {.borrow.}

0
doc/astspec.txt Normal file → Executable file
View file

0
doc/docs.txt Normal file → Executable file
View file

0
doc/endb.txt Normal file → Executable file
View file

0
doc/filelist.txt Normal file → Executable file
View file

4
doc/grammar.txt Normal file → Executable file
View file

@ -135,10 +135,10 @@ fromStmt ::= 'from' filename 'import' symbol (comma symbol)*
pragma ::= '{.' optInd (colonExpr [comma])* [SAD] ('.}' | '}')
param ::= symbol (comma symbol)* ':' typeDesc
param ::= symbol (comma symbol)* (':' typeDesc ['=' expr] | '=' expr)
paramList ::= ['(' [param (comma param)*] [SAD] ')'] [':' typeDesc]
genericParam ::= symbol [':' typeDesc]
genericParam ::= symbol [':' typeDesc] ['=' expr]
genericParams ::= '[' genericParam (comma genericParam)* [SAD] ']'
procDecl ::= 'proc' symbol ['*'] [genericParams] paramList [pragma]

129
doc/intern.txt Normal file → Executable file
View file

@ -17,7 +17,7 @@ The Nimrod project's directory structure is:
============ ==============================================
Path Purpose
============ ==============================================
``bin`` binary files go into here
``bin`` generated binary files
``build`` generated C code for the installation
``nim`` Pascal sources of the Nimrod compiler; this
should be modified, not the Nimrod version in
@ -26,16 +26,16 @@ Path Purpose
automatically generated from the Pascal
version
``data`` data files that are used for generating source
code go into here
code
``doc`` the documentation lives here; it is a bunch of
reStructuredText files
``dist`` additional packages for the distribution
``config`` configuration files for Nimrod go into here
``config`` configuration files for Nimrod
``lib`` the Nimrod library lives here; ``rod`` depends
on it!
``web`` website of Nimrod; generated by ``koch.py``
from the ``*.txt`` and ``*.tmpl`` files
``obj`` generated ``*.obj`` files go into here
``obj`` generated ``*.obj`` files
============ ==============================================
@ -72,6 +72,18 @@ the same::
./boot [-d:release]
Coding Guidelines
=================
* Use CamelCase, not underscored_identifiers.
* Indent with two spaces.
* 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 which start with
``P``.
Pascal annotations
==================
There are some annotations that the Pascal sources use so that they can
@ -153,9 +165,9 @@ Complex assignments
for any type that needs one. However, this would make the code bigger and
the RTTI is likely already there for the GC.
We already knew the type information as a graph in the compiler.
We already know the type information as a graph in the compiler.
Thus we need to serialize this graph as RTTI for C code generation.
Look at the file ``lib/hti.nim`` for more information.
Look at the file ``lib/system/hti.nim`` for more information.
The Garbage Collector
@ -243,11 +255,8 @@ Consider this example:
# r is on the stack
setRef(r.left) # here we should update the refcounts!
Though it would be possible to produce code updating the refcounts (if
necessary) before and after the call to ``setRef``, it is a complex task to
do so in the code generator. So we don't and instead decide at runtime
whether the reference is on the stack or not. The generated code looks
roughly like this:
We have to decide at runtime whether the reference is on the stack or not.
The generated code looks roughly like this:
.. code-block:: C
void setref(TNode** ref) {
@ -260,13 +269,7 @@ roughly like this:
Note that for systems with a continous stack (which most systems have)
the check whether the ref is on the stack is very cheap (only two
comparisons). Another advantage of this scheme is that the code produced is
smaller.
The algorithm in pseudo-code
----------------------------
To be written.
comparisons).
The compiler's architecture
@ -332,3 +335,93 @@ underlying C compiler already does all the hard work for us. The problem is the
common runtime library, especially the memory manager. Note that Borland's
Delphi had exactly the same problem. The workaround is to not link the GC with
the Dll and provide an extra runtime dll that needs to be initialized.
Code generation for closures
============================
Example code:
.. code-block:: nimrod
proc add(x: int): proc (y: int): int {.closure.} =
return lambda (y: int): int =
return x + y
var add2 = add(2)
echo add2(5) #OUT 7
This should produce roughly this code:
.. code-block:: nimrod
type
PClosure = ref object
fn: proc (x: int, c: PClosure): int
x: int # data
proc wasLambda(y: int, c: PClosure): int =
return y + c.x
proc add(x: int): PClosure =
var c: PClosure
new(c)
c.x = x
c.fn = wasLambda
var add2 = add(2)
echo add2.fn(5, add2)
Beware of nesting:
.. code-block:: nimrod
proc add(x: int): proc (y: int): proc (z: int): int {.closure.} {.closure.} =
return lamba (y: int): proc (z: int): int {.closure.} =
return lambda (z: int): int =
return x + y + z
var add24 = add(2)(4)
echo add24(5) #OUT 11
This should produce roughly this code:
.. code-block:: nimrod
type
PClosure1 = ref object
fn: proc (x: int, c: PClosure1): int
x: int # data
PClosure2 = ref object
fn: proc (x: int, c: PClosure2): int
y: int
c1: PClosure1
proc innerLambda(z: int, c2: PClosure2): int =
return c2.c1.x + c2.y + z
proc outerLambda1(y: int, c1: PClosure1): PClosure2 =
new(result)
result.c1 = c1
result.y = y
result.fn = innerLambda
proc add(x: int): PClosure1 =
new(result)
result.x = x
result.fn = outerLambda
var tmp = add(2)
var tmp2 = tmp.fn(4, tmp)
var add24 = tmp2.fn(4, tmp2)
echo add24(5)
Accumulator
-----------
.. code-block:: nimrod
proc GetAccumulator(start: int): proc (): int {.closure} =
var i = start
return lambda: int =
inc i
return i

2
doc/lib.txt Normal file → Executable file
View file

@ -134,7 +134,7 @@ Impure libraries
Wrappers
========
Note that the generated HTML for some of these wrappers is so huge, that it is
The generated HTML for some of these wrappers is so huge, that it is
not contained in the distribution. You can then find them on the website.
* `posix <posix.html>`_

363
doc/manual.txt Normal file → Executable file
View file

@ -8,6 +8,10 @@ Nimrod Manual
.. contents::
"Complexity" seems to be a lot like "energy": you can transfer it from the end
user to one/some of the other players, but the total amount seems to remain
pretty much constant for a given task. -- Ran
About this document
===================
@ -171,10 +175,10 @@ preferred. Another advantage is that it frees the programmer from remembering
the exact spelling of an identifier.
Literal strings
String literals
---------------
`Literal strings`:idx: can be delimited by matching double quotes, and can
`String literals`:idx: can be delimited by matching double quotes, and can
contain the following `escape sequences`:idx:\ :
================== ===================================================
@ -202,12 +206,21 @@ contain the following `escape sequences`:idx:\ :
Strings in Nimrod may contain any 8-bit value, except embedded zeros.
Literal strings can also be delimited by three double squotes
Triple quoted string literals
-----------------------------
String literals can also be delimited by three double quotes
``"""`` ... ``"""``.
Literals in this form may run for several lines, may contain ``"`` and do not
interpret any escape sequences.
For convenience, when the opening ``"""`` is immediately followed by a newline,
the newline is not included in the string.
Raw string literals
-------------------
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
@ -218,7 +231,22 @@ convenient for regular expressions or Windows paths:
var f = openFile(r"C:\texts\text.txt") # a raw string, so ``\t`` is no tab
Literal characters
Generalized raw string literals
-------------------------------
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
``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
(for example regular expressions).
The construct ``identifier"""string literal"""`` exists too. It is a shortcut
for ``identifier("""string literal""")``.
Character literals
------------------
Character literals are enclosed in single quotes ``''`` and can contain the
@ -501,7 +529,7 @@ designed for this.
Another reason is that Nimrod can support ``array[char, int]`` or
``set[char]`` efficiently as many algorithms rely on this feature. The
`TRune` type is used for Unicode characters, it can represent any Unicode
character. ``TRune`` is declared the ``unicode`` module.
character. ``TRune`` is declared in the ``unicode`` module.
@ -548,7 +576,7 @@ Subrange types
~~~~~~~~~~~~~~
A `subrange`:idx: 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
highest and lowest value of the type:
lowest and highest value of the type:
.. code-block:: nimrod
type
@ -764,7 +792,7 @@ basetype can only be an ordinal type. The reason is that sets are implemented
as high performance bit vectors.
Sets can be constructed via the set constructor: ``{}`` is the empty set. The
empty set is type combatible with any special set type. The constructor
empty set is type compatible with any special set type. The constructor
can also be used to include elements (and ranges of elements) in the set:
.. code-block:: nimrod
@ -903,9 +931,8 @@ each other:
`closure`:idx:
indicates that the procedure expects a context, a closure that needs
to be passed to the procedure. The implementation is the
same as ``cdecl``, but with a hidden pointer parameter (the
*closure*). The hidden parameter is always the last one.
to be passed to the procedure. The calling convention ``nimcall`` is
compatible to ``closure``.
`syscall`:idx:
The syscall convention is the same as ``__syscall`` in C. It is used for
@ -915,11 +942,108 @@ each other:
The generated C code will not have any explicit calling convention and thus
use the C compiler's default calling convention. This is needed because
Nimrod's default calling convention for procedures is ``fastcall`` to
improve speed. This is unlikely to be needed by the user.
improve speed.
Most calling conventions exist only for the Windows 32-bit platform.
Distinct type
~~~~~~~~~~~~~
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. Explict type conversions from a distinct type to its
base type and vice versa are allowed.
A distinct type can be used to model different physical `units`:idx: with a
numerical base type, for example. The following example models currencies.
Different currencies should not be mixed in monetary calculations. Distinct
types are a perfect tool to model different currencies:
.. code-block:: nimrod
type
TDollar = distinct int
TEuro = distinct int
var
d: TDollar
e: TEuro
echo d + 12
# Error: cannot add a number with no unit and a ``TDollar``
Unfortunetaly, ``d + 12.TDollar`` is not allowed either,
because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
a ``+`` for dollars needs to be defined:
.. code-block::
proc `+` (x, y: TDollar): TDollar =
result = TDollar(int(x) + int(y))
It does not make sense to multiply a dollar with a dollar, but with a
number without unit; and the same holds for division:
.. code-block::
proc `*` (x: TDollar, y: int): TDollar =
result = TDollar(int(x) * y)
proc `*` (x: int, y: TDollar): TDollar =
result = TDollar(x * int(y))
proc `div` ...
This quickly gets tedious. The implementations are trivial and the compiler
should not generate all this code only to optimize it away later - after all
``+`` for dollars should produce the same binary code as ``+`` for ints.
The pragma ``borrow`` has been designed to solve this problem; in principle
it generates the above trivial implementations:
.. code-block:: nimrod
proc `*` (x: TDollar, y: int): TDollar {.borrow.}
proc `*` (x: int, y: TDollar): TDollar {.borrow.}
proc `div` (x: TDollar, y: int): TDollar {.borrow.}
The ``borrow`` pragma makes the compiler use the same implementation as
the proc that deals with the distinct type's base type, so no code is
generated.
But it seems all this boilerplate code needs to be repeated for the ``TEuro``
currency. This can be solved with templates_.
.. code-block:: nimrod
template Additive(typ: typeDesc): stmt =
proc `+` *(x, y: typ): typ {.borrow.}
proc `-` *(x, y: typ): typ {.borrow.}
# unary operators:
proc `+` *(x: typ): typ {.borrow.}
proc `-` *(x: typ): typ {.borrow.}
template Multiplicative(typ, base: typeDesc): stmt =
proc `*` *(x: typ, y: base): typ {.borrow.}
proc `*` *(x: base, y: typ): typ {.borrow.}
proc `div` *(x: typ, y: base): typ {.borrow.}
proc `mod` *(x: typ, y: base): typ {.borrow.}
template Comparable(typ: typeDesc): stmt =
proc `<` * (x, y: typ): bool {.borrow.}
proc `<=` * (x, y: typ): bool {.borrow.}
proc `==` * (x, y: typ): bool {.borrow.}
template DefineCurrency(typ, base: expr): stmt =
type
typ* = distinct base
Additive(typ)
Multiplicative(typ, base)
Comparable(typ)
DefineCurrency(TDollar, int)
DefineCurrency(TEuro, int)
Type relations
--------------
@ -956,7 +1080,7 @@ algorithm determines type equality:
for i in 0..a.tupleLen-1:
if not typeEqualsAux(a[i], b[i], s): return false
result = true
of object, enum, abstract:
of object, enum, distinct:
result = a == b
of proc:
result = typeEqualsAux(a.parameterTuple, b.parameterTuple, s) and
@ -973,7 +1097,7 @@ auxiliary set ``s`` to detect this case.
Subtype relation
~~~~~~~~~~~~~~~~
If object ``b`` inherits from ``a``, ``b`` is a subtype of ``a``. This subtype
If object ``a`` inherits from ``b``, ``a`` is a subtype of ``b``. This subtype
relation is extended to the types ``var``, ``ref``, ``ptr``:
.. code-block:: nimrod
@ -987,27 +1111,70 @@ relation is extended to the types ``var``, ``ref``, ``ptr``:
of var, ref, ptr:
result = isSubtype(a.baseType, b.baseType)
XXX nil is a special value!
.. XXX nil is a special value!
Convertible relation
~~~~~~~~~~~~~~~~~~~~
A type ``a`` is convertible to type ``b`` iff the following algorithm returns
true:
A type ``a`` is **implicitely** convertible to type ``b`` iff the following
algorithm returns true:
.. code-block:: nimrod
proc isConvertible(a, b: PType): bool =
if a.kind == b.kind:
case a.kind
of proc:
# XXX range types?
proc isImplicitelyConvertible(a, b: PType): bool =
case a.kind
of proc:
if b.kind == proc:
var x = a.parameterTuple
var y = b.parameterTuple
if x.tupleLen == y.tupleLen:
for i in 0.. x.tupleLen-1:
if not isSubtype(x[i], y[i]): return false
result = isSubType(b.resultType, a.resultType)
of int8: result = b.kind in {int16, int32, int64, int}
of int16: result = b.kind in {int32, int64, int}
of int32: result = b.kind in {int64, int}
of float: result = b.kind in {float32, float64}
of float32: result = b.kind in {float64, float}
of float64: result = b.kind in {float32, float}
of seq:
result = b.kind == openArray and typeEquals(a.baseType, b.baseType)
of array:
result = b.kind == openArray and typeEquals(a.baseType, b.baseType)
if a.baseType == char and a.indexType.rangeA == 0:
result = b.kind = cstring
of cstring, ptr:
result = b.kind == pointer
of string:
result = b.kind == cstring
A type ``a`` is **explicitely** convertible to type ``b`` iff the following
algorithm returns true:
.. code-block:: nimrod
proc isIntegralType(t: PType): bool =
result = isOrdinal(t) or t.kind in {float, float32, float64}
proc isExplicitelyConvertible(a, b: PType): bool =
if isImplicitelyConvertible(a, b): return true
if isIntegralType(a) and isIntegralType(b): return true
if isSubtype(a, b) or isSubtype(b, a): return true
if a.kind == distinct and typeEquals(a.baseType, b): return true
if b.kind == distinct and typeEquals(b.baseType, a): return true
return false
Assignment compability
~~~~~~~~~~~~~~~~~~~~~~
An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an
`l-value` and ``isImplicitelyConvertible(b.typ, a.typ)`` holds.
Overloading resolution
~~~~~~~~~~~~~~~~~~~~~~
To be written.
Statements and expressions
@ -1095,7 +1262,7 @@ Type default value
============================ ==============================================
any integer type 0
any float 0.0
char '\0'
char '\\0'
bool false
ref or pointer type nil
procedural type nil
@ -1192,8 +1359,8 @@ a static error is given. This holds only for expressions of ordinal types.
If the expression is not of an ordinal type, and no ``else`` part is
given, control just passes after the ``case`` statement.
To suppress the static error in the ordinal case the programmer needs
to write an ``else`` part with a ``nil`` statement.
To suppress the static error in the ordinal case an ``else`` part with a ``nil``
statement can be used.
When statement
@ -1271,7 +1438,7 @@ Example:
# and tries to add them
var
f: TFile
if openFile(f, "numbers.txt"):
if open(f, "numbers.txt"):
try:
var a = readLine(f)
var b = readLine(f)
@ -1285,7 +1452,7 @@ Example:
except:
echo("Unknown exception!")
finally:
closeFile(f)
close(f)
The statements after the `try`:idx: are executed in sequential order unless
an exception ``e`` is raised. If the exception type of ``e`` matches any
@ -1417,7 +1584,7 @@ Example:
The `while`:idx: 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 leaved with a ``break`` statement.
so that they can be left with a ``break`` statement.
Continue statement
@ -1562,8 +1729,9 @@ type `var`).
return intToStr(x)
Operators with one parameter are prefix operators, operators with two
parameters are infix operators. There is no way to declare postfix
operators: All postfix operators are built-in and handled by the
parameters are infix operators. (However, the parser distinguishes these from
the operators position within an expression.) There is no way to declare
postfix operators: All postfix operators are built-in and handled by the
grammar explicitely.
Any operator can be called like an ordinary proc with the '`opr`'
@ -1622,18 +1790,13 @@ return values. This can be done in a cleaner way by returning a tuple:
assert t.res == 1
assert t.remainder = 3
Even more elegant is to use `tuple unpacking` to access the tuple's fields:
Even more elegant is to use `tuple unpacking`:idx: to access the tuple's fields:
.. code-block:: nimrod
var (x, y) = divmod(8, 5) # tuple unpacking
assert x == 1
assert y == 3
Unfortunately, this form of tuple unpacking is not yet implemented.
..
XXX remove this as soon as tuple unpacking is implemented
Iterators and the for statement
@ -1655,7 +1818,7 @@ Syntax::
The `for`:idx: statement is an abstract mechanism to iterate over the elements
of a container. It relies on an `iterator`:idx: to do so. Like ``while``
statements, ``for`` statements open an `implicit block`:idx:, so that they
can be leaved with a ``break`` statement. The ``for`` loop declares
can be left with a ``break`` statement. The ``for`` loop declares
iteration variables (``x`` in the example) - their scope reaches until the
end of the loop body. The iteration variables' types are inferred by the
return type of the iterator.
@ -1737,8 +1900,6 @@ possible within a single ``type`` section.
Generics
~~~~~~~~
`Version 0.7.10: Generic types like in the example do not work.`:red:
Example:
.. code-block:: nimrod
@ -1778,11 +1939,9 @@ Example:
# inorder traversal of a binary tree
# recursive iterators are not yet implemented, so this does not work in
# the current compiler!
if root.le != nil:
yield inorder(root.le)
if root.le != nil: yield inorder(root.le)
yield root.data
if root.ri != nil:
yield inorder(root.ri)
if root.ri != nil: yield inorder(root.ri)
var
root: PBinaryTree[string] # instantiate a PBinaryTree with the type string
@ -1799,12 +1958,11 @@ introduce type parameters or to instantiate a generic proc, iterator or type.
Templates
~~~~~~~~~
A `template`:idx: is a simple form of a macro. It operates on parse trees and is
processed in the semantic pass of the compiler. So they integrate well with the
rest of the language and share none of C's preprocessor macros flaws. However,
they may lead to code that is harder to understand and maintain. So one ought
to use them sparingly. The usage of ordinary procs, iterators or generics is
preferred to the usage of templates.
A `template`:idx: 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.
The syntax to *invoke* a template is the same as calling a procedure.
Example:
@ -1815,20 +1973,86 @@ Example:
assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact
templates:
| ``a > b`` is transformed into ``b < a``.
| ``a in b`` is transformed into ``contains(b, a)``.
| ``notin`` and ``isnot`` have the obvious meanings.
The "types" of templates can be the symbols ``expr`` (stands for *expression*),
``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type
description*). These are no real types, they just help the compiler parsing.
Real types can be used too; this implies that expressions are expected.
However, for parameter type checking the arguments are semantically checked
before being passed to the template. Other arguments are not semantically
checked before being passed to the template.
The template body does not open a new scope. To open a new scope a ``block``
statement can be used:
.. code-block:: nimrod
template declareInScope(x: expr, t: typeDesc): stmt =
var x: t
template declareInNewScope(x: expr, t: typeDesc): stmt =
# open a new scope:
block:
var x: t
declareInScope(a, int)
a = 42 # works, `a` is known here
declareInNewScope(b, int)
b = 42 # does not work, `b` is unknown
If there is a ``stmt`` parameter it should be the last in the template
declaration, because statements are passed to a template via a
special ``:`` syntax:
.. code-block:: nimrod
template withFile(f, fn, mode: expr, actions: stmt): stmt =
block:
var f: TFile
if open(f, fn, mode):
try:
actions
finally:
close(f)
else:
quit("cannot open: " & fn)
withFile(txt, "ttempl3.txt", fmWrite):
txt.writeln("line 1")
txt.writeln("line 2")
In the example the two ``writeln`` statements are bound to the ``actions``
parameter.
**Style note**: For code readability, it is the best idea to use the least
powerful programming construct that still suffices. So the "check list" is:
(1) Use an ordinary proc/iterator, if possible.
(2) Else: Use a generic proc/iterator, if possible.
(3) Else: Use a template, if possible.
(4) Else: Use a macro.
Macros
------
`Macros`:idx: are the most powerful feature of Nimrod. They can be used
to implement `domain specific languages`:idx:. But they may lead to code
that is harder to understand and maintain. So one ought to use them sparingly.
to implement `domain specific languages`:idx:.
While macros enable advanced compile-time code tranformations, they
cannot change Nimrod's syntax. However, this is no real restriction because
Nimrod's syntax is flexible enough anyway.
To write macros, one needs to know how the Nimrod concrete syntax is converted
to an abstract syntax tree. (Unfortunately the AST is not yet documented.)
to an abstract syntax tree.
There are two ways to invoke a macro:
(1) invoking a macro like a procedure call (`expression macros`)
@ -1847,7 +2071,7 @@ variable number of arguments:
import macros
macro debug(n: expr): stmt =
# `n` is a Nimrod AST that contains the whole macro expression
# `n` is a Nimrod AST that contains the whole macro invokation
# this macro returns a list of statements:
result = newNimNode(nnkStmtList, n)
# iterate over any argument that is passed to this macro:
@ -1948,6 +2172,7 @@ This is best illustrated by an example:
main()
.. code-block:: nimrod
# Module B
import A # A is not parsed here! Only the already known symbols
# of A are imported.
@ -1981,7 +2206,7 @@ Tuple or object scope
The field identifiers inside a tuple or object definition are valid in the
following places:
* To the end of the tuple/object definition
* To the end of the tuple/object definition.
* Field designators of a variable of the given tuple/object type.
* In all descendent types of the object type.
@ -2000,9 +2225,11 @@ iterator in which case the overloading resolution takes place:
# Module A
var x*: string
.. code-block:: nimrod
# Module B
var x*: int
.. code-block:: nimrod
# Module C
import A, B
write(stdout, x) # error: x is ambiguous
@ -2035,26 +2262,22 @@ processed on the fly during semantic checking. Pragmas are enclosed in the
special ``{.`` and ``.}`` curly brackets.
define pragma
-------------
The `define`:idx: pragma defines a conditional symbol. This symbol may only be
used in other pragmas and in the ``defined`` expression and not in ordinary
Nimrod source code. The conditional symbols go into a special symbol table.
The compiler defines the target processor and the target operating
system as conditional symbols.
Warning: The ``define`` pragma is deprecated as it conflicts with separate
compilation! One should use boolean constants as a replacement - this is
cleaner anyway.
noSideEffect pragma
-------------------
The `noSideEffect`:idx: 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``
or ``ref T`` or ``ptr T`` this means no locations are modified. It is a static
error to mark a proc/iterator to have no side effect if the compiler cannot
verify this.
undef pragma
------------
The `undef`:idx: pragma the counterpart to the define pragma. It undefines a
conditional symbol.
Warning: The ``undef`` pragma is deprecated as it conflicts with separate
compilation!
compileTime pragma
------------------
The `compileTime`:idx: 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.
error pragma

0
doc/mytest.cfg Normal file → Executable file
View file

0
doc/nimdoc.css Normal file → Executable file
View file

65
doc/nimrodc.txt Normal file → Executable file
View file

@ -107,8 +107,8 @@ non-optional argument has to be the name of the dynamic library:
proc gtk_image_new(): PGtkWidget {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
In general, importing a dynamic library does not require any special linker
options or linking with import libraries. This also
implies that no *devel* packages need to be installed.
options or linking with import libraries. This also implies that no *devel*
packages need to be installed.
No_decl Pragma
@ -279,9 +279,7 @@ However, sometimes one has to optimize. Do it in the following order:
4. try to find a better algorithm
5. do low-level optimizations
This section can only help you with the last item. Note that rewriting parts
of your program in C is *never* necessary to speed up your program, because
everything that can be done in C can be done in Nimrod.
This section can only help you with the last item.
Optimizing string handling
@ -308,31 +306,32 @@ if several different string constants are used. This is likely to be more
efficient than any hand-coded scheme.
The ECMAScript code generator
=============================
Note: As of version 0.7.0 the ECMAScript code generator is not maintained any
longer. Help if you are interested.
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:, since
it is the proper term.
The ECMAScript code generator is experimental!
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
Since ECMAScript does not have a portable means to include another module,
Nimrod just generates a long ``.js`` file.
Features or modules that the ECMAScript platform does not support are not
available. This includes:
* manual memory management (``alloc``, etc.)
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
* file management (``openfile``, etc.)
* most modules of the Standard library
* proper 64 bit integer arithmetic
* proper unsigned integer arithmetic
However, the modules `strutils`:idx:, `math`:idx:, and `times`:idx: are
available! To access the DOM, use the `dom`:idx: module that is only available
for the ECMAScript platform.
..
The ECMAScript code generator
=============================
Note: As of version 0.7.0 the ECMAScript code generator is not maintained any
longer. Help if you are interested.
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:,
since it is the proper term.
The ECMAScript code generator is experimental!
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
Since ECMAScript does not have a portable means to include another module,
Nimrod just generates a long ``.js`` file.
Features or modules that the ECMAScript platform does not support are not
available. This includes:
* manual memory management (``alloc``, etc.)
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
* file management
* most modules of the Standard library
* proper 64 bit integer arithmetic
* proper unsigned integer arithmetic
However, the modules `strutils`:idx:, `math`:idx:, and `times`:idx: are
available! To access the DOM, use the `dom`:idx: module that is only
available for the ECMAScript platform.

0
doc/overview.txt Normal file → Executable file
View file

0
doc/readme.txt Normal file → Executable file
View file

0
doc/regexprs.txt Normal file → Executable file
View file

0
doc/rst.txt Normal file → Executable file
View file

View file

@ -1,24 +0,0 @@
==============================
First steps after installation
==============================
This document explains how to *use* the Nimrod compiler.
Open your favourite text editor and type (or download it
`here <download/code/hallo.nim>`_):
.. code-block:: nimrod
:file: ../tests/hallo.nim
Save this file as ``hallo.nim`` somewhere (I refer to the location as
``$yourloc``). Now open a console and call the Nimrod compiler::
nimrod compile --run $yourloc/hallo
The ``--run`` switch tells Nimrod that it should run the generated
executable after successful compilation. If things don't work,
check if Nimrod's ``bin`` directory is in your path environment
variable. On Windows the directory ``dist\llvm-gcc4.2\bin`` may
also be required in your path.
Note that Nimrod produced a standalone native executable in
``$yourloc`` that you can run without the Nimrod compiler.

1200
doc/theindex.txt Normal file → Executable file

File diff suppressed because it is too large Load diff

0
doc/tut1.txt Normal file → Executable file
View file

46
doc/tut2.txt Normal file → Executable file
View file

@ -311,11 +311,10 @@ class provides a constructor, etc.
c.draw()
The code uses a ``draw`` procedure that is bound statically, but inside it
the dynamic dispatch happens with the help of the ``fdraw`` field. This is
slightly more inconvienent than in traditional OOP-languages, but has the
advantage of being much more flexible (and somewhat faster). The above approach
also allows some form *monkey patching* by modifying the ``fdraw`` field.
the dynamic dispatch happens with the help of the ``fdraw`` field. Even though
this solution has its advantages compared to traditional OOP-languages, it is
a **preliminary** solution. Multimethods are a planned language feature that
provide a more flexible and efficient mechanism.
Exceptions
@ -323,15 +322,13 @@ Exceptions
In Nimrod `exceptions`:idx: are objects. By convention, exception types are
prefixed with an 'E', not 'T'. The ``system`` module defines an exception
hierarchy that you should stick to. Reusing an existing exception type is
often better than defining a new exception type: It avoids a proliferation of
types.
hierarchy that you might want to stick to.
Exceptions should be allocated on the heap because their lifetime is unknown.
A convention is that exceptions should be raised in *exceptional* cases:
For example, if a file cannot be opened, this should not raise an exception
since this is quite common (the file may have been deleted).
For example, if a file cannot be opened, this should not raise an
exception since this is quite common (the file may not exist).
Raise statement
@ -359,7 +356,7 @@ The `try`:idx: statement handles exceptions:
# and tries to add them
var
f: TFile
if openFile(f, "numbers.txt"):
if open(f, "numbers.txt"):
try:
var a = readLine(f)
var b = readLine(f)
@ -375,7 +372,7 @@ The `try`:idx: statement handles exceptions:
# reraise the unknown exception:
raise
finally:
closeFile(f)
close(f)
The statements after the ``try`` are executed unless an exception is
raised. Then the appropriate ``except`` part is executed.
@ -396,8 +393,6 @@ is not executed (if an exception occurs).
Generics
========
`Version 0.7.10: Complex generic types like in the example do not work.`:red:
`Generics`:idx: are Nimrod's means to parametrize procs, iterators or types
with `type parameters`:idx:. They are most useful for efficient type safe
containers:
@ -448,7 +443,7 @@ containers:
while stack.len > 0:
var n = stack.pop()
while n != nil:
yield n
yield n.data
add(stack, n.ri) # push right subtree onto the stack
n = n.le # and follow the left pointer
@ -472,8 +467,7 @@ Templates
Templates are a simple substitution mechanism that operates on Nimrod's
abstract syntax trees. Templates are processed in the semantic pass of the
compiler. They integrate well with the rest of the language and share none
of C's preprocessor macros flaws. However, they may lead to code that is harder
to understand and maintain. So one should use them sparingly.
of C's preprocessor macros flaws.
To *invoke* a template, call it like a procedure.
@ -488,7 +482,8 @@ Example:
The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact
templates: This has the benefit that if you overload the ``==`` operator,
the ``!=`` operator is available automatically and does the right thing.
the ``!=`` operator is available automatically and does the right thing. (Except
for IEEE floating point numbers - NaN breaks basic boolean logic.)
``a > b`` is transformed into ``b < a``.
``a in b`` is transformed into ``contains(b, a)``.
@ -513,7 +508,7 @@ This code has a shortcoming: If ``debug`` is set to false someday, the quite
expensive ``$`` and ``&`` operations are still performed! (The argument
evaluation for procedures is said to be *eager*).
Turning the ``log`` proc into a template solves this problem in an elegant way:
Turning the ``log`` proc into a template solves this problem:
.. code-block:: nimrod
const
@ -530,7 +525,7 @@ Turning the ``log`` proc into a template solves this problem in an elegant way:
The "types" of templates can be the symbols ``expr`` (stands for *expression*),
``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type
description*). These are no real types, they just help the compiler parsing.
In later versions, real types will be supported too.
However, real types are supported too.
The template body does not open a new scope. To open a new scope
use a ``block`` statement:
@ -557,7 +552,8 @@ via a special ``:`` syntax:
.. code-block:: nimrod
template withFile(f, filename, mode: expr, actions: stmt): stmt =
template withFile(f: expr, filename: string, mode: TFileMode,
actions: stmt): stmt =
block:
var fn = filename
var f: TFile
@ -583,11 +579,6 @@ once.
Macros
======
If the template mechanism scares you, you will be pleased to hear that
templates are not really necessary: Macros can do anything that templates can
do and much more. Macros are harder to write than templates and even harder
to get right :-). Now that you have been warned, lets see what a macro *is*.
Macros enable advanced compile-time code tranformations, but they
cannot change Nimrod's syntax. However, this is no real restriction because
Nimrod's syntax is flexible enough anyway.
@ -598,7 +589,8 @@ to an abstract syntax tree (AST). The AST is documented in the
There are two ways to invoke a macro:
(1) invoking a macro like a procedure call (`expression macros`:idx:)
(2) invoking a macro with the special ``macrostmt`` syntax (`statement macros`:idx:)
(2) invoking a macro with the special ``macrostmt``
syntax (`statement macros`:idx:)
Expression Macros