version 0.8.5: bugfixes; compiler now maintained in Nimrod
This commit is contained in:
parent
196ef92c86
commit
90119066ad
30 changed files with 1248 additions and 3819 deletions
|
|
@ -168,7 +168,7 @@ tupleDesc ::= '[' optInd [param (comma param)*] [SAD] ']'
|
|||
|
||||
objectDef ::= 'object' [pragma] ['of' typeDesc] objectPart
|
||||
enumField ::= symbol ['=' expr]
|
||||
enumDef ::= 'enum' ['of' typeDesc] (enumField [comma] [COMMENT | IND COMMENT])+
|
||||
enumDef ::= 'enum' (enumField [comma] [COMMENT | IND COMMENT])+
|
||||
|
||||
typeDecl ::= COMMENT
|
||||
| symbol ['*'] [genericParams] ['=' typeDef] [COMMENT | IND COMMENT]
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ Path Purpose
|
|||
``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
|
||||
``rod``!
|
||||
has been used for bootstrapping, but new
|
||||
development is done with the Nimrod version.
|
||||
``rod`` Nimrod sources of the Nimrod compiler;
|
||||
automatically generated from the Pascal
|
||||
version
|
||||
version.
|
||||
``data`` data files that are used for generating source
|
||||
code
|
||||
code; not used anymore
|
||||
``doc`` the documentation; it is a bunch of
|
||||
reStructuredText files
|
||||
``dist`` additional packages for the distribution
|
||||
|
|
@ -43,80 +43,23 @@ Path Purpose
|
|||
Bootstrapping the compiler
|
||||
==========================
|
||||
|
||||
The compiler is written in a subset of Pascal with special annotations so
|
||||
that it can be translated to Nimrod code automatically. This conversion is
|
||||
done by Nimrod itself via the undocumented ``boot`` command. Thus both Nimrod
|
||||
and Free Pascal can compile the Nimrod compiler. However, the Pascal version
|
||||
has no garbage collector and leaks memory! So the Pascal version should only
|
||||
be used for bootstrapping.
|
||||
|
||||
Requirements for bootstrapping:
|
||||
|
||||
- Python (should work with version 1.5 or higher) (optional)
|
||||
- supported C compiler
|
||||
As of version 0.8.5 the compiler is maintained in Nimrod. (The first versions
|
||||
have been implemented in Object Pascal.) The Python-based build system has
|
||||
been rewritten in Nimrod too.
|
||||
|
||||
Compiling the compiler is a simple matter of running::
|
||||
|
||||
koch.py boot
|
||||
nimrod c koch.nim
|
||||
./koch boot
|
||||
|
||||
For a release version use::
|
||||
|
||||
koch.py boot -d:release
|
||||
nimrod c koch.nim
|
||||
./koch boot -d:release
|
||||
|
||||
The ``koch.py`` script is Nimrod's maintainance script. It is a replacement for
|
||||
The ``koch`` program is Nimrod's maintainance script. It is a replacement for
|
||||
make and shell scripting with the advantage that it is much more portable.
|
||||
|
||||
If you don't have Python, there is a ``boot`` Nimrod program which does roughly
|
||||
the same::
|
||||
|
||||
nimrod cc boot.nim
|
||||
./boot [-d:release]
|
||||
|
||||
|
||||
Pascal annotations
|
||||
==================
|
||||
There are some annotations that the Pascal sources use so that they can
|
||||
be converted to Nimrod automatically:
|
||||
|
||||
``{@discard} <expr>``
|
||||
Tells the compiler that a ``discard`` statement is needed for Nimrod
|
||||
here.
|
||||
|
||||
``{@cast}typ(expr)``
|
||||
Tells the compiler that the Pascal conversion is a ``cast`` in Nimrod.
|
||||
|
||||
``{@emit <code>}``
|
||||
Emits ``<code>``. The code fragment needs to be in Pascal syntax.
|
||||
|
||||
``{@ignore} <codeA> {@emit <codeB>}``
|
||||
Ignores ``<codeA>`` and instead emits ``<codeB>`` which needs to be in
|
||||
Pascal syntax. An empty ``{@emit}`` is possible too (it then only closes
|
||||
the ``<codeA>`` part).
|
||||
|
||||
``record {@tuple}``
|
||||
Is used to tell the compiler that the record type should be transformed
|
||||
to a Nimrod tuple type.
|
||||
|
||||
``^ {@ptr}``
|
||||
Is used to tell the compiler that the pointer type should be transformed
|
||||
to a Nimrod ``ptr`` type. The default is a ``ref`` type.
|
||||
|
||||
``'a' + ''``
|
||||
The idiom ``+''`` is used to tell the compiler that it is a string
|
||||
literal and not a character literal. (Pascal does not distinguish between
|
||||
character literals and string literals of length 1.)
|
||||
|
||||
``+{&}``
|
||||
This tells the compiler that Pascal's ``+`` here is a string concatenation
|
||||
and thus should be converted to ``&``. Note that this is not needed if
|
||||
any of the operands is a string literal because the compiler then can
|
||||
figure this out by itself.
|
||||
|
||||
``{@set}['a', 'b', 'c']``
|
||||
Tells the compiler that Pascal's ``[]`` constructor is a set and not an
|
||||
array. This is only needed if the compiler cannot figure this out for
|
||||
itself.
|
||||
|
||||
|
||||
Coding Guidelines
|
||||
=================
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ components called `locations`:idx:. A variable is basically a name for a
|
|||
location. Each variable and location is of a certain `type`:idx:. The
|
||||
variable's type is called `static type`:idx:, the location's type is called
|
||||
`dynamic type`:idx:. If the static type is not the same as the dynamic type,
|
||||
it is a supertype of the dynamic type.
|
||||
it is a supertype or subtype of the dynamic type.
|
||||
|
||||
An `identifier`:idx: is a symbol declared as a name for a variable, type,
|
||||
procedure, etc. The region of the program over which a declaration applies is
|
||||
|
|
@ -1066,7 +1066,7 @@ Type equality
|
|||
~~~~~~~~~~~~~
|
||||
Nimrod uses structural type equivalence for most types. Only for objects,
|
||||
enumerations and distinct types name equivalence is used. The following
|
||||
algorithm determines type equality:
|
||||
algorithm (in pseudo-code) determines type equality:
|
||||
|
||||
.. code-block:: nimrod
|
||||
proc typeEqualsAux(a, b: PType,
|
||||
|
|
@ -1362,11 +1362,12 @@ Example:
|
|||
|
||||
The `case`:idx: statement is similar to the if statement, but it represents
|
||||
a multi-branch selection. The expression after the keyword ``case`` is
|
||||
evaluated and if its value is in a *vallist* the corresponding statements
|
||||
evaluated and if its value is in a *slicelist* the corresponding statements
|
||||
(after the ``of`` keyword) are executed. If the value is not in any
|
||||
given *slicelist* the ``else`` part is executed. If there is no ``else``
|
||||
part and not all possible values that ``expr`` can hold occur in a ``vallist``,
|
||||
a static error is given. This holds only for expressions of ordinal types.
|
||||
part and not all possible values that ``expr`` can hold occur in a
|
||||
``slicelist``, a static error occurs. This holds only for expressions of
|
||||
ordinal types.
|
||||
If the expression is not of an ordinal type, and no ``else`` part is
|
||||
given, control passes after the ``case`` statement.
|
||||
|
||||
|
|
@ -1398,7 +1399,7 @@ The `when`:idx: statement is almost identical to the ``if`` statement with some
|
|||
exceptions:
|
||||
|
||||
* Each ``expr`` has to be a constant expression (of type ``bool``).
|
||||
* The statements do not open a new scope if they introduce new identifiers.
|
||||
* The statements do not open a new scope.
|
||||
* The statements that belong to the expression that evaluated to true are
|
||||
translated by the compiler, the other statements are not checked for
|
||||
semantics! However, each ``expr`` is checked for semantics.
|
||||
|
|
@ -1814,8 +1815,8 @@ One can use `tuple unpacking`:idx: to access the tuple's fields:
|
|||
Multi-methods
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Procedures always use static dispatch. Dynamic dispatch is achieved by
|
||||
`multi-methods`:idx:.
|
||||
Procedures always use static dispatch. `Multi-methods`:idx: use dynamic
|
||||
dispatch.
|
||||
|
||||
.. code-block:: nimrod
|
||||
type
|
||||
|
|
@ -2133,8 +2134,8 @@ Symbol binding within templates happens after template instantation:
|
|||
echo genId() # Error: undeclared identifier: 'lastId'
|
||||
|
||||
Exporting a template is a often a leaky abstraction. However, to compensate for
|
||||
this case, the ``bind`` operator can be used: All identifiers
|
||||
within a ``bind`` context are bound early (i.e. when the template is parsed).
|
||||
this case, the ``bind`` operator can be used: All identifiers within a ``bind``
|
||||
context are bound early (i.e. when the template is parsed).
|
||||
The affected identifiers are then always bound early even if the other
|
||||
occurences are in no ``bind`` context:
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
:Version: |nimrodversion|
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue