perf(gengo): short-circuit AND/OR with literal LHS
Skip the PushBool/PopLogical/branch wrapper when the LHS of .AND. / .OR. is a bare .T./.F. literal. `.T. .AND. X` emits X alone; `.F. .AND. X` emits PushBool(false) with X dropped; symmetric for OR. Common after constant-folding a sub-expression — pairs with the earlier dead-IF-branch peephole. FiveSql2 43/43, Harbour compat 56/56. Verified via /tmp/test_andor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1938,8 +1938,19 @@ func (g *Generator) emitExpr(expr ast.Expr) {
|
||||
g.emitLiteral(folded)
|
||||
break
|
||||
}
|
||||
// Short-circuit AND/OR: Harbour evaluates right operand only if needed
|
||||
// Short-circuit AND/OR: Harbour evaluates right operand only if needed.
|
||||
// With a literal LHS we can skip the PushBool/PopLogical roundtrip
|
||||
// entirely — .T. .AND. B folds to B, .F. .AND. B folds to false,
|
||||
// and symmetrically for OR.
|
||||
if e.Op == token.AND {
|
||||
if v, ok := boolLiteralValue(e.Left); ok {
|
||||
if v {
|
||||
g.emitExpr(e.Right)
|
||||
} else {
|
||||
g.writeln("t.PushBool(false)")
|
||||
}
|
||||
break
|
||||
}
|
||||
g.emitExpr(e.Left)
|
||||
g.writeln("if !t.PopLogical() {")
|
||||
g.writeln("t.PushBool(false)")
|
||||
@@ -1947,6 +1958,14 @@ func (g *Generator) emitExpr(expr ast.Expr) {
|
||||
g.emitExpr(e.Right)
|
||||
g.writeln("}")
|
||||
} else if e.Op == token.OR {
|
||||
if v, ok := boolLiteralValue(e.Left); ok {
|
||||
if v {
|
||||
g.writeln("t.PushBool(true)")
|
||||
} else {
|
||||
g.emitExpr(e.Right)
|
||||
}
|
||||
break
|
||||
}
|
||||
g.emitExpr(e.Left)
|
||||
g.writeln("if t.PopLogical() {")
|
||||
g.writeln("t.PushBool(true)")
|
||||
|
||||
Reference in New Issue
Block a user