async works again
This commit is contained in:
parent
813f98fb34
commit
b4c62d5fed
3 changed files with 188 additions and 20 deletions
|
|
@ -451,6 +451,8 @@ proc newEnvVar(owner: PSym; typ: PType): PNode =
|
||||||
var v = newSym(skVar, getIdent(envName), owner, owner.info)
|
var v = newSym(skVar, getIdent(envName), owner, owner.info)
|
||||||
incl(v.flags, sfShadowed)
|
incl(v.flags, sfShadowed)
|
||||||
v.typ = typ
|
v.typ = typ
|
||||||
|
result = newSymNode(v)
|
||||||
|
when false:
|
||||||
if owner.kind == skIterator and owner.typ.callConv == ccClosure:
|
if owner.kind == skIterator and owner.typ.callConv == ccClosure:
|
||||||
let it = getHiddenParam(owner)
|
let it = getHiddenParam(owner)
|
||||||
addUniqueField(it.typ.sons[0], v)
|
addUniqueField(it.typ.sons[0], v)
|
||||||
|
|
@ -460,6 +462,8 @@ proc newEnvVar(owner: PSym; typ: PType): PNode =
|
||||||
|
|
||||||
proc setupEnvVar(owner: PSym; d: DetectionPass;
|
proc setupEnvVar(owner: PSym; d: DetectionPass;
|
||||||
c: var LiftingPass): PNode =
|
c: var LiftingPass): PNode =
|
||||||
|
if owner.isIterator:
|
||||||
|
return getHiddenParam(owner).newSymNode
|
||||||
result = c.envvars.getOrDefault(owner.id)
|
result = c.envvars.getOrDefault(owner.id)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
let envVarType = d.ownerToType.getOrDefault(owner.id)
|
let envVarType = d.ownerToType.getOrDefault(owner.id)
|
||||||
|
|
@ -482,7 +486,11 @@ proc rawClosureCreation(owner: PSym;
|
||||||
d: DetectionPass; c: var LiftingPass): PNode =
|
d: DetectionPass; c: var LiftingPass): PNode =
|
||||||
result = newNodeI(nkStmtList, owner.info)
|
result = newNodeI(nkStmtList, owner.info)
|
||||||
|
|
||||||
let env = setupEnvVar(owner, d, c)
|
var env: PNode
|
||||||
|
if owner.isIterator:
|
||||||
|
env = getHiddenParam(owner).newSymNode
|
||||||
|
else:
|
||||||
|
env = setupEnvVar(owner, d, c)
|
||||||
if env.kind == nkSym:
|
if env.kind == nkSym:
|
||||||
var v = newNodeI(nkVarSection, env.info)
|
var v = newNodeI(nkVarSection, env.info)
|
||||||
addVar(v, env)
|
addVar(v, env)
|
||||||
|
|
|
||||||
87
tests/closure/tclosure0.nim
Normal file
87
tests/closure/tclosure0.nim
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
discard """
|
||||||
|
output: '''foo88
|
||||||
|
23 24foo 88
|
||||||
|
18
|
||||||
|
18
|
||||||
|
99
|
||||||
|
99
|
||||||
|
99
|
||||||
|
99 99
|
||||||
|
99 99
|
||||||
|
12 99 99
|
||||||
|
12 99 99'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
when true:
|
||||||
|
# test simple closure within dummy 'main':
|
||||||
|
proc dummy =
|
||||||
|
proc main2(param: int) =
|
||||||
|
var fooB = 23
|
||||||
|
proc outer(outerParam: string) =
|
||||||
|
var outerVar = 88
|
||||||
|
echo outerParam, outerVar
|
||||||
|
proc inner() =
|
||||||
|
block Test:
|
||||||
|
echo fooB, " ", param, outerParam, " ", outerVar
|
||||||
|
inner()
|
||||||
|
outer("foo")
|
||||||
|
main2(24)
|
||||||
|
|
||||||
|
dummy()
|
||||||
|
|
||||||
|
when true:
|
||||||
|
proc outer2(x:int) : proc(y:int):int = # curry-ed application
|
||||||
|
return proc(y:int):int = x*y
|
||||||
|
|
||||||
|
var fn = outer2(6) # the closure
|
||||||
|
echo fn(3) # it works
|
||||||
|
|
||||||
|
var rawP = fn.rawProc()
|
||||||
|
var rawE = fn.rawEnv()
|
||||||
|
|
||||||
|
# A type to cast the function pointer into a nimcall
|
||||||
|
type
|
||||||
|
TimesClosure = proc(a: int, x: pointer): int {.nimcall.}
|
||||||
|
|
||||||
|
# Call the function with its closure
|
||||||
|
echo cast[TimesClosure](rawP)(3, rawE)
|
||||||
|
|
||||||
|
when true:
|
||||||
|
proc outer =
|
||||||
|
var x, y: int = 99
|
||||||
|
proc innerA = echo x
|
||||||
|
proc innerB =
|
||||||
|
echo y
|
||||||
|
innerA()
|
||||||
|
|
||||||
|
innerA()
|
||||||
|
innerB()
|
||||||
|
|
||||||
|
outer()
|
||||||
|
|
||||||
|
when true:
|
||||||
|
proc indirectDep =
|
||||||
|
var x, y: int = 99
|
||||||
|
proc innerA = echo x, " ", y
|
||||||
|
proc innerB =
|
||||||
|
innerA()
|
||||||
|
|
||||||
|
innerA()
|
||||||
|
innerB()
|
||||||
|
|
||||||
|
indirectDep()
|
||||||
|
|
||||||
|
when true:
|
||||||
|
proc needlessIndirection =
|
||||||
|
var x, y: int = 99
|
||||||
|
proc indirection =
|
||||||
|
var z = 12
|
||||||
|
proc innerA = echo z, " ", x, " ", y
|
||||||
|
proc innerB =
|
||||||
|
innerA()
|
||||||
|
|
||||||
|
innerA()
|
||||||
|
innerB()
|
||||||
|
indirection()
|
||||||
|
|
||||||
|
needlessIndirection()
|
||||||
73
tests/iter/tclosureiters.nim
Normal file
73
tests/iter/tclosureiters.nim
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
discard """
|
||||||
|
output: '''0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
5 5
|
||||||
|
7 7
|
||||||
|
9 9
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
when true:
|
||||||
|
proc main() =
|
||||||
|
let
|
||||||
|
lo=0
|
||||||
|
hi=10
|
||||||
|
|
||||||
|
iterator itA(): int =
|
||||||
|
for x in lo..hi:
|
||||||
|
yield x
|
||||||
|
|
||||||
|
for x in itA():
|
||||||
|
echo x
|
||||||
|
|
||||||
|
var y: int
|
||||||
|
|
||||||
|
iterator itB(): int =
|
||||||
|
while y <= hi:
|
||||||
|
yield y
|
||||||
|
inc y
|
||||||
|
|
||||||
|
y = 5
|
||||||
|
for x in itB():
|
||||||
|
echo x, " ", y
|
||||||
|
inc y
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
iterator infinite(): int {.closure.} =
|
||||||
|
var i = 0
|
||||||
|
while true:
|
||||||
|
yield i
|
||||||
|
inc i
|
||||||
|
|
||||||
|
iterator take[T](it: iterator (): T, numToTake: int): T {.closure.} =
|
||||||
|
var i = 0
|
||||||
|
for x in it():
|
||||||
|
if i >= numToTake:
|
||||||
|
break
|
||||||
|
yield x
|
||||||
|
inc i
|
||||||
|
|
||||||
|
# gives wrong reasult (3 times 0)
|
||||||
|
for x in infinite.take(3):
|
||||||
|
echo x
|
||||||
|
|
||||||
|
# does what we want
|
||||||
|
let inf = infinite
|
||||||
|
for x in inf.take(3):
|
||||||
|
echo x
|
||||||
Loading…
Add table
Add a link
Reference in a new issue