diff options
author | Araq <rumpf_a@web.de> | 2014-06-28 01:03:07 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-06-28 01:03:07 +0200 |
commit | 59f61bae05047a0f110ca419272dbe3d53a412a6 (patch) | |
tree | 515365fc9af2d973533fb292ca7b0749f5f1830d | |
parent | 79586487be202ffb7499a8917ac33024ce9c3a16 (diff) | |
download | Nim-59f61bae05047a0f110ca419272dbe3d53a412a6.tar.gz |
new jester compiles
-rw-r--r-- | compiler/lambdalifting.nim | 24 | ||||
-rw-r--r-- | compiler/lowerings.nim | 10 | ||||
-rw-r--r-- | tests/closure/tjester.nim | 32 |
3 files changed, 58 insertions, 8 deletions
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 402ad7d3d..ee380b305 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -240,9 +240,6 @@ proc newEnv(o: POuterContext; up: PEnv, n: PNode; owner: PSym): PEnv = result.next = o.head o.head = result if owner.kind != skModule and (up == nil or up.fn != owner): - if owner.ast == nil: - debug owner - echo owner.name.s let param = getEnvParam(owner) if param != nil: result.obj = param.typ.sons[0] @@ -808,8 +805,9 @@ proc transformOuterProc(o: POuterContext, n: PNode; it: TIter): PNode = if it.fn.kind == skClosureIterator and interestingIterVar(local) and it.fn == local.owner: # every local goes through the closure: - if not containsOrIncl(o.capturedVars, local.id): - addField(it.obj, local) + #if not containsOrIncl(o.capturedVars, local.id): + # addField(it.obj, local) + addUniqueField(it.obj, local) return indirectAccess(newSymNode(it.closureParam), local, n.info) var closure = PEnv(idTableGet(o.lambdasToEnv, local)) @@ -853,10 +851,18 @@ proc transformOuterProc(o: POuterContext, n: PNode; it: TIter): PNode = of nkLambdaKinds, nkIteratorDef: if n.typ != nil: result = transformOuterProc(o, n.sons[namePos], it) - of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, - nkClosure: + of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef: # don't recurse here: discard + of nkClosure: + if n.sons[0].kind == nkSym: + var local = n.sons[0].sym + if isInnerProc(local, o.fn) and o.processed.contains(local.id): + o.processed.excl(local.id) + let body = local.getBody + let newBody = transformOuterProcBody(o, body, initIter(local)) + if newBody != nil: + local.ast.sons[bodyPos] = newBody of nkHiddenStdConv, nkHiddenSubConv, nkConv: let x = transformOuterProc(o, n.sons[1], it) if x != nil: n.sons[1] = x @@ -878,6 +884,8 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode = # ignore forward declaration: result = body else: + #if fn.name.s == "cbOuter": + # echo rendertree(fn.ast, {renderIds}) var o = newOuterContext(fn) let ex = closureCreationPoint(body) let env = newEnv(o, nil, ex, fn) @@ -890,7 +898,7 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode = discard transformOuterProcBody(o, body, initIter(fn)) result = ex finishEnvironments(o) - #if fn.name.s == "cbOuter" or fn.name.s == "factory2": + #if fn.name.s == "cbOuter": # echo rendertree(result, {renderIds}) proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode = diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 74690ac0c..5b61a9cae 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -90,6 +90,16 @@ proc addField*(obj: PType; s: PSym) = field.position = sonsLen(obj.n) addSon(obj.n, newSymNode(field)) +proc addUniqueField*(obj: PType; s: PSym) = + let fieldName = getIdent(s.name.s & $s.id) + if lookupInRecord(obj.n, fieldName) == nil: + var field = newSym(skField, fieldName, s.owner, s.info) + let t = skipIntLit(s.typ) + field.typ = t + assert t.kind != tyStmt + field.position = sonsLen(obj.n) + addSon(obj.n, newSymNode(field)) + proc newDotExpr(obj, b: PSym): PNode = result = newNodeI(nkDotExpr, obj.info) let field = getSymFromList(obj.typ.n, getIdent(b.name.s & $b.id)) diff --git a/tests/closure/tjester.nim b/tests/closure/tjester.nim new file mode 100644 index 000000000..48e5186f0 --- /dev/null +++ b/tests/closure/tjester.nim @@ -0,0 +1,32 @@ +discard """ + output: '''baro0''' +""" + +type + Future[T] = ref object + data: T + callback: proc () {.closure.} + +proc cbOuter(response: string) {.closure, discardable.} = + iterator cbIter(): Future[int] {.closure.} = + for i in 0..7: + proc foo(): int = + iterator fooIter(): Future[int] {.closure.} = + echo response, i + yield Future[int](data: 17) + var iterVar = fooIter + iterVar().data + yield Future[int](data: foo()) + + var iterVar2 = cbIter + proc cb2() {.closure.} = + try: + if not finished(iterVar2): + let next = iterVar2() + if next != nil: + next.callback = cb2 + except: + echo "WTF" + cb2() + +cbOuter "baro" |