}}}
(context *funcContext, reg int, expr ast.Expr, thenlabel, elselabel int, hasnextcond bool)
| 930 | } // }}} |
| 931 | |
| 932 | func compileBranchCondition(context *funcContext, reg int, expr ast.Expr, thenlabel, elselabel int, hasnextcond bool) { // {{{ |
| 933 | // TODO folding constants? |
| 934 | code := context.Code |
| 935 | flip := 0 |
| 936 | jumplabel := elselabel |
| 937 | if hasnextcond { |
| 938 | flip = 1 |
| 939 | jumplabel = thenlabel |
| 940 | } |
| 941 | |
| 942 | switch ex := expr.(type) { |
| 943 | case *ast.FalseExpr, *ast.NilExpr: |
| 944 | if !hasnextcond { |
| 945 | code.AddASbx(OP_JMP, 0, elselabel, sline(expr)) |
| 946 | return |
| 947 | } |
| 948 | case *ast.TrueExpr, *ast.NumberExpr, *ast.StringExpr: |
| 949 | if !hasnextcond { |
| 950 | return |
| 951 | } |
| 952 | case *ast.UnaryNotOpExpr: |
| 953 | compileBranchCondition(context, reg, ex.Expr, elselabel, thenlabel, !hasnextcond) |
| 954 | return |
| 955 | case *ast.LogicalOpExpr: |
| 956 | switch ex.Operator { |
| 957 | case "and": |
| 958 | nextcondlabel := context.NewLabel() |
| 959 | compileBranchCondition(context, reg, ex.Lhs, nextcondlabel, elselabel, false) |
| 960 | context.SetLabelPc(nextcondlabel, context.Code.LastPC()) |
| 961 | compileBranchCondition(context, reg, ex.Rhs, thenlabel, elselabel, hasnextcond) |
| 962 | case "or": |
| 963 | nextcondlabel := context.NewLabel() |
| 964 | compileBranchCondition(context, reg, ex.Lhs, thenlabel, nextcondlabel, true) |
| 965 | context.SetLabelPc(nextcondlabel, context.Code.LastPC()) |
| 966 | compileBranchCondition(context, reg, ex.Rhs, thenlabel, elselabel, hasnextcond) |
| 967 | } |
| 968 | return |
| 969 | case *ast.RelationalOpExpr: |
| 970 | compileRelationalOpExprAux(context, reg, ex, flip, jumplabel) |
| 971 | return |
| 972 | } |
| 973 | |
| 974 | a := reg |
| 975 | compileExprWithMVPropagation(context, expr, ®, &a) |
| 976 | code.AddABC(OP_TEST, a, 0, 0^flip, sline(expr)) |
| 977 | code.AddASbx(OP_JMP, 0, jumplabel, sline(expr)) |
| 978 | } // }}} |
| 979 | |
| 980 | func compileWhileStmt(context *funcContext, stmt *ast.WhileStmt) { // {{{ |
| 981 | thenlabel := context.NewLabel() |
no test coverage detected
searching dependent graphs…