Skip to content

Commit 241c5bf

Browse files
committed
cue/parser: allow let clause in comprehension
Closes #284 Change-Id: Ie051eb90f98f8e3cdf85d2aa3177ca6355619c9b Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7303 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 0eb7cc5 commit 241c5bf

File tree

5 files changed

+61
-14
lines changed

5 files changed

+61
-14
lines changed

cue/ast/astutil/resolve.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -413,20 +413,30 @@ func resolveIdent(s *scope, x *ast.Ident) bool {
413413

414414
func scopeClauses(s *scope, clauses []ast.Clause) *scope {
415415
for _, c := range clauses {
416-
if f, ok := c.(*ast.ForClause); ok { // TODO(let): support let clause
417-
walk(s, f.Source)
418-
s = newScope(s.file, s, f, nil)
419-
if f.Key != nil {
420-
name, err := ast.ParseIdent(f.Key)
416+
switch x := c.(type) {
417+
case *ast.ForClause:
418+
walk(s, x.Source)
419+
s = newScope(s.file, s, x, nil)
420+
if x.Key != nil {
421+
name, err := ast.ParseIdent(x.Key)
421422
if err == nil {
422-
s.insert(name, f.Key, f)
423+
s.insert(name, x.Key, x)
423424
}
424425
}
425-
name, err := ast.ParseIdent(f.Value)
426+
name, err := ast.ParseIdent(x.Value)
426427
if err == nil {
427-
s.insert(name, f.Value, f)
428+
s.insert(name, x.Value, x)
428429
}
429-
} else {
430+
431+
case *ast.LetClause:
432+
walk(s, x.Expr)
433+
s = newScope(s.file, s, x, nil)
434+
name, err := ast.ParseIdent(x.Ident)
435+
if err == nil {
436+
s.insert(name, x.Ident, x)
437+
}
438+
439+
default:
430440
walk(s, c)
431441
}
432442
}

cue/parser/parser.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,11 +1123,20 @@ func (p *parser) parseComprehensionClauses(first bool) (clauses []ast.Clause, c
11231123
Condition: p.parseRHS(),
11241124
}))
11251125

1126-
// TODO:
1127-
// case token.LET:
1128-
// c := p.openComments()
1129-
// p.expect(token.LET)
1130-
// return nil, c
1126+
case token.LET:
1127+
c := p.openComments()
1128+
letPos := p.expect(token.LET)
1129+
1130+
ident := p.parseIdent()
1131+
assign := p.expect(token.BIND)
1132+
expr := p.parseRHS()
1133+
1134+
clauses = append(clauses, c.closeClause(p, &ast.LetClause{
1135+
Let: letPos,
1136+
Ident: ident,
1137+
Equal: assign,
1138+
Expr: expr,
1139+
}))
11311140

11321141
default:
11331142
return clauses, nil

cue/parser/parser_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,17 @@ func TestParse(t *testing.T) {
279279
}
280280
}`,
281281
`{y: {a: 1, b: 2}, a: {for k: v in y if v>2 {"\(k)": v}}}`,
282+
}, {
283+
"nested comprehensions",
284+
`{
285+
y: { a: 1, b: 2}
286+
a: {
287+
for k, v in y let x = v+2 if x > 2 {
288+
"\(k)": v
289+
}
290+
}
291+
}`,
292+
`{y: {a: 1, b: 2}, a: {for k: v in y let x=v+2 if x>2 {"\(k)": v}}}`,
282293
}, {
283294
"let declaration",
284295
`{

cue/testdata/eval/comprehensions.txtar

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ b: {
1313
l: 40
1414
}
1515
}
16+
17+
c: {
18+
for k, v in a let y = v+10 if y > 50 {
19+
"\(k)": y
20+
}
21+
}
1622
-- out/eval --
1723
(struct){
1824
a: (struct){
@@ -26,6 +32,10 @@ b: {
2632
z: (int){ 50 }
2733
l: (int){ 40 }
2834
}
35+
c: (struct){
36+
y: (int){ 110 }
37+
z: (int){ 60 }
38+
}
2939
}
3040
-- out/compile --
3141
--- in.cue
@@ -48,4 +58,9 @@ b: {
4858
l: 40
4959
}
5060
}
61+
c: {
62+
for k, v in 〈1;a〉 let y = (〈0;v〉 + 10) if (〈0;y〉 > 50) {
63+
"\(〈2;k〉)": 〈1;y〉
64+
}
65+
}
5166
}

internal/core/subsume/structural.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ func (c *collatedDecls) collate(env *adt.Environment, s *adt.StructLit) {
275275
c.yielders = append(c.yielders, x)
276276

277277
case *adt.LetClause:
278+
c.yielders = append(c.yielders, x)
279+
278280
case *adt.ValueClause:
279281
}
280282
}

0 commit comments

Comments
 (0)