documented the `noforward` pragma
This commit is contained in:
parent
14b5d5f262
commit
1d29d24465
4 changed files with 60 additions and 2 deletions
|
|
@ -914,12 +914,13 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
if sfNoForward in c.module.flags and
|
if sfNoForward in c.module.flags and
|
||||||
sfSystemModule notin c.module.flags:
|
sfSystemModule notin c.module.flags:
|
||||||
addInterfaceOverloadableSymAt(c, c.currentScope, s)
|
addInterfaceOverloadableSymAt(c, c.currentScope, s)
|
||||||
|
s.flags.incl sfForward
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
s = n[namePos].sym
|
s = n[namePos].sym
|
||||||
typeIsDetermined = s.typ == nil
|
typeIsDetermined = s.typ == nil
|
||||||
if typeIsDetermined: assert phase == stepCompileBody
|
# if typeIsDetermined: assert phase == stepCompileBody
|
||||||
else: assert phase == stepDetermineType
|
# else: assert phase == stepDetermineType
|
||||||
# before compiling the proc body, set as current the scope
|
# before compiling the proc body, set as current the scope
|
||||||
# where the proc was declared
|
# where the proc was declared
|
||||||
let oldScope = c.currentScope
|
let oldScope = c.currentScope
|
||||||
|
|
|
||||||
|
|
@ -4648,6 +4648,51 @@ Example:
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.}
|
||||||
|
|
||||||
|
NoForward pragma
|
||||||
|
----------------
|
||||||
|
The `noforward`:idx pragma can be used to turn on and off a special compilation
|
||||||
|
mode that to large extent eliminates the need for forward declarations. In this
|
||||||
|
mode, the proc 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, whoose 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 expresions 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
|
||||||
|
``nimrod check`` provides this option as well.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block: nimrod
|
||||||
|
|
||||||
|
{. noforward: on .}
|
||||||
|
|
||||||
|
proc foo(x: int) =
|
||||||
|
bar x
|
||||||
|
|
||||||
|
proc bar(x: int) =
|
||||||
|
echo x
|
||||||
|
|
||||||
|
foo(10)
|
||||||
|
|
||||||
Pragma pragma
|
Pragma pragma
|
||||||
-------------
|
-------------
|
||||||
|
|
|
||||||
10
tests/compile/tnoforward.nim
Normal file
10
tests/compile/tnoforward.nim
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{. noforward: on .}
|
||||||
|
|
||||||
|
proc foo(x: int) =
|
||||||
|
bar x
|
||||||
|
|
||||||
|
proc bar(x: int) =
|
||||||
|
echo x
|
||||||
|
|
||||||
|
foo(10)
|
||||||
|
|
||||||
|
|
@ -56,6 +56,8 @@ Compiler Additions
|
||||||
to be turned on explicitly via ``--warning[ShadowIdent]:on``.
|
to be turned on explicitly via ``--warning[ShadowIdent]:on``.
|
||||||
- The compiler now supports almost every pragma in a ``push`` pragma.
|
- The compiler now supports almost every pragma in a ``push`` pragma.
|
||||||
- Generic converters have been implemented.
|
- Generic converters have been implemented.
|
||||||
|
- Added a ``noforward`` pragma enabling a special compilation mode that largely
|
||||||
|
eliminates the need for forward declarations.
|
||||||
|
|
||||||
|
|
||||||
Language Additions
|
Language Additions
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue