Major changes since last commit: - FiveSql2 SQL:1999 engine (10,458 LOC) — 43/43 ALL PASS - 21 compiler/runtime bugs fixed (short-circuit AND/OR, FOR LOOP, etc.) - @byref pass-by-reference via RefCell pattern - Mutable closure capture (EnsureLocalRef + RefCell sharing) - RTL: 400 → 479 functions (+79: file, string, datetime, hash, UTF-8) - DateTime/Timestamp fully working (hb_DateTime, hb_Hour/Min/Sec, display) - Reserved word guard (39 keywords blocked from function calls) - AEval arg order fix (element before index) - Closure capture redecl fix (unique _cap_ names per block) - Hash/string indexing in ArrayPush/ArrayPop - Harbour compat test suite: 51/51 - 4 docs: Porting Report, Implementation Plan, Optimization Plan, Commercialization Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com)
|
|
// All rights reserved.
|
|
|
|
package gengo
|
|
|
|
import "five/compiler/ast"
|
|
|
|
// hasXBaseCommands checks if the file contains any xBase commands.
|
|
func hasXBaseCommands(file *ast.File) bool {
|
|
for _, d := range file.Decls {
|
|
switch decl := d.(type) {
|
|
case *ast.FuncDecl:
|
|
if scanStmtsForXBase(decl.Body) {
|
|
return true
|
|
}
|
|
case *ast.MethodDecl:
|
|
if scanStmtsForXBase(decl.Body) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func scanStmtsForXBase(stmts []ast.Stmt) bool {
|
|
for _, s := range stmts {
|
|
switch v := s.(type) {
|
|
case *ast.UseCmd, *ast.GoCmd, *ast.SkipCmd, *ast.SeekCmd,
|
|
*ast.ReplaceCmd, *ast.AppendCmd, *ast.DeleteCmd,
|
|
*ast.SelectCmd, *ast.IndexCmd, *ast.SetCmd:
|
|
return true
|
|
case *ast.IfStmt:
|
|
if scanStmtsForXBase(v.Body) || scanStmtsForXBase(v.ElseBody) {
|
|
return true
|
|
}
|
|
for _, ei := range v.ElseIfs {
|
|
if scanStmtsForXBase(ei.Body) {
|
|
return true
|
|
}
|
|
}
|
|
case *ast.ForStmt:
|
|
if scanStmtsForXBase(v.Body) {
|
|
return true
|
|
}
|
|
case *ast.ForEachStmt:
|
|
if scanStmtsForXBase(v.Body) {
|
|
return true
|
|
}
|
|
case *ast.DoWhileStmt:
|
|
if scanStmtsForXBase(v.Body) {
|
|
return true
|
|
}
|
|
case *ast.SeqStmt:
|
|
if scanStmtsForXBase(v.Body) || scanStmtsForXBase(v.RecoverBody) {
|
|
return true
|
|
}
|
|
case *ast.SwitchStmt:
|
|
for _, c := range v.Cases {
|
|
if scanStmtsForXBase(c.Body) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|