mirror of
https://github.com/apple/pkl.git
synced 2026-06-25 14:56:19 +02:00
Improve handling of frame slots (#1634)
This makes various improvements to the handling of frame slot vars, and includes some bug fixes introduced by https://github.com/apple/pkl/pull/1622 * Refactor SymbolTable to track for-generator and parameter slots in each scope * Execute let expressions in their own root node in some places * Unify how frame slots are managed; they are all represented as `FrameSlotVariable`, created in `AstBuilder`, and passed into `SymbolTable`. * Fix how let expressions are executed in custom this scopes (introduce a new root node when needed)
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
// let expr inside custom this scopes
|
||||
typealias Foo = String(let (x = this) this == x)
|
||||
|
||||
typealias Foo2 = String(let (x = "foo") this.startsWith(x), let (y = "o") this.endsWith(y))
|
||||
|
||||
typealias Foo3 = String(let (x = "foo") this.startsWith(x))(let (y = "o") this.endsWith(y))
|
||||
|
||||
res1: Foo = "foo"
|
||||
|
||||
res2: Foo2 = "foo"
|
||||
|
||||
res3: Foo3 = "foo"
|
||||
|
||||
hidden bar {
|
||||
new {
|
||||
name = "fooey"
|
||||
}
|
||||
}
|
||||
|
||||
res4 = (bar) {
|
||||
[[let (x = "foo") this.name.startsWith(x)]] {
|
||||
name = "bob"
|
||||
}
|
||||
}
|
||||
|
||||
res5 = (bar) {
|
||||
[[let (x = this) x.name.startsWith("foo")]] {
|
||||
name = "bob"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
res =
|
||||
let (
|
||||
x = new Listing {
|
||||
for (elem in List(1, 2)) {
|
||||
elem + 5
|
||||
}
|
||||
}
|
||||
)
|
||||
x
|
||||
|
||||
res2 =
|
||||
let (qux = 1)
|
||||
let (
|
||||
x = new Listing {
|
||||
for (num in List(1, 2)) {
|
||||
qux + num
|
||||
}
|
||||
}
|
||||
)
|
||||
x
|
||||
|
||||
res3 =
|
||||
let (qux = 1)
|
||||
let (
|
||||
x = new Listing {
|
||||
for (num in List(1, 2)) {
|
||||
qux + num
|
||||
}
|
||||
}
|
||||
)
|
||||
let (y = 5)
|
||||
let (
|
||||
z = new Listing {
|
||||
for (nummm in List(1, 2)) {
|
||||
when (qux + y == nummm) {
|
||||
nummm + y
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
new { ...x; ...z }
|
||||
|
||||
res4 =
|
||||
let (m: Mapping<String, String> = new Mapping {
|
||||
["foo"] = "bar"
|
||||
})
|
||||
new Mapping {
|
||||
for (k, _ in Map("foo", "bar")) {
|
||||
[k] {
|
||||
m[k]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
prop = "qux"
|
||||
|
||||
res =
|
||||
new Mapping {
|
||||
default {
|
||||
when (module.prop == "qux") {
|
||||
myProp = "qux"
|
||||
}
|
||||
}
|
||||
["bar"] {}
|
||||
}
|
||||
+13
@@ -480,3 +480,16 @@ whenWithElse = new Dynamic {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local func = (it) -> new Listing {
|
||||
for (elem1 in List(1, 2)) {
|
||||
it
|
||||
new Listing {
|
||||
for (elem2 in List(1, 2)) {
|
||||
elem1 + elem2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nestedForsWithinLambda = func.apply("hi")
|
||||
|
||||
+39
@@ -475,3 +475,42 @@ withinLetExpr =
|
||||
[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// object bodies that are children of for-generators inherit the frame descriptor of the parent object
|
||||
nestedObjectInsideFor {
|
||||
for (idx, qux in List(1, 2)) {
|
||||
[idx] {
|
||||
for (baz in List(1, 2)) {
|
||||
when (baz == qux) {
|
||||
baz
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// object bodies inherit the frame descriptor of the parent object
|
||||
doublyNestedObjectInsideFor {
|
||||
for (idx, qux in List(1, 2)) {
|
||||
[idx] {
|
||||
new Listing {
|
||||
for (baz in List(1, 2)) {
|
||||
when (baz == qux) {
|
||||
baz
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insideObjectBodyWithParam: Mapping<String, Dynamic> = new {
|
||||
default { key ->
|
||||
for (key, value in Map("foo", List(new Dynamic { bar = 1 }))) {
|
||||
[key] {
|
||||
...value
|
||||
}
|
||||
}
|
||||
}
|
||||
["res"] {}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
examples {
|
||||
local a = List("1", "2", "3", "4")
|
||||
local b = List("a", "b", "c", "d")
|
||||
|
||||
|
||||
["shadow key variable"] {
|
||||
new {
|
||||
for (key, outerValue in a) {
|
||||
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
res {
|
||||
for (prefix in List("foo")) {
|
||||
"foobar" as String(let (y = this) y.startsWith(prefix))
|
||||
}
|
||||
}
|
||||
+27
-1
@@ -43,7 +43,8 @@ res5 = new {
|
||||
|
||||
// nested predicate
|
||||
res6 = (people) {
|
||||
[[(people) { [[name == "Barn Owl"]] { age = 99 } }.toList().find((it) -> it.age == 99).name == name]] {
|
||||
[[(people) { [[name == "Barn Owl"]] { age = 99 } }.toList().find((it) -> it.age == 99).name
|
||||
== name]] {
|
||||
age = 55
|
||||
}
|
||||
}
|
||||
@@ -86,3 +87,28 @@ res12 = (people) {
|
||||
[[name == "Pigeon"]] { age = 122 }
|
||||
}
|
||||
}
|
||||
|
||||
res13 = (people) {
|
||||
[[(() -> this.name == "Pigeon").apply()]] {
|
||||
age = 99
|
||||
}
|
||||
}
|
||||
|
||||
res14 = (people) {
|
||||
for (foo in List(1, 2)) {
|
||||
[[foo == 1]] {
|
||||
age = foo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res15 =
|
||||
(
|
||||
(it) -> (people) {
|
||||
for (foo in List(1, 2)) {
|
||||
[[foo == 1]] {
|
||||
age = foo
|
||||
}
|
||||
}
|
||||
}
|
||||
).apply("hi")
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
res1 = "foo"
|
||||
res2 = "foo"
|
||||
res3 = "foo"
|
||||
res4 {
|
||||
new {
|
||||
name = "bob"
|
||||
}
|
||||
}
|
||||
res5 {
|
||||
new {
|
||||
name = "bob"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
res {
|
||||
6
|
||||
7
|
||||
}
|
||||
res2 {
|
||||
2
|
||||
3
|
||||
}
|
||||
res3 {
|
||||
2
|
||||
3
|
||||
}
|
||||
res4 {
|
||||
["foo"] {
|
||||
"bar"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
prop = "qux"
|
||||
res {
|
||||
["bar"] {
|
||||
myProp = "qux"
|
||||
}
|
||||
}
|
||||
+12
@@ -335,3 +335,15 @@ whenWithElse {
|
||||
20
|
||||
40
|
||||
}
|
||||
nestedForsWithinLambda {
|
||||
"hi"
|
||||
new {
|
||||
2
|
||||
3
|
||||
}
|
||||
"hi"
|
||||
new {
|
||||
3
|
||||
4
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -323,3 +323,32 @@ withinLetExpr {
|
||||
["a"] = 1
|
||||
["b"] = 2
|
||||
}
|
||||
nestedObjectInsideFor {
|
||||
[0] {
|
||||
1
|
||||
}
|
||||
[1] {
|
||||
2
|
||||
}
|
||||
}
|
||||
doublyNestedObjectInsideFor {
|
||||
[0] {
|
||||
new {
|
||||
1
|
||||
}
|
||||
}
|
||||
[1] {
|
||||
new {
|
||||
2
|
||||
}
|
||||
}
|
||||
}
|
||||
insideObjectBodyWithParam {
|
||||
["res"] {
|
||||
["foo"] {
|
||||
new {
|
||||
bar = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
res {
|
||||
"foobar"
|
||||
}
|
||||
+42
@@ -153,3 +153,45 @@ res12 {
|
||||
age = 33
|
||||
}
|
||||
}
|
||||
res13 {
|
||||
new {
|
||||
name = "Pigeon"
|
||||
age = 99
|
||||
}
|
||||
new {
|
||||
name = "Barn Owl"
|
||||
age = 21
|
||||
}
|
||||
new {
|
||||
name = "Parrot"
|
||||
age = 33
|
||||
}
|
||||
}
|
||||
res14 {
|
||||
new {
|
||||
name = "Pigeon"
|
||||
age = 1
|
||||
}
|
||||
new {
|
||||
name = "Barn Owl"
|
||||
age = 1
|
||||
}
|
||||
new {
|
||||
name = "Parrot"
|
||||
age = 1
|
||||
}
|
||||
}
|
||||
res15 {
|
||||
new {
|
||||
name = "Pigeon"
|
||||
age = 1
|
||||
}
|
||||
new {
|
||||
name = "Barn Owl"
|
||||
age = 1
|
||||
}
|
||||
new {
|
||||
name = "Parrot"
|
||||
age = 1
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user