added tools and web dirs
This commit is contained in:
parent
300430fbba
commit
66a7e3d37c
489 changed files with 4593 additions and 9878 deletions
129
doc/intern.txt
Normal file → Executable file
129
doc/intern.txt
Normal file → Executable 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue