mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 22:33:49 +00:00
new jester compiles
This commit is contained in:
@@ -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 =
|
||||
|
||||
@@ -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))
|
||||
|
||||
32
tests/closure/tjester.nim
Normal file
32
tests/closure/tjester.nim
Normal file
@@ -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"
|
||||
Reference in New Issue
Block a user