'var T' for iterators

This commit is contained in:
Araq
2011-07-31 22:39:17 +02:00
parent 4f7fa05911
commit 3e806a374a
7 changed files with 79 additions and 11 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

5
examples/lazarus/backend.nim Executable file
View File

@@ -0,0 +1,5 @@
# Backend for the Lazarus GUI
proc myAdd*(x, y: int): int {.cdecl, exportc.} =
result = x + y

View 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 ""

View File

@@ -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