'var T' for iterators
This commit is contained in:
parent
4f7fa05911
commit
3e806a374a
7 changed files with 79 additions and 11 deletions
|
|
@ -207,7 +207,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
# This function replaces all other methods for generating
|
# This function replaces all other methods for generating
|
||||||
# the assignment operation in C.
|
# the assignment operation in C.
|
||||||
if src.t != nil and src.t.kind == tyPtr:
|
if src.t != nil and src.t.kind == tyPtr:
|
||||||
# little HACK to suppor the new 'var T' as return type:
|
# little HACK to support the new 'var T' as return type:
|
||||||
appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
return
|
return
|
||||||
var ty = skipTypes(dest.t, abstractVarRange)
|
var ty = skipTypes(dest.t, abstractVarRange)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,15 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
GlobalError(n.info, errExprXHasNoType,
|
GlobalError(n.info, errExprXHasNoType,
|
||||||
renderTree(result, {renderNoComments}))
|
renderTree(result, {renderNoComments}))
|
||||||
|
|
||||||
|
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
|
result = semExpr(c, n, flags)
|
||||||
|
if result.kind == nkEmpty:
|
||||||
|
# do not produce another redundant error message:
|
||||||
|
raiseRecoverableError()
|
||||||
|
if result.typ == nil:
|
||||||
|
GlobalError(n.info, errExprXHasNoType,
|
||||||
|
renderTree(result, {renderNoComments}))
|
||||||
|
|
||||||
proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
result = symChoice(c, n, s)
|
result = symChoice(c, n, s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,26 @@ proc SemReturn(c: PContext, n: PNode): PNode =
|
||||||
if n[0][1].kind == nkSym and n[0][1].sym.kind == skResult:
|
if n[0][1].kind == nkSym and n[0][1].sym.kind == skResult:
|
||||||
n.sons[0] = ast.emptyNode
|
n.sons[0] = ast.emptyNode
|
||||||
|
|
||||||
|
proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
||||||
|
var t = skipTypes(restype, {tyGenericInst})
|
||||||
|
case t.kind
|
||||||
|
of tyVar:
|
||||||
|
n.sons[0] = takeImplicitAddr(c, n.sons[0])
|
||||||
|
of tyTuple:
|
||||||
|
for i in 0.. <t.sonsLen:
|
||||||
|
var e = skipTypes(t.sons[i], {tyGenericInst})
|
||||||
|
if e.kind == tyVar:
|
||||||
|
if n.sons[0].kind == nkPar:
|
||||||
|
n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i])
|
||||||
|
elif n.sons[0].kind == nkHiddenSubConv and
|
||||||
|
n.sons[0].sons[1].kind == nkPar:
|
||||||
|
var a = n.sons[0].sons[1]
|
||||||
|
a.sons[i] = takeImplicitAddr(c, a.sons[i])
|
||||||
|
else:
|
||||||
|
debug n.sons[0]
|
||||||
|
localError(n.sons[0].info, errXExpected, "tuple constructor")
|
||||||
|
else: nil
|
||||||
|
|
||||||
proc SemYield(c: PContext, n: PNode): PNode =
|
proc SemYield(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkSonsLen(n, 1)
|
checkSonsLen(n, 1)
|
||||||
|
|
@ -178,6 +198,7 @@ proc SemYield(c: PContext, n: PNode): PNode =
|
||||||
if restype != nil:
|
if restype != nil:
|
||||||
n.sons[0] = fitNode(c, restype, n.sons[0])
|
n.sons[0] = fitNode(c, restype, n.sons[0])
|
||||||
if n.sons[0].typ == nil: InternalError(n.info, "semYield")
|
if n.sons[0].typ == nil: InternalError(n.info, "semYield")
|
||||||
|
SemYieldVarResult(c, n, restype)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errCannotReturnExpr)
|
localError(n.info, errCannotReturnExpr)
|
||||||
|
|
||||||
|
|
@ -361,7 +382,7 @@ proc semFor(c: PContext, n: PNode): PNode =
|
||||||
checkMinSonsLen(n, 3)
|
checkMinSonsLen(n, 3)
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
openScope(c.tab)
|
openScope(c.tab)
|
||||||
n.sons[length-2] = semExprWithType(c, n.sons[length-2], {efWantIterator})
|
n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
|
||||||
var call = n.sons[length-2]
|
var call = n.sons[length-2]
|
||||||
if call.kind != nkCall or call.sons[0].kind != nkSym or
|
if call.kind != nkCall or call.sons[0].kind != nkSym or
|
||||||
call.sons[0].sym.kind != skIterator:
|
call.sons[0].sym.kind != skIterator:
|
||||||
|
|
|
||||||
|
|
@ -504,7 +504,13 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||||
IdNodeTablePut(newC.mapping, formal, newSymNode(temp))
|
IdNodeTablePut(newC.mapping, formal, newSymNode(temp))
|
||||||
of paVarAsgn:
|
of paVarAsgn:
|
||||||
assert(skipTypes(formal.typ, abstractInst).kind == tyVar)
|
assert(skipTypes(formal.typ, abstractInst).kind == tyVar)
|
||||||
InternalError(arg.info, "not implemented: pass to var parameter")
|
# XXX why is this even necessary?
|
||||||
|
var b = newNodeIT(nkHiddenAddr, arg.info, formal.typ)
|
||||||
|
b.add(arg)
|
||||||
|
arg = b
|
||||||
|
IdNodeTablePut(newC.mapping, formal, arg)
|
||||||
|
# XXX BUG still not correct if the arg has a side effect!
|
||||||
|
#InternalError(arg.info, "not implemented: pass to var parameter")
|
||||||
var body = newC.owner.ast.sons[codePos]
|
var body = newC.owner.ast.sons[codePos]
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(n.info)
|
||||||
inc(c.inlining)
|
inc(c.inlining)
|
||||||
|
|
|
||||||
5
examples/lazarus/backend.nim
Executable file
5
examples/lazarus/backend.nim
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Backend for the Lazarus GUI
|
||||||
|
|
||||||
|
proc myAdd*(x, y: int): int {.cdecl, exportc.} =
|
||||||
|
result = x + y
|
||||||
|
|
||||||
29
tests/accept/run/tmoditer.nim
Normal file
29
tests/accept/run/tmoditer.nim
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
discard """
|
||||||
|
output: "XXXXX01234"
|
||||||
|
"""
|
||||||
|
|
||||||
|
iterator modPairs(a: var array[0..4,string]): tuple[key: int, val: var string] =
|
||||||
|
for i in 0..a.high:
|
||||||
|
yield (i, a[i])
|
||||||
|
|
||||||
|
iterator modItems*[T](a: var array[0..4,T]): var T =
|
||||||
|
for i in 0..a.high:
|
||||||
|
yield a[i]
|
||||||
|
|
||||||
|
var
|
||||||
|
arr = ["a", "b", "c", "d", "e"]
|
||||||
|
|
||||||
|
for a in modItems(arr):
|
||||||
|
a = "X"
|
||||||
|
|
||||||
|
for a in items(arr):
|
||||||
|
stdout.write(a)
|
||||||
|
|
||||||
|
for i, a in modPairs(arr):
|
||||||
|
a = $i
|
||||||
|
|
||||||
|
for a in items(arr):
|
||||||
|
stdout.write(a)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
10
todo.txt
10
todo.txt
|
|
@ -1,11 +1,10 @@
|
||||||
Version 0.8.14
|
Version 0.8.14
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
- fix serious bug that keeps teventemitter from compiling
|
||||||
- ``var T`` as a return type:
|
- ``var T`` as a return type:
|
||||||
* for iterators
|
|
||||||
* add ``modGet`` for generics
|
* add ``modGet`` for generics
|
||||||
* documentation
|
* documentation
|
||||||
* provide ``mod`` as an alternative syntax for ``var``
|
|
||||||
- optional indentation for 'case' statement
|
- optional indentation for 'case' statement
|
||||||
- make threadvar efficient again on linux after testing
|
- make threadvar efficient again on linux after testing
|
||||||
- test the sort implementation again
|
- test the sort implementation again
|
||||||
|
|
@ -19,8 +18,7 @@ version 0.9.0
|
||||||
- add --deadlock_prevention:on|off switch? timeout for locks?
|
- add --deadlock_prevention:on|off switch? timeout for locks?
|
||||||
- warning for implicit openArray -> varargs convention
|
- warning for implicit openArray -> varargs convention
|
||||||
- implement explicit varargs
|
- implement explicit varargs
|
||||||
- tests: run modules that contain "#RUN_ME", compile the other
|
- tests: run the GC tests
|
||||||
modules; run the GC tests
|
|
||||||
- change overloading resolution
|
- change overloading resolution
|
||||||
- implement closures; implement proper coroutines
|
- implement closures; implement proper coroutines
|
||||||
|
|
||||||
|
|
@ -40,8 +38,6 @@ version 0.9.XX
|
||||||
- implicit ref/ptr->var conversion; the compiler may store an object
|
- implicit ref/ptr->var conversion; the compiler may store an object
|
||||||
implicitly on the heap for write barrier efficiency; better:
|
implicitly on the heap for write barrier efficiency; better:
|
||||||
proc specialization in the code gen
|
proc specialization in the code gen
|
||||||
- resizing of strings/sequences could take into account the memory that
|
|
||||||
is allocated
|
|
||||||
- find a way to reintroduce the cleanup() pass for C code generation: this
|
- find a way to reintroduce the cleanup() pass for C code generation: this
|
||||||
is hard because of partial evaluation --> symbol files will fix this as
|
is hard because of partial evaluation --> symbol files will fix this as
|
||||||
a side effect
|
a side effect
|
||||||
|
|
@ -81,6 +77,8 @@ Low priority
|
||||||
- find a way for easy constructors and destructors; (destructors are much more
|
- find a way for easy constructors and destructors; (destructors are much more
|
||||||
important than constructors)
|
important than constructors)
|
||||||
- code generated for type information is wasteful
|
- code generated for type information is wasteful
|
||||||
|
- resizing of strings/sequences could take into account the memory that
|
||||||
|
is allocated
|
||||||
|
|
||||||
|
|
||||||
Version 2
|
Version 2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue