修正了一些错误

This commit is contained in:
2026-07-26 20:32:26 +08:00
parent ca7c2120b8
commit 1837339f69
203 changed files with 374300 additions and 2638 deletions

View File

@@ -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: