doc: Trim .txt files trailing whitespace

via OSX: find . -name '*.txt' -exec sed -i '' -E 's/[[:space:]]+$//' {} +
This commit is contained in:
Adam Strzelecki 2015-09-04 23:10:48 +02:00
commit 0b44d812f1
33 changed files with 566 additions and 566 deletions

View file

@ -22,8 +22,8 @@ Path Purpose
``bin`` generated binary files
``build`` generated C code for the installation
``compiler`` the Nim compiler itself; note that this
code has been translated from a bootstrapping
version written in Pascal, so the code is **not**
code has been translated from a bootstrapping
version written in Pascal, so the code is **not**
a poster child of good Nim code
``config`` configuration files for Nim
``dist`` additional packages for the distribution
@ -38,8 +38,8 @@ Path Purpose
Bootstrapping the compiler
==========================
As of version 0.8.5 the compiler is maintained in Nim. (The first versions
have been implemented in Object Pascal.) The Python-based build system has
As of version 0.8.5 the compiler is maintained in Nim. (The first versions
have been implemented in Object Pascal.) The Python-based build system has
been rewritten in Nim too.
Compiling the compiler is a simple matter of running::
@ -121,7 +121,7 @@ Look at the file ``lib/system/hti.nim`` for more information.
Debugging the compiler
======================
You can of course use GDB or Visual Studio to debug the
You can of course use GDB or Visual Studio to debug the
compiler (via ``--debuginfo --lineDir:on``). However, there
are also lots of procs that aid in debugging:
@ -180,7 +180,7 @@ children. Types and symbols are represented by other nodes, because they
may contain cycles. The AST changes its shape after semantic checking. This
is needed to make life easier for the code generators. See the "ast" module
for the type definitions. The `macros <macros.html>`_ module contains many
examples how the AST represents each syntactic structure.
examples how the AST represents each syntactic structure.
How the RTL is compiled
@ -202,7 +202,7 @@ Compilation cache
=================
The implementation of the compilation cache is tricky: There are lots
of issues to be solved for the front- and backend. In the following
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*.
@ -214,31 +214,31 @@ Methods and type converters
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Nim contains language features that are *global*. The best example for that
are multi methods: Introducing a new method with the same name and some
are multi methods: Introducing a new method with the same name and some
compatible object parameter means that the method's dispatcher needs to take
the new method into account. So the dispatching logic is only completely known
after the whole program has been translated!
Other features that are *implicitly* triggered cause problems for modularity
Other features that are *implicitly* triggered cause problems for modularity
too. Type converters fall into this category:
.. code-block:: nim
# module A
converter toBool(x: int): bool =
result = x != 0
.. code-block:: nim
# module B
import A
if 1:
echo "ugly, but should work"
If in the above example module ``B`` is re-compiled, but ``A`` is not then
``B`` needs to be aware of ``toBool`` even though ``toBool`` is not referenced
in ``B`` *explicitly*.
in ``B`` *explicitly*.
Both the multi method and the type converter problems are solved by storing
Both the multi method and the type converter problems are solved by storing
them in special sections in the ROD file that are loaded *unconditionally*
when the ROD file is read.
@ -266,7 +266,7 @@ Backend issues
- Emulated thread vars are global.
However the biggest problem is that dead code elimination breaks modularity!
However the biggest problem is that dead code elimination breaks modularity!
To see why, consider this scenario: The module ``G`` (for example the huge
Gtk2 module...) is compiled with dead code elimination turned on. So none
of ``G``'s procs is generated at all.
@ -274,13 +274,13 @@ of ``G``'s procs is generated at all.
Then module ``B`` is compiled that requires ``G.P1``. Ok, no problem,
``G.P1`` is loaded from the symbol file and ``G.c`` now contains ``G.P1``.
Then module ``A`` (that depends onto ``B`` and ``G``) is compiled and ``B``
Then module ``A`` (that depends onto ``B`` and ``G``) is compiled and ``B``
and ``G`` are left unchanged. ``A`` requires ``G.P2``.
So now ``G.c`` MUST contain both ``P1`` and ``P2``, but we haven't even
loaded ``P1`` from the symbol file, nor do we want to because we then quickly
would restore large parts of the whole program. But we also don't want to
store ``P1`` in ``B.c`` because that would mean to store every symbol where
So now ``G.c`` MUST contain both ``P1`` and ``P2``, but we haven't even
loaded ``P1`` from the symbol file, nor do we want to because we then quickly
would restore large parts of the whole program. But we also don't want to
store ``P1`` in ``B.c`` because that would mean to store every symbol where
it is referred from which ultimately means the main module and putting
everything in a single C file.
@ -290,7 +290,7 @@ that is implemented in the C code generator (have a look at the ``ccgmerge``
module). The merging may lead to *cruft* (aka dead code) in generated C code
which can only be removed by recompiling a project with the compilation cache
turned off. Nevertheless the merge solution is way superior to the
cheap solution "turn off dead code elimination if the compilation cache is
cheap solution "turn off dead code elimination if the compilation cache is
turned on".
@ -394,7 +394,7 @@ Consider this example:
# r is on the stack
setRef(r.left) # here we should update the refcounts!
We have to decide at runtime whether the reference is on the stack or not.
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
@ -422,7 +422,7 @@ Design
A ``closure`` proc var can call ordinary procs of the default Nim calling
convention. But not the other way round! A closure is implemented as a
``tuple[prc, env]``. ``env`` can be nil implying a call without a closure.
This means that a call through a closure generates an ``if`` but the
This means that a call through a closure generates an ``if`` but the
interoperability is worth the cost of the ``if``. Thunk generation would be
possible too, but it's slightly more effort to implement.
@ -430,7 +430,7 @@ Tests with GCC on Amd64 showed that it's really beneficical if the
'environment' pointer is passed as the last argument, not as the first argument.
Proper thunk generation is harder because the proc that is to wrap
could stem from a complex expression:
could stem from a complex expression:
.. code-block:: nim
receivesClosure(returnsDefaultCC[i])
@ -438,15 +438,15 @@ could stem from a complex expression:
A thunk would need to call 'returnsDefaultCC[i]' somehow and that would require
an *additional* closure generation... Ok, not really, but it requires to pass
the function to call. So we'd end up with 2 indirect calls instead of one.
Another much more severe problem which this solution is that it's not GC-safe
Another much more severe problem which this solution is that it's not GC-safe
to pass a proc pointer around via a generic ``ref`` type.
Example code:
.. code-block:: nim
proc add(x: int): proc (y: int): int {.closure.} =
return proc (y: int): int =
proc add(x: int): proc (y: int): int {.closure.} =
return proc (y: int): int =
return x + y
var add2 = add(2)
@ -458,16 +458,16 @@ This should produce roughly this code:
type
PEnv = ref object
x: int # data
proc anon(y: int, c: PClosure): int =
proc anon(y: int, c: PClosure): int =
return y + c.x
proc add(x: int): tuple[prc, data] =
var env: PEnv
new env
env.x = x
result = (anon, env)
var add2 = add(2)
let tmp = if add2.data == nil: add2.prc(5) else: add2.prc(5, add2.data)
echo tmp
@ -476,9 +476,9 @@ This should produce roughly this code:
Beware of nesting:
.. code-block:: nim
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 =
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)
@ -490,26 +490,26 @@ This should produce roughly this code:
type
PEnvX = ref object
x: int # data
PEnvY = ref object
y: int
ex: PEnvX
proc lambdaZ(z: int, ey: PEnvY): int =
return ey.ex.x + ey.y + z
proc lambdaY(y: int, ex: PEnvX): tuple[prc, data: PEnvY] =
var ey: PEnvY
new ey
ey.y = y
ey.ex = ex
result = (lambdaZ, ey)
proc add(x: int): tuple[prc, data: PEnvX] =
var ex: PEnvX
ex.x = x
result = (labmdaY, ex)
var tmp = add(2)
var tmp2 = tmp.fn(4, tmp.data)
var add24 = tmp2.fn(4, tmp2.data)
@ -517,14 +517,14 @@ This should produce roughly this code:
We could get rid of nesting environments by always inlining inner anon procs.
More useful is escape analysis and stack allocation of the environment,
More useful is escape analysis and stack allocation of the environment,
however.
Alternative
-----------
Process the closure of all inner procs in one pass and accumulate the
Process the closure of all inner procs in one pass and accumulate the
environments. This is however not always possible.
@ -532,21 +532,21 @@ Accumulator
-----------
.. code-block:: nim
proc getAccumulator(start: int): proc (): int {.closure} =
proc getAccumulator(start: int): proc (): int {.closure} =
var i = start
return lambda: int =
return lambda: int =
inc i
return i
proc p =
var delta = 7
proc accumulator(start: int): proc(): int =
var x = start-1
result = proc (): int =
result = proc (): int =
x = x + delta
inc delta
return x
var a = accumulator(3)
var b = accumulator(4)
echo a() + b()
@ -560,7 +560,7 @@ pass generates code to setup the environment and to pass it around. However,
this pass does not change the types! So we have some kind of mismatch here; on
the one hand the proc expression becomes an explicit tuple, on the other hand
the tyProc(ccClosure) type is not changed. For C code generation it's also
important the hidden formal param is ``void*`` and not something more
important the hidden formal param is ``void*`` and not something more
specialized. However the more specialized env type needs to passed to the
backend somehow. We deal with this by modifying ``s.ast[paramPos]`` to contain
the formal hidden parameter, but not ``s.typ``!