'bind' as a declarative statement

This commit is contained in:
Araq 2011-10-10 02:04:15 +02:00
commit 51e01879ba
18 changed files with 204 additions and 93 deletions

View file

@ -33,7 +33,7 @@ primaryPrefix ::= (prefixOperator | 'bind') optInd
primarySuffix ::= '.' optInd symbol [generalizedLit]
| '(' optInd namedExprList optPar ')'
| '[' optInd [indexExpr (comma indexExpr)* [comma]] optPar ']'
| '{' optInd ':' | colonExprList optPar '}'
| '{' optInd [indexExpr (comma indexExpr)* [comma]] optPar '}'
| pragma
primary ::= primaryPrefix* (symbol [generalizedLit] |
@ -98,7 +98,7 @@ complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
| blockStmt | asmStmt
| procDecl | iteratorDecl | macroDecl | templateDecl | methodDecl
| constSection | letSection | varSection
| typeSection | whenStmt
| typeSection | whenStmt | bindStmt
indPush ::= IND # and push indentation onto the stack
indPop ::= # pop indentation from the stack
@ -132,6 +132,7 @@ blockStmt ::= 'block' [symbol] ':' stmt
filename ::= symbol | STR_LIT | RSTR_LIT | TRIPLESTR_LIT
importStmt ::= 'import' filename (comma filename)*
includeStmt ::= 'include' filename (comma filename)*
bindStmt ::= 'bind' IDENT (comma IDENT)*
fromStmt ::= 'from' filename 'import' symbol (comma symbol)*
pragma ::= '{.' optInd (colonExpr [comma])* optPar ('.}' | '}')

View file

@ -2589,11 +2589,17 @@ Symbol binding within templates happens after template instantation:
echo genId() # Error: undeclared identifier: 'lastId'
Bind statement
~~~~~~~~~~~~~~
Syntax::
bindStmt ::= 'bind' IDENT (comma IDENT)*
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).
The affected identifiers are then always bound early even if the other
occurences are in no ``bind`` context:
this case, a `bind`:idx: statement can be used: It declares all identifiers
that should be bound early (i.e. when the template is parsed):
.. code-block:: nimrod
# Module A
@ -2601,7 +2607,8 @@ occurences are in no ``bind`` context:
lastId = 0
template genId*: expr =
inc(bind lastId)
bind lastId
inc(lastId)
lastId
.. code-block:: nimrod
@ -2610,14 +2617,8 @@ occurences are in no ``bind`` context:
echo genId() # Works
A ``bind`` statement can also be used in generics for the same purpose.
**Style note**: For code readability, it is the best idea to use the least
powerful programming construct that still suffices. So the "check list" is:
(1) Use an ordinary proc/iterator, if possible.
(2) Else: Use a generic proc/iterator, if possible.
(3) Else: Use a template, if possible.
(4) Else: Use a macro.
Identifier construction
~~~~~~~~~~~~~~~~~~~~~~~
@ -2740,6 +2741,14 @@ regular expressions:
return tkUnknown
**Style note**: For code readability, it is the best idea to use the least
powerful programming construct that still suffices. So the "check list" is:
(1) Use an ordinary proc/iterator, if possible.
(2) Else: Use a generic proc/iterator, if possible.
(3) Else: Use a template, if possible.
(4) Else: Use a macro.
Modules
-------