changed to {.experimental: codeReordering.}, postpoing declared() stuff

This commit is contained in:
awr
2018-09-06 23:49:38 -05:00
parent 47726ecb9e
commit 32deb70bae

View File

@@ -6418,6 +6418,111 @@ iterator in which case the overloading resolution takes place:
var x = 4
write(stdout, x) # not ambiguous: uses the module C's x
Code reordering
~~~~~~~~~~~~~~~
**Note**: Code reordering is experimental and must be enabled via the
``{.experimental.}`` pragma.
The code reordering feature can implicitly rearrange procedure, template, and
macro definitions along with variable declarations and initializations at the top
level scope so that, to a large extent, a programmer should not have to worry
about ordering definitions correctly or be forced to use forward declarations to
preface definitions inside a module.
..
NOTE: The following was documentation for the code reordering precursor,
which was {.noForward.}.
In this mode, procedure definitions may appear out of order and the compiler
will postpone their semantic analysis and compilation until it actually needs
to generate code using the definitions. In this regard, this mode is similar
to the modus operandi of dynamic scripting languages, where the function
calls are not resolved until the code is executed. Here is the detailed
algorithm taken by the compiler:
1. When a callable symbol is first encountered, the compiler will only note
the symbol callable name and it will add it to the appropriate overload set
in the current scope. At this step, it won't try to resolve any of the type
expressions used in the signature of the symbol (so they can refer to other
not yet defined symbols).
2. When a top level call is encountered (usually at the very end of the
module), the compiler will try to determine the actual types of all of the
symbols in the matching overload set. This is a potentially recursive process
as the signatures of the symbols may include other call expressions, whose
types will be resolved at this point too.
3. Finally, after the best overload is picked, the compiler will start
compiling the body of the respective symbol. This in turn will lead the
compiler to discover more call expressions that need to be resolved and steps
2 and 3 will be repeated as necessary.
Please note that if a callable symbol is never used in this scenario, its
body will never be compiled. This is the default behavior leading to best
compilation times, but if exhaustive compilation of all definitions is
required, using ``nim check`` provides this option as well.
Example:
.. code-block:: nim
{.experimental: "codeReordering".}
proc foo(x: int) =
bar(x)
proc bar(x: int) =
echo(x)
foo(10)
Variables can also be reordered as well. Keep in mind, when we initialize (i.e.
combined declaration and assignment in one statement) variables, that entire
statement itself may be reordered. Be wary of what code you execute at the top
level:
.. code-block:: nim
{.experimental: "codeReordering".}
proc a() =
echo(foo)
var foo = 5
a() # outputs: "5"
..
TODO: Let's table this for now. This is an *experimental feature* and so the
specific manner in which ``declared`` operates with it can be decided in
eventuality.
The values of expressions involving ``declared`` are decided *before* the
code reordering process, and not after. As an example, the output of this
code is the same as it would be with code reordering disabled.
.. code-block:: nim
{.experimental: "codeReordering".}
proc x() =
echo(declared(foo))
var foo = 4
x() # "false"
It is important to note that reordering *only* works for symbols at top level
scope. Therefore, the following will *fail to compile:*
.. code-block:: nim
{.experimental: "codeReordering".}
proc a() =
b()
proc b() =
echo("Hello!")
a()
Compiler Messages
=================
@@ -6825,103 +6930,6 @@ and before any variable in a module that imports it.
reorder pragma
--------------
**Note**: Code reordering is experimental. By default it is turned off.
The ``reorder`` pragma can be used to turn on and off a special compilation mode
that aims to be able to implicitly rearrange procedure, template, and macro
definitions along with variable declarations and initializations at the top
level scope so that, to a large extent, a programmer should not have to worry
about ordering definitions correctly or be forced to use forward declarations to
preface definitions inside a module.
..
NOTE: The following was documentation for the precursor to {.reorder.},
which was {.noForward.}.
In this mode, procedure definitions may appear out of order and the compiler
will postpone their semantic analysis and compilation until it actually needs
to generate code using the definitions. In this regard, this mode is similar
to the modus operandi of dynamic scripting languages, where the function
calls are not resolved until the code is executed. Here is the detailed
algorithm taken by the compiler:
1. When a callable symbol is first encountered, the compiler will only note
the symbol callable name and it will add it to the appropriate overload set
in the current scope. At this step, it won't try to resolve any of the type
expressions used in the signature of the symbol (so they can refer to other
not yet defined symbols).
2. When a top level call is encountered (usually at the very end of the
module), the compiler will try to determine the actual types of all of the
symbols in the matching overload set. This is a potentially recursive process
as the signatures of the symbols may include other call expressions, whose
types will be resolved at this point too.
3. Finally, after the best overload is picked, the compiler will start
compiling the body of the respective symbol. This in turn will lead the
compiler to discover more call expressions that need to be resolved and steps
2 and 3 will be repeated as necessary.
Please note that if a callable symbol is never used in this scenario, its
body will never be compiled. This is the default behavior leading to best
compilation times, but if exhaustive compilation of all definitions is
required, using ``nim check`` provides this option as well.
Example:
.. code-block:: nim
{.reorder: on.}
proc foo(x: int) =
bar(x)
proc bar(x: int) =
echo(x)
foo(10)
Variables can also be reordered as well. Keep in mind, when we initialize (i.e.
combined declaration and assignment in one statement) variables, that entire
statement itself may be reordered. Be wary of what code you execute at the top
level:
.. code-block:: nim
{.reorder: on.}
proc a() =
echo(foo)
var foo = 5
a() # outputs: "5"
The values of expressions involving `declared` are decided *before* the code
reordering process, and not after. As an example, the output of this code is
the same as it would be with code reordering disabled.
.. code-block:: nim
{.reorder: on.}
proc x() =
echo(declared(foo))
var foo = 4
x() # "false"
It is important to note that reordering *only* works for symbols at top level
scope. Therefore, the following will *fail to compile:*
.. code-block:: nim
{.reorder: on.}
proc a() =
b()
proc b() =
echo("Hello!")
a()
pragma pragma
-------------