修正了一些错误
This commit is contained in:
@@ -16,6 +16,7 @@ import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Handles.HandlesType as HandlesType
|
||||
import lib.core.BuildPipeline as BuildPipeline
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.StubMerger as StubMerger
|
||||
@@ -31,8 +32,9 @@ import hashlib
|
||||
|
||||
# 内存大小: fl_bytes=264 (33*8), POOL_SIZE-fl_bytes 必须是 2 的幂以避免浪费
|
||||
# 1073742088 - 264 = 1073741824 (1024MB usable = 2^30)
|
||||
# 注意: POOL_SIZE 必须是 2^30+264=1073742088,否则 _largest_pow2_le 会取 2^29=512MB
|
||||
# Phase1 翻译 87 个 includes 文件 + Phase2 翻译 30 个测试文件,512MB 不足导致 Phase2 崩溃
|
||||
POOL_SIZE: t.CDefine = 1073741824
|
||||
POOL_SIZE: t.CDefine = 1073742088
|
||||
# 语言编码页
|
||||
CODE_PAGE: t.CDefine = 65001
|
||||
# 源代码缓冲区大小(1MB)
|
||||
@@ -47,18 +49,33 @@ SRC_BUF_SIZE: t.CDefine = 1048576
|
||||
def main() -> int:
|
||||
w32cmd.SetConsoleOutputCP(CODE_PAGE)
|
||||
w32cmd.SetConsoleCP(CODE_PAGE)
|
||||
# 用 fflush(0) 刷新所有流,确保崩溃前输出可见(0=NULL 刷新所有输出流)
|
||||
stdio.printf("[DBG] main enter\n")
|
||||
stdio.fflush(0)
|
||||
# 初始化 mbuddy 内存池
|
||||
stdio.printf("[DBG] before malloc\n")
|
||||
stdio.fflush(0)
|
||||
arena: bytes = stdlib.malloc(POOL_SIZE)
|
||||
stdio.printf("[DBG] after malloc arena=%p\n", arena)
|
||||
stdio.fflush(0)
|
||||
if arena is None:
|
||||
stdio.printf("FAIL: malloc for arena failed\n")
|
||||
return 1
|
||||
stdio.printf("[DBG] before MemBuddy\n")
|
||||
stdio.fflush(0)
|
||||
mb: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, POOL_SIZE)
|
||||
stdio.printf("[DBG] after MemBuddy mb=%p\n", mb)
|
||||
stdio.fflush(0)
|
||||
if mb is None:
|
||||
stdio.printf("FAIL: MemBuddy init failed\n")
|
||||
return 1
|
||||
|
||||
# 设置全局 mbuddy 指针(sys 和 argparse 都需要)
|
||||
stdio.printf("[DBG] before _mbuddy setup\n")
|
||||
stdio.fflush(0)
|
||||
sys._mbuddy = mb
|
||||
stdio.printf("[DBG] sys._mbuddy ok\n")
|
||||
stdio.fflush(0)
|
||||
argparse._mbuddy = mb
|
||||
ast._mbuddy = mb
|
||||
lib._mbuddy = (memhub.MemManager | t.CPtr)(mb)
|
||||
@@ -72,44 +89,87 @@ def main() -> int:
|
||||
Phase2._mbuddy = (memhub.MemManager | t.CPtr)(mb)
|
||||
subprocess._mbuddy = mb
|
||||
hashlib._mbuddy = (memhub.MemManager | t.CPtr)(mb)
|
||||
VLogger._mbuddy = (memhub.MemManager | t.CPtr)(mb)
|
||||
stdio.printf("[DBG] before InitLib\n")
|
||||
stdio.fflush(0)
|
||||
lib.InitLib((memhub.MemManager | t.CPtr)(mb))
|
||||
stdio.printf("[DBG] after InitLib\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
# 初始化 VLogger 并打印启动日志
|
||||
log: VLogger.Logger | t.CPtr = VLogger.get_logger()
|
||||
stdio.printf("[DBG] after get_logger log=%p\n", log)
|
||||
stdio.fflush(0)
|
||||
if log is not None:
|
||||
log.info("TransPyV 启动")
|
||||
stdio.printf("[DBG] after log.info\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
# 初始化命令行参数(Windows: GetCommandLineA, POSIX: /proc/self/cmdline)
|
||||
stdio.printf("[DBG] before _init_argv\n")
|
||||
stdio.fflush(0)
|
||||
sys._init_argv()
|
||||
stdio.printf("[DBG] after _init_argv\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
# 创建参数解析器
|
||||
stdio.printf("[DBG] before ArgumentParser\n")
|
||||
stdio.fflush(0)
|
||||
parser: argparse.ArgumentParser | t.CPtr = argparse.ArgumentParser(
|
||||
"TransPyV", "TransPyV 命令行参数解析", pool=mb)
|
||||
stdio.printf("[DBG] after ArgumentParser parser=%p\n", parser)
|
||||
stdio.fflush(0)
|
||||
|
||||
# 注册参数(与 Projectrans.py main() 一致)
|
||||
stdio.printf("[DBG] before add_argument --project\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--project", None, argparse.STRING, 0, None, False,
|
||||
argparse.STORE, "project.json 路径(默认查找当前目录)")
|
||||
stdio.printf("[DBG] after add_argument --project\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--src", None, argparse.STRING, 0, None, False,
|
||||
argparse.STORE, "源文件目录(覆盖 project.json)")
|
||||
stdio.printf("[DBG] after --src\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--temp", None, argparse.STRING, 0, None, False,
|
||||
argparse.STORE, "声明接口临时目录(覆盖 project.json)")
|
||||
stdio.printf("[DBG] after --temp\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--output", None, argparse.STRING, 0, None, False,
|
||||
argparse.STORE, "输出目录(覆盖 project.json)")
|
||||
stdio.printf("[DBG] after --output\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--phase", None, argparse.STRING, 0, None, False,
|
||||
argparse.STORE, "阶段: 1=生成声明, 2=翻译+编译, all=全部")
|
||||
stdio.printf("[DBG] after --phase\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--cc", None, argparse.STRING, 0, None, False,
|
||||
argparse.STORE, "LLVM 编译器命令(覆盖 project.json)")
|
||||
stdio.printf("[DBG] after --cc\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--clean", None, argparse.BOOL, 0, None, False,
|
||||
argparse.STORE_TRUE, "清理 output 和 temp 目录")
|
||||
stdio.printf("[DBG] after --clean\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--run", None, argparse.BOOL, 0, None, False,
|
||||
argparse.STORE_TRUE, "编译成功后立即执行生成的可执行文件")
|
||||
stdio.printf("[DBG] after --run\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--rebuild-includes", None, argparse.BOOL, 0, None, False,
|
||||
argparse.STORE_TRUE, "删除 includes.binary 预编译缓存并重新编译所有 includes")
|
||||
stdio.printf("[DBG] after --rebuild-includes\n")
|
||||
stdio.fflush(0)
|
||||
parser.add_argument("--clear-cache", None, argparse.BOOL, 0, None, False,
|
||||
argparse.STORE_TRUE, "清除 .transpyc_cache 全局缓存")
|
||||
stdio.printf("[DBG] after --clear-cache\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
# 解析命令行参数
|
||||
stdio.printf("[DBG] before parse_args\n")
|
||||
stdio.fflush(0)
|
||||
args: argparse.ParsedArgs | t.CPtr = parser.parse_args(sys._argc, sys._argv)
|
||||
stdio.printf("[DBG] after parse_args args=%p\n", args)
|
||||
stdio.fflush(0)
|
||||
if args is None:
|
||||
if log is not None:
|
||||
log.error("参数解析失败", "argparse")
|
||||
@@ -184,12 +244,21 @@ def main() -> int:
|
||||
proj_loaded: int = 0
|
||||
proj_path: str = project
|
||||
if proj_path is not None:
|
||||
stdio.printf("[DBG] before Load_project_config path=%s\n", proj_path)
|
||||
stdio.fflush(0)
|
||||
if log is not None:
|
||||
log.banner("工程配置")
|
||||
if Config.Load_project_config(proj_path) == 0:
|
||||
stdio.printf("[DBG] Load_project_config OK\n")
|
||||
stdio.fflush(0)
|
||||
proj_loaded = 1
|
||||
else:
|
||||
stdio.printf(" 警告: 无法加载 project.vpj: %s\n", proj_path)
|
||||
if log is not None:
|
||||
warn_buf: str = stdlib.malloc(256)
|
||||
if warn_buf is not None:
|
||||
viperlib.snprintf(warn_buf, 256, "无法加载 project.vpj: %s", proj_path)
|
||||
log.warning(warn_buf, "config")
|
||||
stdlib.free(warn_buf)
|
||||
else:
|
||||
# 尝试默认路径 project.vpj(当前目录和上级目录)
|
||||
proj_path = "project.vpj"
|
||||
@@ -215,18 +284,33 @@ def main() -> int:
|
||||
if proj_dir is not None:
|
||||
string.memcpy(proj_dir, proj_path, slash_pos)
|
||||
proj_dir[slash_pos] = '\0'
|
||||
stdio.printf("[DBG] before resolve_paths dir=%s\n", proj_dir)
|
||||
stdio.fflush(0)
|
||||
Config.resolve_paths(proj_dir)
|
||||
stdio.printf("[DBG] resolve_paths OK\n")
|
||||
stdio.fflush(0)
|
||||
Config.print_config()
|
||||
stdio.printf("[DBG] print_config OK\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
# === --clean: 清理 temp 和 output 目录 ===
|
||||
if _gb_clean:
|
||||
stdio.printf("\n[clean] 清理临时目录...\n")
|
||||
if log is not None:
|
||||
log.info("清理临时目录...", "clean")
|
||||
if Config.TempDir is not None:
|
||||
n: int = Utils.CleanDir(Config.TempDir)
|
||||
stdio.printf("[clean] %s: 删除 %d 个文件\n", Config.TempDir, n)
|
||||
if log is not None:
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "%s: 删除 %d 个文件", Config.TempDir, n)
|
||||
log.info(fb, "clean")
|
||||
if Config.OutputDir is not None:
|
||||
n2: int = Utils.CleanDir(Config.OutputDir)
|
||||
stdio.printf("[clean] %s: 删除 %d 个文件\n", Config.OutputDir, n2)
|
||||
if log is not None:
|
||||
fb2: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb2 is not None:
|
||||
viperlib.snprintf(fb2, 1024, "%s: 删除 %d 个文件", Config.OutputDir, n2)
|
||||
log.info(fb2, "clean")
|
||||
|
||||
# === --phase 参数控制 ===
|
||||
# phase=1: 仅 stub 分离(生成 .stub.ll/.text.ll),不编译
|
||||
@@ -241,7 +325,11 @@ def main() -> int:
|
||||
do_phase1 = 1
|
||||
if phase_mode == "2" or phase_mode == "all":
|
||||
do_phase2 = 1
|
||||
stdio.printf("[phase] 模式: %s (phase1=%d phase2=%d)\n", phase_mode, do_phase1, do_phase2)
|
||||
if log is not None:
|
||||
fb3: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb3 is not None:
|
||||
viperlib.snprintf(fb3, 1024, "模式: %s (phase1=%d phase2=%d)", phase_mode, do_phase1, do_phase2)
|
||||
log.info(fb3, "phase")
|
||||
|
||||
# === Phase1: 扫描 includes(按需翻译)===
|
||||
# 对 includes 目录中每个 .py 文件,若 stub 不存在则翻译并分离 stub
|
||||
@@ -249,10 +337,15 @@ def main() -> int:
|
||||
ph1_temp: str = Config.TempDir
|
||||
if ph1_temp is None:
|
||||
ph1_temp = "."
|
||||
stdio.printf("[DBG] before Phase1.RunPhase1 inc=%s temp=%s\n", Config.IncludesDir, ph1_temp)
|
||||
stdio.fflush(0)
|
||||
Phase1.RunPhase1(mb, Config.IncludesDir, ph1_temp, log)
|
||||
stdio.printf("[DBG] Phase1.RunPhase1 OK\n")
|
||||
stdio.fflush(0)
|
||||
# 如果仅 Phase1(不执行 Phase2),直接退出
|
||||
if do_phase2 == 0:
|
||||
stdio.printf("[phase] Phase1 完成,退出\n")
|
||||
if log is not None:
|
||||
log.info("Phase1 完成,退出", "phase")
|
||||
return 0
|
||||
|
||||
# AST 解析:如果指定了 --src 或 --project,读取文件并解析为 AST 树
|
||||
@@ -270,10 +363,14 @@ def main() -> int:
|
||||
mf_linker_out: str = Config.LinkerOutput if Config.LinkerOutput is not None else "app.exe"
|
||||
mf_includes_bin: str = Config.get_includes_binary_dir()
|
||||
|
||||
stdio.printf("[DBG] before Phase2.RunMultiFileProject src=%s temp=%s out=%s\n", Config.SourceDir, mf_temp, mf_output)
|
||||
stdio.fflush(0)
|
||||
mf_ret: int = Phase2.RunMultiFileProject(
|
||||
mb, Config.SourceDir, mf_temp, mf_output,
|
||||
mf_cc, mf_cc_flags, mf_linker, mf_linker_flags, mf_linker_out,
|
||||
mf_includes_bin, Config.IncludesDir, do_phase1, do_phase2, log, args)
|
||||
stdio.printf("[DBG] Phase2.RunMultiFileProject OK ret=%d\n", mf_ret)
|
||||
stdio.fflush(0)
|
||||
argparse.release(args)
|
||||
if log is not None:
|
||||
log.success("TransPyV 完成")
|
||||
@@ -288,7 +385,11 @@ def main() -> int:
|
||||
if path_buf is not None:
|
||||
viperlib.snprintf(path_buf, sd_len + 16, "%s/main.py", Config.SourceDir)
|
||||
src_path = path_buf
|
||||
stdio.printf("[project] 入口文件: %s\n", src_path)
|
||||
if log is not None:
|
||||
fb4: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb4 is not None:
|
||||
viperlib.snprintf(fb4, 1024, "入口文件: %s", src_path)
|
||||
log.info(fb4, "project")
|
||||
if src_path is not None:
|
||||
if log is not None:
|
||||
log.banner("AST 解析")
|
||||
@@ -296,8 +397,10 @@ def main() -> int:
|
||||
f: fileio.File | t.CPtr = fileio.File(src_path, fileio.MODE.R)
|
||||
if f.closed:
|
||||
if log is not None:
|
||||
log.error("无法打开文件", "fileio")
|
||||
stdio.printf(" 路径: %s\n", src_path)
|
||||
fb5: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb5 is not None:
|
||||
viperlib.snprintf(fb5, 1024, "无法打开文件: %s", src_path)
|
||||
log.error(fb5, "fileio")
|
||||
argparse.release(args)
|
||||
return 1
|
||||
# 分配源代码缓冲区
|
||||
@@ -313,8 +416,10 @@ def main() -> int:
|
||||
f.close()
|
||||
if bytes_read < 0:
|
||||
if log is not None:
|
||||
log.error("读取文件失败", "fileio")
|
||||
stdio.printf(" 错误码: %d\n", bytes_read)
|
||||
fb6: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb6 is not None:
|
||||
viperlib.snprintf(fb6, 1024, "读取文件失败 (错误码: %d)", bytes_read)
|
||||
log.error(fb6, "fileio")
|
||||
argparse.release(args)
|
||||
return 1
|
||||
# 添加 null 终止符,确保 strlen 和 SHA1 计算正确
|
||||
@@ -324,7 +429,10 @@ def main() -> int:
|
||||
src_buf[SRC_BUF_SIZE - 1] = 0
|
||||
if log is not None:
|
||||
log.info("文件读取完成", "fileio")
|
||||
stdio.printf("读取 %d 字节\n", bytes_read)
|
||||
fb7: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb7 is not None:
|
||||
viperlib.snprintf(fb7, 1024, "读取 %d 字节", bytes_read)
|
||||
log.info(fb7, "fileio")
|
||||
# 解析 AST(拆分为词法+语法两阶段,便于调试)
|
||||
ast._init_tables(mb)
|
||||
lx: ast.Lexer | t.CPtr = ast.new_lexer(mb)
|
||||
@@ -396,6 +504,8 @@ def main() -> int:
|
||||
# 使用 project.vpj 中的配置
|
||||
temp_dir: str = Config.TempDir if Config.TempDir is not None else "."
|
||||
output_dir: str = Config.OutputDir if Config.OutputDir is not None else "."
|
||||
# 设置全局 temp_dir(供跨模块 CDefine 查找使用)
|
||||
HandlesType.set_temp_dir(temp_dir)
|
||||
cc_cmd: str = Config.CompilerCmd if Config.CompilerCmd is not None else "llc"
|
||||
cc_flags: str = "-filetype=obj -relocation-model=pic"
|
||||
linker_cmd: str = Config.LinkerCmd if Config.LinkerCmd is not None else "clang++"
|
||||
@@ -468,7 +578,8 @@ def main() -> int:
|
||||
final_ir = combined_buf
|
||||
final_ir_len = combined_len
|
||||
else:
|
||||
stdio.printf("[stub] BuildCombinedIR 失败,使用原始 IR\n")
|
||||
if log is not None:
|
||||
log.warning("BuildCombinedIR 失败,使用原始 IR", "stub")
|
||||
stdlib.free(combined_buf)
|
||||
|
||||
br: BuildPipeline.BuildResult | t.CPtr = BuildPipeline.run_pipeline(
|
||||
@@ -479,21 +590,35 @@ def main() -> int:
|
||||
if br is not None and br.Success == 1:
|
||||
if log is not None:
|
||||
log.success("编译管线完成")
|
||||
stdio.printf("输出: %s/%s\n", output_dir, linker_output)
|
||||
fb8: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb8 is not None:
|
||||
viperlib.snprintf(fb8, 1024, "输出: %s/%s", output_dir, linker_output)
|
||||
log.info(fb8)
|
||||
# --run 模式:执行生成的可执行文件
|
||||
if args.get_bool("run"):
|
||||
exe_path: bytes = stdlib.malloc(string.strlen(output_dir) + string.strlen(linker_output) + 2)
|
||||
if exe_path is not None:
|
||||
viperlib.snprintf(exe_path, 256, "%s/%s", output_dir, linker_output)
|
||||
stdio.printf("[run] 执行: %s\n", exe_path)
|
||||
if log is not None:
|
||||
fb9: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb9 is not None:
|
||||
viperlib.snprintf(fb9, 1024, "执行: %s", exe_path)
|
||||
log.info(fb9, "run")
|
||||
r: subprocess.CompletedProcess | t.CPtr = subprocess.run(exe_path, False, False)
|
||||
if r is not None:
|
||||
stdio.printf("[run] 退出码: %d\n", r.returncode)
|
||||
if log is not None:
|
||||
fb10: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb10 is not None:
|
||||
viperlib.snprintf(fb10, 1024, "退出码: %d", r.returncode)
|
||||
log.info(fb10, "run")
|
||||
else:
|
||||
if log is not None:
|
||||
log.error("编译管线失败", "pipeline")
|
||||
if br is not None and br.ErrorMsg is not None:
|
||||
stdio.printf("[FATAL] 编译管线失败: %s\n", br.ErrorMsg)
|
||||
if br is not None and br.ErrorMsg is not None:
|
||||
fb11: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb11 is not None:
|
||||
viperlib.snprintf(fb11, 1024, "编译管线失败: %s", br.ErrorMsg)
|
||||
log.error(fb11, "FATAL")
|
||||
sys.exit(1)
|
||||
else:
|
||||
if log is not None:
|
||||
|
||||
Reference in New Issue
Block a user