Skip to content

Commit a0c5279

Browse files
authored
internal/gogrep: add support for $*_ in slice expr members (#284)
`$*_` inside a slice expression encodes an optional slice expression member: it could be nil or set to something that is non-nil.
1 parent af7b672 commit a0c5279

File tree

4 files changed

+54
-21
lines changed

4 files changed

+54
-21
lines changed

internal/gogrep/compile.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -534,31 +534,31 @@ func (c *compiler) compileSliceExpr(n *ast.SliceExpr) {
534534
switch {
535535
case n.Low == nil && n.High == nil && !n.Slice3:
536536
c.emitInstOp(opSliceExpr)
537-
c.compileExpr(n.X)
537+
c.compileOptExpr(n.X)
538538
case n.Low != nil && n.High == nil && !n.Slice3:
539539
c.emitInstOp(opSliceFromExpr)
540-
c.compileExpr(n.X)
541-
c.compileExpr(n.Low)
540+
c.compileOptExpr(n.X)
541+
c.compileOptExpr(n.Low)
542542
case n.Low == nil && n.High != nil && !n.Slice3:
543543
c.emitInstOp(opSliceToExpr)
544-
c.compileExpr(n.X)
545-
c.compileExpr(n.High)
544+
c.compileOptExpr(n.X)
545+
c.compileOptExpr(n.High)
546546
case n.Low != nil && n.High != nil && !n.Slice3:
547547
c.emitInstOp(opSliceFromToExpr)
548-
c.compileExpr(n.X)
549-
c.compileExpr(n.Low)
550-
c.compileExpr(n.High)
548+
c.compileOptExpr(n.X)
549+
c.compileOptExpr(n.Low)
550+
c.compileOptExpr(n.High)
551551
case n.Low == nil && n.Slice3:
552552
c.emitInstOp(opSliceToCapExpr)
553-
c.compileExpr(n.X)
554-
c.compileExpr(n.High)
555-
c.compileExpr(n.Max)
553+
c.compileOptExpr(n.X)
554+
c.compileOptExpr(n.High)
555+
c.compileOptExpr(n.Max)
556556
case n.Low != nil && n.Slice3:
557557
c.emitInstOp(opSliceFromToCapExpr)
558-
c.compileExpr(n.X)
559-
c.compileExpr(n.Low)
560-
c.compileExpr(n.High)
561-
c.compileExpr(n.Max)
558+
c.compileOptExpr(n.X)
559+
c.compileOptExpr(n.Low)
560+
c.compileOptExpr(n.High)
561+
c.compileOptExpr(n.Max)
562562
default:
563563
panic(c.errorf(n, "unexpected slice expr"))
564564
}

internal/gogrep/compile_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,19 @@ func TestCompileWildcard(t *testing.T) {
343343
` • • NodeSeq`,
344344
` • • End`,
345345
},
346+
347+
`s[$*_:$*_]`: {
348+
`SliceFromToExpr`,
349+
` • Ident s`,
350+
` • OptNode`,
351+
` • OptNode`,
352+
},
353+
354+
`s[$*_:]`: {
355+
`SliceFromExpr`,
356+
` • Ident s`,
357+
` • OptNode`,
358+
},
346359
})
347360

348361
for i := range tests {

internal/gogrep/match.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -251,24 +251,23 @@ func (m *matcher) matchNodeWithInst(inst instruction, n ast.Node) bool {
251251
return ok && n.Low == nil && n.High == nil && m.matchNode(n.X)
252252
case opSliceFromExpr:
253253
n, ok := n.(*ast.SliceExpr)
254-
return ok && n.Low != nil && n.High == nil && !n.Slice3 &&
254+
return ok && n.High == nil && !n.Slice3 &&
255255
m.matchNode(n.X) && m.matchNode(n.Low)
256256
case opSliceToExpr:
257257
n, ok := n.(*ast.SliceExpr)
258-
return ok && n.Low == nil && n.High != nil && !n.Slice3 &&
258+
return ok && n.Low == nil && !n.Slice3 &&
259259
m.matchNode(n.X) && m.matchNode(n.High)
260260
case opSliceFromToExpr:
261261
n, ok := n.(*ast.SliceExpr)
262-
return ok && n.Low != nil && n.High != nil && !n.Slice3 &&
262+
return ok && !n.Slice3 &&
263263
m.matchNode(n.X) && m.matchNode(n.Low) && m.matchNode(n.High)
264264
case opSliceToCapExpr:
265265
n, ok := n.(*ast.SliceExpr)
266-
return ok && n.Low == nil && n.High != nil && n.Max != nil &&
266+
return ok && n.Low == nil &&
267267
m.matchNode(n.X) && m.matchNode(n.High) && m.matchNode(n.Max)
268268
case opSliceFromToCapExpr:
269269
n, ok := n.(*ast.SliceExpr)
270-
return ok && n.Low != nil && n.High != nil && n.Max != nil &&
271-
m.matchNode(n.X) && m.matchNode(n.Low) && m.matchNode(n.High) && m.matchNode(n.Max)
270+
return ok && m.matchNode(n.X) && m.matchNode(n.Low) && m.matchNode(n.High) && m.matchNode(n.Max)
272271

273272
case opIndexExpr:
274273
n, ok := n.(*ast.IndexExpr)

internal/gogrep/match_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,12 @@ func TestMatch(t *testing.T) {
167167
{`x[:y]`, 0, `z[:y]`},
168168
{`x[:y]`, 0, `x[:y:z]`},
169169
{`$x[:$y]`, 1, `a[:1]`},
170+
{`$x[:$y]`, 0, `a[:]`},
170171
{`x[y:]`, 1, `x[y:]`},
171172
{`x[y:]`, 0, `z[y:]`},
172173
{`x[y:]`, 0, `x[z:]`},
173174
{`$x[$y:]`, 1, `a[1:]`},
175+
{`$x[$y:]`, 0, `a[:]`},
174176
{`x[y:z]`, 1, `x[y:z]`},
175177
{`x[y:z]`, 0, `_[y:z]`},
176178
{`x[y:z]`, 0, `x[_:z]`},
@@ -189,6 +191,25 @@ func TestMatch(t *testing.T) {
189191
{`x[5:y:z]`, 0, `x[5:y:_]`},
190192
{`x[5:y:z]`, 0, `x[0:y:z]`},
191193
{`x[5:y:z]`, 0, `x[5:y]`},
194+
{`x[$*_:]`, 1, `x[:]`},
195+
{`x[$*_:]`, 1, `x[1:]`},
196+
{`x[$*_:]`, 0, `x[1:2]`},
197+
{`x[:$*_]`, 1, `x[:]`},
198+
{`x[:$*_]`, 1, `x[:2]`},
199+
{`x[:$*_]`, 0, `x[1:2]`},
200+
{`x[$*_:$*_]`, 1, `x[:]`},
201+
{`x[$*_:$*_]`, 1, `x[1:]`},
202+
{`x[$*_:$*_]`, 1, `x[:2]`},
203+
{`x[$*_:$*_]`, 1, `x[1:2]`},
204+
{`x[$*_:$*_]`, 0, `x[1:2:2]`},
205+
{`x[$*_:$*_:$*_]`, 1, `x[:]`},
206+
{`x[$*_:$*_:$*_]`, 1, `x[1:]`},
207+
{`x[$*_:$*_:$*_]`, 1, `x[:2]`},
208+
{`x[$*_:$*_:$*_]`, 1, `x[1:2]`},
209+
{`x[$*_:$*_:$*_]`, 1, `x[1:2:2]`},
210+
{`x[$*y:$*y]`, 1, `x[:]`},
211+
{`x[$*y:$*y]`, 1, `x[1:1]`},
212+
{`x[$*y:$*y]`, 0, `x[1:0]`},
192213

193214
// Composite literals.
194215
{`[]int{1, $x, $x}`, 1, `[]int{1, 2, 2}`},

0 commit comments

Comments
 (0)