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

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