implicit invokation of items/pairs iterators
This commit is contained in:
parent
7f3b3298b4
commit
2ae78c0cfb
6 changed files with 72 additions and 30 deletions
|
|
@ -178,7 +178,8 @@ proc semCast(c: PContext, n: PNode): PNode =
|
||||||
addSon(result, copyTree(n.sons[0]))
|
addSon(result, copyTree(n.sons[0]))
|
||||||
addSon(result, semExprWithType(c, n.sons[1]))
|
addSon(result, semExprWithType(c, n.sons[1]))
|
||||||
if not isCastable(result.typ, result.sons[1].Typ):
|
if not isCastable(result.typ, result.sons[1].Typ):
|
||||||
GlobalError(result.info, errExprCannotBeCastedToX, typeToString(result.Typ))
|
GlobalError(result.info, errExprCannotBeCastedToX,
|
||||||
|
typeToString(result.Typ))
|
||||||
|
|
||||||
proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -398,19 +398,9 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
b.add(ast.emptyNode)
|
b.add(ast.emptyNode)
|
||||||
stmts.add(b)
|
stmts.add(b)
|
||||||
|
|
||||||
proc semFor(c: PContext, n: PNode): PNode =
|
proc semForVars(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkMinSonsLen(n, 3)
|
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
openScope(c.tab)
|
|
||||||
n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
|
|
||||||
var call = n.sons[length-2]
|
|
||||||
if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
|
|
||||||
call.sons[0].sym.kind != skIterator:
|
|
||||||
GlobalError(n.sons[length - 2].info, errIteratorExpected)
|
|
||||||
elif call.sons[0].sym.magic != mNone:
|
|
||||||
result = semForFields(c, n, call.sons[0].sym.magic)
|
|
||||||
else:
|
|
||||||
var iter = skipTypes(n.sons[length-2].typ, {tyGenericInst})
|
var iter = skipTypes(n.sons[length-2].typ, {tyGenericInst})
|
||||||
# length == 3 means that there is one for loop variable
|
# length == 3 means that there is one for loop variable
|
||||||
# and thus no tuple unpacking:
|
# and thus no tuple unpacking:
|
||||||
|
|
@ -434,6 +424,34 @@ proc semFor(c: PContext, n: PNode): PNode =
|
||||||
Inc(c.p.nestedLoopCounter)
|
Inc(c.p.nestedLoopCounter)
|
||||||
n.sons[length-1] = SemStmt(c, n.sons[length-1])
|
n.sons[length-1] = SemStmt(c, n.sons[length-1])
|
||||||
Dec(c.p.nestedLoopCounter)
|
Dec(c.p.nestedLoopCounter)
|
||||||
|
|
||||||
|
proc implicitIterator(c: PContext, it: string, arg: PNode): PNode =
|
||||||
|
result = newNodeI(nkCall, arg.info)
|
||||||
|
result.add(newIdentNode(it.getIdent, arg.info))
|
||||||
|
result.add(arg)
|
||||||
|
result = semExprNoDeref(c, result, {efWantIterator})
|
||||||
|
|
||||||
|
proc semFor(c: PContext, n: PNode): PNode =
|
||||||
|
result = n
|
||||||
|
checkMinSonsLen(n, 3)
|
||||||
|
var length = sonsLen(n)
|
||||||
|
openScope(c.tab)
|
||||||
|
n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
|
||||||
|
var call = n.sons[length-2]
|
||||||
|
if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
|
||||||
|
call.sons[0].sym.kind != skIterator:
|
||||||
|
if length == 3:
|
||||||
|
n.sons[length-2] = implicitIterator(c, "items", n.sons[length-2])
|
||||||
|
result = semForVars(c, n)
|
||||||
|
elif length == 4:
|
||||||
|
n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2])
|
||||||
|
result = semForVars(c, n)
|
||||||
|
else:
|
||||||
|
GlobalError(n.sons[length - 2].info, errIteratorExpected)
|
||||||
|
elif call.sons[0].sym.magic != mNone:
|
||||||
|
result = semForFields(c, n, call.sons[0].sym.magic)
|
||||||
|
else:
|
||||||
|
result = semForVars(c, n)
|
||||||
closeScope(c.tab)
|
closeScope(c.tab)
|
||||||
|
|
||||||
proc semRaise(c: PContext, n: PNode): PNode =
|
proc semRaise(c: PContext, n: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -2328,7 +2328,7 @@ Iterators and the for statement
|
||||||
|
|
||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
forStmt ::= 'for' symbol (comma symbol)* [comma] 'in' expr ['..' expr] ':' stmt
|
forStmt ::= 'for' symbol (comma symbol)* [comma] 'in' expr ':' stmt
|
||||||
|
|
||||||
param ::= symbol (comma symbol)* [comma] ':' typeDesc
|
param ::= symbol (comma symbol)* [comma] ':' typeDesc
|
||||||
paramList ::= ['(' [param (comma param)* [comma]] ')'] [':' typeDesc]
|
paramList ::= ['(' [param (comma param)* [comma]] ')'] [':' typeDesc]
|
||||||
|
|
@ -2386,6 +2386,24 @@ as there are components in the tuple. The i'th iteration variable's type is
|
||||||
the type of the i'th component.
|
the type of the i'th component.
|
||||||
|
|
||||||
|
|
||||||
|
Implict items/pairs invokations
|
||||||
|
+++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
If the for loop expression ``e`` does not denote an iterator and the for loop
|
||||||
|
has exactly 1 variable, the for loop expression is rewritten to ``items(e)``;
|
||||||
|
ie. an ``items`` iterator is implicitely invoked:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
for x in [1,2,3]: echo x
|
||||||
|
|
||||||
|
If the for loop has exactly 2 variables, a ``pairs`` iterator is implicitely
|
||||||
|
invoked.
|
||||||
|
|
||||||
|
Symbol lookup of the identifiers ``items``/``pairs`` is performed after
|
||||||
|
the rewriting step, so that all overloadings of ``items``/``pairs`` are taken
|
||||||
|
into account.
|
||||||
|
|
||||||
|
|
||||||
Type sections
|
Type sections
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
@ -3322,6 +3340,7 @@ strings automatically:
|
||||||
Dynlib pragma for import
|
Dynlib pragma for import
|
||||||
------------------------
|
------------------------
|
||||||
With the `dynlib`:idx: pragma a procedure can be imported from
|
With the `dynlib`:idx: pragma a procedure can be imported from
|
||||||
|
|
||||||
a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). The
|
a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). The
|
||||||
non-optional argument has to be the name of the dynamic library:
|
non-optional argument has to be the name of the dynamic library:
|
||||||
|
|
||||||
|
|
|
||||||
4
tests/compile/timplicititems.nim
Normal file
4
tests/compile/timplicititems.nim
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
for x in [1, 2, 3, 4]:
|
||||||
|
echo x
|
||||||
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -1,10 +1,8 @@
|
||||||
version 0.8.14
|
version 0.8.14
|
||||||
==============
|
==============
|
||||||
|
|
||||||
- fix remaining generics bugs
|
- fix allocator bug
|
||||||
- fix line info in assertions
|
- fix line info in assertions
|
||||||
- implicit invokation of `items`/`pairs` seems nice; ensure items(23) does
|
|
||||||
not compile though
|
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ Version 0.8.14 has been released! Get it `here <download.html>`_.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
--------
|
--------
|
||||||
|
|
||||||
- Boehm GC now works with ``--threads:on``.
|
|
||||||
- Fixed a serious memory corruption concerning message passing.
|
- Fixed a serious memory corruption concerning message passing.
|
||||||
- Fixed a serious bug concerning different instantiations of a generic proc.
|
- Fixed a serious bug concerning different instantiations of a generic proc.
|
||||||
- Fixed a newly introduced bug where a wrong ``EIO`` exception was raised for
|
- Fixed a newly introduced bug where a wrong ``EIO`` exception was raised for
|
||||||
|
|
@ -20,6 +19,7 @@ Bugfixes
|
||||||
- Some more bugfixes for macros and compile-time evaluation.
|
- Some more bugfixes for macros and compile-time evaluation.
|
||||||
- The GC now takes into account interior pointers on the stack which may be
|
- The GC now takes into account interior pointers on the stack which may be
|
||||||
introduced by aggressive C optimizers.
|
introduced by aggressive C optimizers.
|
||||||
|
- Lots of other bugfixes: Too many to list them all.
|
||||||
|
|
||||||
|
|
||||||
Changes affecting backwards compatibility
|
Changes affecting backwards compatibility
|
||||||
|
|
@ -77,6 +77,8 @@ Language Additions
|
||||||
- ``bind`` (used for symbol binding in templates and generics) is now a
|
- ``bind`` (used for symbol binding in templates and generics) is now a
|
||||||
declarative statement.
|
declarative statement.
|
||||||
- Nimrod now supports single assignment variables via the ``let`` statement.
|
- Nimrod now supports single assignment variables via the ``let`` statement.
|
||||||
|
- Iterators named ``items`` and ``pairs`` are implicitly invoked when
|
||||||
|
an explicit iterator is missing.
|
||||||
- The slice assignment ``a[i..j] = b`` where ``a`` is a sequence or string
|
- The slice assignment ``a[i..j] = b`` where ``a`` is a sequence or string
|
||||||
now supports *splicing*.
|
now supports *splicing*.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue