diff options
-rw-r--r-- | compiler/semstmts.nim | 5 | ||||
-rw-r--r-- | doc/manual.txt | 45 | ||||
-rw-r--r-- | tests/compile/tnoforward.nim | 10 | ||||
-rw-r--r-- | web/news.txt | 2 |
4 files changed, 60 insertions, 2 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 3acd00065..efe5c9217 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -914,12 +914,13 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if sfNoForward in c.module.flags and sfSystemModule notin c.module.flags: addInterfaceOverloadableSymAt(c, c.currentScope, s) + s.flags.incl sfForward return else: s = n[namePos].sym typeIsDetermined = s.typ == nil - if typeIsDetermined: assert phase == stepCompileBody - else: assert phase == stepDetermineType + # if typeIsDetermined: assert phase == stepCompileBody + # else: assert phase == stepDetermineType # before compiling the proc body, set as current the scope # where the proc was declared let oldScope = c.currentScope diff --git a/doc/manual.txt b/doc/manual.txt index 22aa22266..bc9b81bad 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -4648,6 +4648,51 @@ Example: .. code-block:: nimrod {.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 ------------- diff --git a/tests/compile/tnoforward.nim b/tests/compile/tnoforward.nim new file mode 100644 index 000000000..0359ff348 --- /dev/null +++ b/tests/compile/tnoforward.nim @@ -0,0 +1,10 @@ +{. noforward: on .} + +proc foo(x: int) = + bar x + +proc bar(x: int) = + echo x + +foo(10) + diff --git a/web/news.txt b/web/news.txt index ef4255402..7c46e550a 100644 --- a/web/news.txt +++ b/web/news.txt @@ -56,6 +56,8 @@ Compiler Additions to be turned on explicitly via ``--warning[ShadowIdent]:on``. - The compiler now supports almost every pragma in a ``push`` pragma. - Generic converters have been implemented. +- Added a ``noforward`` pragma enabling a special compilation mode that largely + eliminates the need for forward declarations. Language Additions |