summary refs log tree commit diff stats
path: root/doc/intern.txt
diff options
context:
space:
mode:
authorAdam Strzelecki <ono@java.pl>2015-09-04 23:10:48 +0200
committerAdam Strzelecki <ono@java.pl>2015-09-04 23:10:48 +0200
commit0b44d812f10c6dbf7eb7cbf13ae0dc053bb2de9d (patch)
tree3ecdeaa24c4fd828d9408b68f5b4eb9b47171e77 /doc/intern.txt
parent51488766e79a2ce21068b34ecd368c1344ce7cc1 (diff)
downloadNim-0b44d812f10c6dbf7eb7cbf13ae0dc053bb2de9d.tar.gz
doc: Trim .txt files trailing whitespace
via OSX: find . -name '*.txt' -exec sed -i '' -E 's/[[:space:]]+$//' {} +
Diffstat (limited to 'doc/intern.txt')
-rw-r--r--doc/intern.txt92
1 files changed, 46 insertions, 46 deletions
diff --git a/doc/intern.txt b/doc/intern.txt
index 9582fc96f..05847169f 100644
--- a/doc/intern.txt
+++ b/doc/intern.txt
@@ -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``!