'bind' as a declarative statement
This commit is contained in:
parent
c138cc36b4
commit
51e01879ba
18 changed files with 204 additions and 93 deletions
|
|
@ -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 ('.}' | '}')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
-------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue