perf(gengo): fold DO WHILE .T. / .F. at compile time
DO WHILE .T. now emits a bare for-loop with no PushBool/PopLogical per iteration — saves a stack roundtrip on every trip through the idiomatic infinite-loop pattern (9 .prg files use it). DO WHILE .F. emits nothing. Loop exits still work via EXIT / RETURN. FiveSql2 43/43, Harbour compat 56/56. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1391,6 +1391,11 @@ emit:
|
||||
}
|
||||
|
||||
func (g *Generator) emitDoWhile(s *ast.DoWhileStmt, locals localMap) {
|
||||
// DO WHILE .F. — body is unreachable; emit nothing.
|
||||
if v, ok := boolLiteralValue(s.Cond); ok && !v {
|
||||
return
|
||||
}
|
||||
|
||||
// Detect RDD commands in body for WA hoisting
|
||||
hasRDD := hasRDDCommands(s.Body)
|
||||
safeToHoist := hasRDD && !hasWorkareaChange(s.Body)
|
||||
@@ -1405,8 +1410,12 @@ func (g *Generator) emitDoWhile(s *ast.DoWhileStmt, locals localMap) {
|
||||
|
||||
g.writeln("for {")
|
||||
g.indent++
|
||||
g.emitExpr(s.Cond)
|
||||
g.writeln("if !t.PopLogical() { break }")
|
||||
// DO WHILE .T. — the idiomatic infinite loop. Skip the per-iteration
|
||||
// PushBool/PopLogical; exit only through EXIT / LOOP / RETURN.
|
||||
if v, ok := boolLiteralValue(s.Cond); !ok || !v {
|
||||
g.emitExpr(s.Cond)
|
||||
g.writeln("if !t.PopLogical() { break }")
|
||||
}
|
||||
for _, stmt := range s.Body {
|
||||
g.emitStmt(stmt, locals)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user