diff options
author | Araq <rumpf_a@web.de> | 2011-07-31 22:39:17 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-07-31 22:39:17 +0200 |
commit | 3e806a374a1b42246e947965677c4a1520f3db57 (patch) | |
tree | bf2de9968a3288e5f6418eec65e4dbd6587bc07e | |
parent | 4f7fa0591112e70f7eacef051a215e3420f78da8 (diff) | |
download | Nim-3e806a374a1b42246e947965677c4a1520f3db57.tar.gz |
'var T' for iterators
-rwxr-xr-x | compiler/ccgexprs.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 9 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 25 | ||||
-rwxr-xr-x | compiler/transf.nim | 10 | ||||
-rwxr-xr-x | examples/lazarus/backend.nim | 5 | ||||
-rw-r--r-- | tests/accept/run/tmoditer.nim | 29 | ||||
-rwxr-xr-x | todo.txt | 10 |
7 files changed, 79 insertions, 11 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 1e30df7ad..f6680d252 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -207,7 +207,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = # This function replaces all other methods for generating # the assignment operation in C. 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)]) return var ty = skipTypes(dest.t, abstractVarRange) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d403aeef1..3bbc0c71f 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -36,6 +36,15 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = GlobalError(n.info, errExprXHasNoType, 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 = result = symChoice(c, n, s) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 52fc2ea31..1c6c90c84 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -167,6 +167,26 @@ proc SemReturn(c: PContext, n: PNode): PNode = if n[0][1].kind == nkSym and n[0][1].sym.kind == skResult: 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 = result = n checkSonsLen(n, 1) @@ -178,7 +198,8 @@ proc SemYield(c: PContext, n: PNode): PNode = if restype != nil: n.sons[0] = fitNode(c, restype, n.sons[0]) if n.sons[0].typ == nil: InternalError(n.info, "semYield") - else: + SemYieldVarResult(c, n, restype) + else: localError(n.info, errCannotReturnExpr) proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode = @@ -361,7 +382,7 @@ proc semFor(c: PContext, n: PNode): PNode = checkMinSonsLen(n, 3) var length = sonsLen(n) 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] if call.kind != nkCall or call.sons[0].kind != nkSym or call.sons[0].sym.kind != skIterator: diff --git a/compiler/transf.nim b/compiler/transf.nim index 78814edd8..caa73da25 100755 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -502,9 +502,15 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = addVar(v, newSymNode(temp)) add(result, newAsgnStmt(c, newSymNode(temp), arg.ptransNode)) IdNodeTablePut(newC.mapping, formal, newSymNode(temp)) - of paVarAsgn: + of paVarAsgn: 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] pushInfoContext(n.info) inc(c.inlining) diff --git a/examples/lazarus/backend.nim b/examples/lazarus/backend.nim new file mode 100755 index 000000000..64f0c5bf7 --- /dev/null +++ b/examples/lazarus/backend.nim @@ -0,0 +1,5 @@ +# Backend for the Lazarus GUI + +proc myAdd*(x, y: int): int {.cdecl, exportc.} = + result = x + y + diff --git a/tests/accept/run/tmoditer.nim b/tests/accept/run/tmoditer.nim new file mode 100644 index 000000000..1e6be37e4 --- /dev/null +++ b/tests/accept/run/tmoditer.nim @@ -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 "" + diff --git a/todo.txt b/todo.txt index 2c5f15b54..e781e772a 100755 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,10 @@ Version 0.8.14 ============== +- fix serious bug that keeps teventemitter from compiling - ``var T`` as a return type: - * for iterators * add ``modGet`` for generics * documentation - * provide ``mod`` as an alternative syntax for ``var`` - optional indentation for 'case' statement - make threadvar efficient again on linux after testing - test the sort implementation again @@ -19,8 +18,7 @@ version 0.9.0 - add --deadlock_prevention:on|off switch? timeout for locks? - warning for implicit openArray -> varargs convention - implement explicit varargs -- tests: run modules that contain "#RUN_ME", compile the other - modules; run the GC tests +- tests: run the GC tests - change overloading resolution - implement closures; implement proper coroutines @@ -40,8 +38,6 @@ version 0.9.XX - implicit ref/ptr->var conversion; the compiler may store an object implicitly on the heap for write barrier efficiency; better: 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 is hard because of partial evaluation --> symbol files will fix this as a side effect @@ -81,6 +77,8 @@ Low priority - find a way for easy constructors and destructors; (destructors are much more important than constructors) - code generated for type information is wasteful +- resizing of strings/sequences could take into account the memory that + is allocated Version 2 |