enable closures tests for JS & implement finished for JS (#23521)

This commit is contained in:
ringabout
2024-09-09 20:20:40 +08:00
committed by GitHub
parent fcee829d85
commit 3a55bae53f
13 changed files with 79 additions and 28 deletions

View File

@@ -19,6 +19,8 @@
- JS backend now supports lambda lifting for closures. Use `--legacy:jsNoLambdaLifting` to emulate old behavior.
- JS backend now supports closure iterators.
- `owner` in `std/macros` is deprecated.
- Ambiguous type symbols in generic procs and templates now generate symchoice nodes.
@@ -51,6 +53,7 @@
let baz = a # error
```
## Standard library additions and changes
[//]: # "Changes:"

View File

@@ -611,6 +611,17 @@ template unaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
r.res = frmt % [a, tmp]
r.kind = resExpr
proc genBreakState(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes = default(TCompRes)
# mangle `:state` properly somehow
if n.kind == nkClosure:
gen(p, n[1], a)
r.res = "(($1).HEX3Astate < 0)" % [rdLoc(a)]
else:
gen(p, n, a)
r.res = "((($1.ClE_0).HEX3Astate) < 0)" % [rdLoc(a)]
r.kind = resExpr
proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
var
x, y: TCompRes = default(TCompRes)
@@ -3054,16 +3065,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
of nkGotoState, nkState:
globalError(p.config, n.info, "not implemented")
of nkBreakState:
var a: TCompRes = default(TCompRes)
if n[0].kind == nkClosure:
gen(p, n[0][1], a)
let sym = n[0][1].typ[0].n[0].sym
r.res = "(($1).$2 < 0)" % [rdLoc(a), mangleName(p.module, sym)]
else:
gen(p, n[0], a)
let sym = n[0].typ[0].n[0].sym
r.res = "((($1.ClE_0).$2) < 0)" % [rdLoc(a), mangleName(p.module, sym)]
r.kind = resExpr
genBreakState(p, n[0], r)
of nkPragmaBlock: gen(p, n.lastSon, r)
of nkComesFrom:
discard "XXX to implement for better stack traces"

View File

@@ -2350,8 +2350,14 @@ when notJSnotNims:
`result` = `x`.ClE_0;
""".}
proc finished*[T: iterator {.closure.}](x: T): bool {.noSideEffect, inline, magic: "Finished".} =
## It can be used to determine if a first class iterator has finished.
proc finished*[T: iterator {.closure.}](x: T): bool {.noSideEffect, inline, magic: "Finished".} =
## It can be used to determine if a first class iterator has finished.
when defined(js):
# TODO: mangle `:state`
{.emit: """
`result` = (`x`.ClE_0).HEX3Astate < 0;
""".}
else:
{.emit: """
`result` = ((NI*) `x`.ClE_0)[1] < 0;
""".}

View File

@@ -1,4 +1,5 @@
discard """
targets: "c js"
output: "@[\"42\"]"
"""

View File

@@ -1,4 +1,5 @@
discard """
targets: "c js"
output: '''
foo88
23 24foo 88
@@ -183,14 +184,32 @@ block tclosure2:
import typetraits
proc myDiscard[T](a: T) = discard
block:
proc myDiscard[T](a: T) = discard
proc foo() =
let a = 5
let f = (proc() =
myDiscard (proc() = echo a)
)
echo name(typeof(f))
proc foo() =
let a = 5
let f = (proc() =
myDiscard (proc() = echo a)
)
echo name(typeof(f))
foo()
foo()
block:
iterator foo: int {.closure.} =
yield 1
yield 2
yield 3
proc pork =
let call = foo
for i in call():
discard i
let call2 = foo
while not finished(call2):
discard call2()
pork()

View File

@@ -1,3 +1,7 @@
discard """
targets: "c js"
"""
type
A[T] = iterator(x: T): T {.gcsafe, closure.}

View File

@@ -1,3 +1,7 @@
discard """
targets: "c js"
"""
# bug #21306
type
FutureState {.pure.} = enum

View File

@@ -1,3 +1,7 @@
discard """
targets: "c js"
"""
template t1(i: int): int=
i+1
template t2(i: int): int=

View File

@@ -1,4 +1,5 @@
discard """
targets: "c js"
output: '''1
2
3

View File

@@ -1,4 +1,5 @@
discard """
targets: "c js"
output: '''0
1
2
@@ -152,15 +153,18 @@ iterator filesIt(path: string): auto {.closure.} =
yield prefix / f
# bug #13815
var love = iterator: int {.closure.} =
yield cast[type(
block:
var a = 0
yield a
a)](0)
when not defined(js):
var love = iterator: int {.closure.} =
yield cast[type(
block:
var a = 0
yield a
a)](0)
for i in love():
echo i
for i in love():
echo i
else:
echo 0
# bug #18474
iterator pairs(): (int, int) {.closure.} =

View File

@@ -1,4 +1,5 @@
discard """
targets: "c js"
output: '''
[
1

View File

@@ -1,4 +1,5 @@
discard """
targets: "c js"
output: '''
Selecting 2
1.0

View File

@@ -1,4 +1,5 @@
discard """
target: "c js"
output: '''
0
1