new jester compiles
This commit is contained in:
parent
79586487be
commit
59f61bae05
3 changed files with 58 additions and 8 deletions
|
|
@ -240,9 +240,6 @@ proc newEnv(o: POuterContext; up: PEnv, n: PNode; owner: PSym): PEnv =
|
||||||
result.next = o.head
|
result.next = o.head
|
||||||
o.head = result
|
o.head = result
|
||||||
if owner.kind != skModule and (up == nil or up.fn != owner):
|
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)
|
let param = getEnvParam(owner)
|
||||||
if param != nil:
|
if param != nil:
|
||||||
result.obj = param.typ.sons[0]
|
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
|
if it.fn.kind == skClosureIterator and interestingIterVar(local) and
|
||||||
it.fn == local.owner:
|
it.fn == local.owner:
|
||||||
# every local goes through the closure:
|
# every local goes through the closure:
|
||||||
if not containsOrIncl(o.capturedVars, local.id):
|
#if not containsOrIncl(o.capturedVars, local.id):
|
||||||
addField(it.obj, local)
|
# addField(it.obj, local)
|
||||||
|
addUniqueField(it.obj, local)
|
||||||
return indirectAccess(newSymNode(it.closureParam), local, n.info)
|
return indirectAccess(newSymNode(it.closureParam), local, n.info)
|
||||||
|
|
||||||
var closure = PEnv(idTableGet(o.lambdasToEnv, local))
|
var closure = PEnv(idTableGet(o.lambdasToEnv, local))
|
||||||
|
|
@ -853,10 +851,18 @@ proc transformOuterProc(o: POuterContext, n: PNode; it: TIter): PNode =
|
||||||
of nkLambdaKinds, nkIteratorDef:
|
of nkLambdaKinds, nkIteratorDef:
|
||||||
if n.typ != nil:
|
if n.typ != nil:
|
||||||
result = transformOuterProc(o, n.sons[namePos], it)
|
result = transformOuterProc(o, n.sons[namePos], it)
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
|
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef:
|
||||||
nkClosure:
|
|
||||||
# don't recurse here:
|
# don't recurse here:
|
||||||
discard
|
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:
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||||
let x = transformOuterProc(o, n.sons[1], it)
|
let x = transformOuterProc(o, n.sons[1], it)
|
||||||
if x != nil: n.sons[1] = x
|
if x != nil: n.sons[1] = x
|
||||||
|
|
@ -878,6 +884,8 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode =
|
||||||
# ignore forward declaration:
|
# ignore forward declaration:
|
||||||
result = body
|
result = body
|
||||||
else:
|
else:
|
||||||
|
#if fn.name.s == "cbOuter":
|
||||||
|
# echo rendertree(fn.ast, {renderIds})
|
||||||
var o = newOuterContext(fn)
|
var o = newOuterContext(fn)
|
||||||
let ex = closureCreationPoint(body)
|
let ex = closureCreationPoint(body)
|
||||||
let env = newEnv(o, nil, ex, fn)
|
let env = newEnv(o, nil, ex, fn)
|
||||||
|
|
@ -890,7 +898,7 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode =
|
||||||
discard transformOuterProcBody(o, body, initIter(fn))
|
discard transformOuterProcBody(o, body, initIter(fn))
|
||||||
result = ex
|
result = ex
|
||||||
finishEnvironments(o)
|
finishEnvironments(o)
|
||||||
#if fn.name.s == "cbOuter" or fn.name.s == "factory2":
|
#if fn.name.s == "cbOuter":
|
||||||
# echo rendertree(result, {renderIds})
|
# echo rendertree(result, {renderIds})
|
||||||
|
|
||||||
proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode =
|
proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,16 @@ proc addField*(obj: PType; s: PSym) =
|
||||||
field.position = sonsLen(obj.n)
|
field.position = sonsLen(obj.n)
|
||||||
addSon(obj.n, newSymNode(field))
|
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 =
|
proc newDotExpr(obj, b: PSym): PNode =
|
||||||
result = newNodeI(nkDotExpr, obj.info)
|
result = newNodeI(nkDotExpr, obj.info)
|
||||||
let field = getSymFromList(obj.typ.n, getIdent(b.name.s & $b.id))
|
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"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue