From 4ab0438939dcb0adf5248270401a9a1f6ad968b8 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 11:37:43 +0800 Subject: [PATCH] for rangeExpr support if condition (fix #1243) --- cl/compile_test.go | 20 +++++++++++++++++++- cl/stmt.go | 23 +++++++++++++++++------ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/cl/compile_test.go b/cl/compile_test.go index 9d12df2fd..b98f320e2 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -149,7 +149,25 @@ var x string = c.Str() `) } -func Test_Issue1240(t *testing.T) { +func Test_RangeExpressionIf_Issue1243(t *testing.T) { + gopClTest(t, ` +for i <- :10, i%3 == 0 { + println i +}`, `package main + +import fmt "fmt" + +func main() { + for i := 0; i < 10; i += 1 { + if i%3 == 0 { + fmt.Println(i) + } + } +} +`) +} + +func Test_CastSlice_Issue1240(t *testing.T) { gopClTest(t, ` type fvec []float64 type foo float64 diff --git a/cl/stmt.go b/cl/stmt.go index ce318822f..c788fa99e 100644 --- a/cl/stmt.go +++ b/cl/stmt.go @@ -258,7 +258,7 @@ func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) { if v.Tok == token.ASSIGN { tok = v.Tok } - compileForStmt(ctx, toForStmt(v.For, v.Key, v.Body, re, tok)) + compileForStmt(ctx, toForStmt(v.For, v.Key, v.Body, re, tok, nil)) return } cb := ctx.cb @@ -306,7 +306,7 @@ func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) { func compileForPhraseStmt(ctx *blockCtx, v *ast.ForPhraseStmt) { if re, ok := v.X.(*ast.RangeExpr); ok { - compileForStmt(ctx, toForStmt(v.For, v.Value, v.Body, re, token.DEFINE)) + compileForStmt(ctx, toForStmt(v.For, v.Value, v.Body, re, token.DEFINE, v.ForPhrase)) return } cb := ctx.cb @@ -338,7 +338,7 @@ func compileForPhraseStmt(ctx *blockCtx, v *ast.ForPhraseStmt) { cb.End() } -func toForStmt(forPos token.Pos, value ast.Expr, body *ast.BlockStmt, re *ast.RangeExpr, tok token.Token) *ast.ForStmt { +func toForStmt(forPos token.Pos, value ast.Expr, body *ast.BlockStmt, re *ast.RangeExpr, tok token.Token, fp *ast.ForPhrase) *ast.ForStmt { nilIdent := value == nil if !nilIdent { if v, ok := value.(*ast.Ident); ok && v.Name == "_" { @@ -348,11 +348,12 @@ func toForStmt(forPos token.Pos, value ast.Expr, body *ast.BlockStmt, re *ast.Ra if nilIdent { value = &ast.Ident{NamePos: forPos, Name: "_gop_k"} } - if re.First == nil { - re.First = &ast.BasicLit{ValuePos: forPos, Kind: token.INT, Value: "0"} + first := re.First + if first == nil { + first = &ast.BasicLit{ValuePos: forPos, Kind: token.INT, Value: "0"} } initLhs := []ast.Expr{value} - initRhs := []ast.Expr{re.First} + initRhs := []ast.Expr{first} replaceValue := false var cond ast.Expr var post ast.Expr @@ -390,6 +391,16 @@ func toForStmt(forPos token.Pos, value ast.Expr, body *ast.BlockStmt, re *ast.Ra }}, body.List...) tok = token.DEFINE } + if fp != nil && fp.Cond != nil { + condStmt := &ast.IfStmt{ + Init: fp.Init, + Cond: fp.Cond, + Body: body, + } + body = &ast.BlockStmt{ + List: []ast.Stmt{condStmt}, + } + } return &ast.ForStmt{ For: forPos, Init: &ast.AssignStmt{