Nimrod renamed to Nim
This commit is contained in:
parent
c95e47216f
commit
3ea6446900
30 changed files with 379 additions and 379 deletions
|
|
@ -1,10 +1,10 @@
|
|||
=========================================
|
||||
Internals of the Nimrod Compiler
|
||||
Internals of the Nim Compiler
|
||||
=========================================
|
||||
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimrodversion|
|
||||
:Version: |nimversion|
|
||||
|
||||
.. contents::
|
||||
|
||||
|
|
@ -14,23 +14,23 @@
|
|||
Directory structure
|
||||
===================
|
||||
|
||||
The Nimrod project's directory structure is:
|
||||
The Nim project's directory structure is:
|
||||
|
||||
============ ==============================================
|
||||
Path Purpose
|
||||
============ ==============================================
|
||||
``bin`` generated binary files
|
||||
``build`` generated C code for the installation
|
||||
``compiler`` the Nimrod compiler itself; note that this
|
||||
``compiler`` the Nim compiler itself; note that this
|
||||
code has been translated from a bootstrapping
|
||||
version written in Pascal, so the code is **not**
|
||||
a poster child of good Nimrod code
|
||||
``config`` configuration files for Nimrod
|
||||
a poster child of good Nim code
|
||||
``config`` configuration files for Nim
|
||||
``dist`` additional packages for the distribution
|
||||
``doc`` the documentation; it is a bunch of
|
||||
reStructuredText files
|
||||
``lib`` the Nimrod library
|
||||
``web`` website of Nimrod; generated by ``nimweb``
|
||||
``lib`` the Nim library
|
||||
``web`` website of Nim; generated by ``nimweb``
|
||||
from the ``*.txt`` and ``*.tmpl`` files
|
||||
============ ==============================================
|
||||
|
||||
|
|
@ -38,26 +38,26 @@ Path Purpose
|
|||
Bootstrapping the compiler
|
||||
==========================
|
||||
|
||||
As of version 0.8.5 the compiler is maintained in Nimrod. (The first versions
|
||||
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 Nimrod too.
|
||||
been rewritten in Nim too.
|
||||
|
||||
Compiling the compiler is a simple matter of running::
|
||||
|
||||
nimrod c koch.nim
|
||||
nim c koch.nim
|
||||
./koch boot
|
||||
|
||||
For a release version use::
|
||||
|
||||
nimrod c koch.nim
|
||||
nim c koch.nim
|
||||
./koch boot -d:release
|
||||
|
||||
And for a debug version compatible with GDB::
|
||||
|
||||
nimrod c koch.nim
|
||||
nim c koch.nim
|
||||
./koch boot --debuginfo --linedir:on
|
||||
|
||||
The ``koch`` program is Nimrod's maintenance script. It is a replacement for
|
||||
The ``koch`` program is Nim's maintenance script. It is a replacement for
|
||||
make and shell scripting with the advantage that it is much more portable.
|
||||
More information about its options can be found in the `koch <koch.html>`_
|
||||
documentation.
|
||||
|
|
@ -80,13 +80,13 @@ See also the `API naming design <apis.html>`_ document.
|
|||
Porting to new platforms
|
||||
========================
|
||||
|
||||
Porting Nimrod to a new architecture is pretty easy, since C is the most
|
||||
portable programming language (within certain limits) and Nimrod generates
|
||||
Porting Nim to a new architecture is pretty easy, since C is the most
|
||||
portable programming language (within certain limits) and Nim generates
|
||||
C code, porting the code generator is not necessary.
|
||||
|
||||
POSIX-compliant systems on conventional hardware are usually pretty easy to
|
||||
port: Add the platform to ``platform`` (if it is not already listed there),
|
||||
check that the OS, System modules work and recompile Nimrod.
|
||||
check that the OS, System modules work and recompile Nim.
|
||||
|
||||
The only case where things aren't as easy is when the garbage
|
||||
collector needs some assembler tweaking to work. The standard
|
||||
|
|
@ -98,7 +98,7 @@ replace this generic code by some assembler code.
|
|||
Runtime type information
|
||||
========================
|
||||
|
||||
*Runtime type information* (RTTI) is needed for several aspects of the Nimrod
|
||||
*Runtime type information* (RTTI) is needed for several aspects of the Nim
|
||||
programming language:
|
||||
|
||||
Garbage collection
|
||||
|
|
@ -108,7 +108,7 @@ Garbage collection
|
|||
|
||||
Complex assignments
|
||||
Sequences and strings are implemented as
|
||||
pointers to resizeable buffers, but Nimrod requires copying for
|
||||
pointers to resizeable buffers, but Nim requires copying for
|
||||
assignments. Apart from RTTI the compiler could generate copy procedures
|
||||
for any type that needs one. However, this would make the code bigger and
|
||||
the RTTI is likely already there for the GC.
|
||||
|
|
@ -121,12 +121,12 @@ Look at the file ``lib/system/hti.nim`` for more information.
|
|||
The compiler's architecture
|
||||
===========================
|
||||
|
||||
Nimrod uses the classic compiler architecture: A lexer/scanner feds tokens to a
|
||||
Nim uses the classic compiler architecture: A lexer/scanner feds tokens to a
|
||||
parser. The parser builds a syntax tree that is used by the code generator.
|
||||
This syntax tree is the interface between the parser and the code generator.
|
||||
It is essential to understand most of the compiler's code.
|
||||
|
||||
In order to compile Nimrod correctly, type-checking has to be separated from
|
||||
In order to compile Nim correctly, type-checking has to be separated from
|
||||
parsing. Otherwise generics cannot work.
|
||||
|
||||
.. include:: filelist.txt
|
||||
|
|
@ -172,7 +172,7 @@ Frontend issues
|
|||
Methods and type converters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Nimrod contains language features that are *global*. The best example for that
|
||||
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
|
||||
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
|
||||
|
|
@ -181,12 +181,12 @@ after the whole program has been translated!
|
|||
Other features that are *implicitly* triggered cause problems for modularity
|
||||
too. Type converters fall into this category:
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. code-block:: nim
|
||||
# module A
|
||||
converter toBool(x: int): bool =
|
||||
result = x != 0
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. code-block:: nim
|
||||
# module B
|
||||
import A
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ turned on".
|
|||
|
||||
|
||||
|
||||
Debugging Nimrod's memory management
|
||||
Debugging Nim's memory management
|
||||
====================================
|
||||
|
||||
The following paragraphs are mostly a reminder for myself. Things to keep
|
||||
|
|
@ -262,7 +262,7 @@ in mind:
|
|||
|
||||
* Segmentation faults can have multiple reasons: One that is frequently
|
||||
forgotten is that *stack overflow* can trigger one!
|
||||
* If an assertion in Nimrod's memory manager or GC fails, the stack trace
|
||||
* If an assertion in Nim's memory manager or GC fails, the stack trace
|
||||
keeps allocating memory! Thus a stack overflow may happen, hiding the
|
||||
real issue.
|
||||
* What seem to be C code generation problems is often a bug resulting from
|
||||
|
|
@ -300,7 +300,7 @@ set of pointers - this is called a ``TCellSet`` in the source code.
|
|||
Inserting, deleting and searching are done in constant time. However,
|
||||
modifying a ``TCellSet`` during traversation leads to undefined behaviour.
|
||||
|
||||
.. code-block:: Nimrod
|
||||
.. code-block:: Nim
|
||||
type
|
||||
TCellSet # hidden
|
||||
|
||||
|
|
@ -340,11 +340,11 @@ Complete traversal is done in this way::
|
|||
Further complications
|
||||
---------------------
|
||||
|
||||
In Nimrod the compiler cannot always know if a reference
|
||||
In Nim the compiler cannot always know if a reference
|
||||
is stored on the stack or not. This is caused by var parameters.
|
||||
Consider this example:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
.. code-block:: Nim
|
||||
proc setRef(r: var ref TNode) =
|
||||
new(r)
|
||||
|
||||
|
|
@ -380,7 +380,7 @@ Code generation for closures is implemented by `lambda lifting`:idx:.
|
|||
Design
|
||||
------
|
||||
|
||||
A ``closure`` proc var can call ordinary procs of the default Nimrod calling
|
||||
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
|
||||
|
|
@ -393,7 +393,7 @@ Tests with GCC on Amd64 showed that it's really beneficical if the
|
|||
Proper thunk generation is harder because the proc that is to wrap
|
||||
could stem from a complex expression:
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. code-block:: nim
|
||||
receivesClosure(returnsDefaultCC[i])
|
||||
|
||||
A thunk would need to call 'returnsDefaultCC[i]' somehow and that would require
|
||||
|
|
@ -405,7 +405,7 @@ to pass a proc pointer around via a generic ``ref`` type.
|
|||
|
||||
Example code:
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. code-block:: nim
|
||||
proc add(x: int): proc (y: int): int {.closure.} =
|
||||
return proc (y: int): int =
|
||||
return x + y
|
||||
|
|
@ -415,7 +415,7 @@ Example code:
|
|||
|
||||
This should produce roughly this code:
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. code-block:: nim
|
||||
type
|
||||
PEnv = ref object
|
||||
x: int # data
|
||||
|
|
@ -436,7 +436,7 @@ This should produce roughly this code:
|
|||
|
||||
Beware of nesting:
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. 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 =
|
||||
|
|
@ -447,7 +447,7 @@ Beware of nesting:
|
|||
|
||||
This should produce roughly this code:
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. code-block:: nim
|
||||
type
|
||||
PEnvX = ref object
|
||||
x: int # data
|
||||
|
|
@ -492,7 +492,7 @@ environments. This is however not always possible.
|
|||
Accumulator
|
||||
-----------
|
||||
|
||||
.. code-block:: nimrod
|
||||
.. code-block:: nim
|
||||
proc GetAccumulator(start: int): proc (): int {.closure} =
|
||||
var i = start
|
||||
return lambda: int =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue