Skip to content

Commit d937f8e

Browse files
committed
generate slices.All
1 parent 27731d8 commit d937f8e

File tree

3 files changed

+72
-67
lines changed

3 files changed

+72
-67
lines changed

microsmith/expr.go

+11
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,17 @@ func (eb *ExprBuilder) CallFunction(v Variable, ct ...Type) *ast.CallExpr {
794794
ce.Args = []ast.Expr{eb.VarOrLit(t1), eb.VarOrLit(t2)}
795795
}
796796

797+
case "slices.All":
798+
if len(ct) == 0 {
799+
panic("slices.All needs additional type arg")
800+
}
801+
t := ArrayOf(ct[0])
802+
if eb.Deepen() {
803+
ce.Args = []ast.Expr{eb.Expr(t)}
804+
} else {
805+
ce.Args = []ast.Expr{eb.VarOrLit(t)}
806+
}
807+
797808
default:
798809
if f.Args == nil || f.Ret == nil {
799810
panic("CallFunction: missing special handling for " + name)

microsmith/package.go

+16-34
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func (pb *PackageBuilder) File() *ast.File {
196196
}
197197
}
198198

199-
pkgs := []string{"sync/atomic", "math", "reflect", "strings", "unsafe"}
199+
pkgs := []string{"sync/atomic", "math", "reflect", "strings", "unsafe", "slices"}
200200
for _, p := range pkgs {
201201
af.Decls = append(af.Decls, MakeImport(p))
202202
}
@@ -308,44 +308,26 @@ func MakeImport(p string) *ast.GenDecl {
308308
}
309309

310310
func MakeUsePakage(p string) *ast.GenDecl {
311-
se := &ast.SelectorExpr{}
312-
switch p {
313-
case "unsafe":
314-
// var _ = unsafe.Sizeof is not allowed, we need to call it.
315-
return &ast.GenDecl{
316-
Tok: token.VAR,
317-
Specs: []ast.Spec{
318-
&ast.ValueSpec{
319-
Names: []*ast.Ident{&ast.Ident{Name: "_"}},
320-
Values: []ast.Expr{&ast.CallExpr{
321-
Fun: &ast.SelectorExpr{
322-
X: &ast.Ident{Name: "unsafe"},
323-
Sel: &ast.Ident{Name: "Sizeof"},
324-
},
325-
Args: []ast.Expr{&ast.Ident{Name: "0"}},
326-
}},
327-
},
328-
},
329-
}
330-
case "sync/atomic":
331-
se.X = &ast.Ident{Name: "atomic"}
332-
se.Sel = &ast.Ident{Name: "LoadInt32"}
333-
default:
334-
fs := map[string]string{
335-
"math": "Sqrt",
336-
"strings": "Title",
337-
"reflect": "DeepEqual",
338-
}
339-
se.X = &ast.Ident{Name: p}
340-
se.Sel = &ast.Ident{Name: fs[p]}
311+
m := map[string]struct{ p, f, v string }{
312+
"unsafe": {"unsafe", "Sizeof", "0"},
313+
"sync/atomic": {"atomic", "LoadInt32", "nil"},
314+
"slices": {"slices", "All", "[]int{}"},
315+
"math": {"math", "Sqrt", "0"},
316+
"strings": {"strings", "Title", `""`},
317+
"reflect": {"reflect", "DeepEqual", "1,1"},
341318
}
342-
343319
return &ast.GenDecl{
344320
Tok: token.VAR,
345321
Specs: []ast.Spec{
346322
&ast.ValueSpec{
347-
Names: []*ast.Ident{&ast.Ident{Name: "_"}},
348-
Values: []ast.Expr{se},
323+
Names: []*ast.Ident{&ast.Ident{Name: "_"}},
324+
Values: []ast.Expr{&ast.CallExpr{
325+
Fun: &ast.SelectorExpr{
326+
X: &ast.Ident{Name: m[p].p},
327+
Sel: &ast.Ident{Name: m[p].f},
328+
},
329+
Args: []ast.Expr{&ast.Ident{Name: m[p].v}},
330+
}},
349331
},
350332
},
351333
}

microsmith/stmt.go

+45-33
Original file line numberDiff line numberDiff line change
@@ -514,42 +514,54 @@ func (sb *StmtBuilder) RangeStmt() *ast.RangeStmt {
514514
e = f(BT{"int"})
515515
k = sb.S.NewIdent(BT{"int"})
516516
case 3: // func
517-
ft := sb.pb.RandRangeableFuncType()
518-
p, r := ft.MakeFieldLists(true, sb.funcp)
519-
520-
// add yield param to the scope
521-
sb.S.AddVariable(p.List[0].Names[0], ft.Args[0])
522-
sb.funcp++
523-
524-
// generate a body for the func
525-
sb.depth++
526-
var body *ast.BlockStmt
527-
if sb.CanNest() {
528-
old := sb.C.inLoop
529-
sb.C.inLoop = false
530-
body = sb.BlockStmt()
531-
sb.C.inLoop = old
517+
518+
// 50/50 between generating a new Rangeable func type or a
519+
// call to a function from the slices package.
520+
if sb.R.Intn(2) == 0 {
521+
t := sb.pb.RandType()
522+
f := FuncType{N: "slices.All"}
523+
e = sb.E.CallFunction(Variable{f, &ast.Ident{Name: f.N}}, t)
524+
k = sb.S.NewIdent(BT{"int"})
525+
v = sb.S.NewIdent(t)
532526
} else {
533-
body = &ast.BlockStmt{List: []ast.Stmt{sb.AssignStmt()}}
534-
}
535-
sb.depth--
536527

537-
e = &ast.FuncLit{
538-
Type: &ast.FuncType{Params: p, Results: r},
539-
Body: body,
540-
}
528+
ft := sb.pb.RandRangeableFuncType()
529+
p, r := ft.MakeFieldLists(true, sb.funcp)
530+
531+
// add yield param to the scope
532+
sb.S.AddVariable(p.List[0].Names[0], ft.Args[0])
533+
sb.funcp++
541534

542-
// remove the yield param from the scope
543-
sb.S.DeleteIdentByName(p.List[0].Names[0])
544-
sb.funcp--
545-
546-
// declare the iteration variables if needed
547-
switch args := ft.Args[0].(FuncType).Args; len(args) {
548-
case 1:
549-
k = sb.S.NewIdent(args[0])
550-
case 2:
551-
k = sb.S.NewIdent(args[0])
552-
v = sb.S.NewIdent(args[1])
535+
// generate a body for the func
536+
sb.depth++
537+
var body *ast.BlockStmt
538+
if sb.CanNest() {
539+
old := sb.C.inLoop
540+
sb.C.inLoop = false
541+
body = sb.BlockStmt()
542+
sb.C.inLoop = old
543+
} else {
544+
body = &ast.BlockStmt{List: []ast.Stmt{sb.AssignStmt()}}
545+
}
546+
sb.depth--
547+
548+
e = &ast.FuncLit{
549+
Type: &ast.FuncType{Params: p, Results: r},
550+
Body: body,
551+
}
552+
553+
// remove the yield param from the scope
554+
sb.S.DeleteIdentByName(p.List[0].Names[0])
555+
sb.funcp--
556+
557+
// declare the iteration variables if needed
558+
switch args := ft.Args[0].(FuncType).Args; len(args) {
559+
case 1:
560+
k = sb.S.NewIdent(args[0])
561+
case 2:
562+
k = sb.S.NewIdent(args[0])
563+
v = sb.S.NewIdent(args[1])
564+
}
553565
}
554566
default:
555567
panic("unreachable")

0 commit comments

Comments
 (0)