将 .py 和 .pyi 后缀名改为了 .vp 和 .vpi 后缀名

This commit is contained in:
2026-07-30 16:34:50 +08:00
parent 32af3f93fa
commit d227bee139
74 changed files with 42 additions and 25 deletions

291
App/lib/core/VLogger.vp Normal file
View File

@@ -0,0 +1,291 @@
import t, c
from stdint import *
import stdio
import stdlib
import memhub
import sys
import w32.win32console as w32cmd
import w32.win32file as w32file
import w32.win32base as win32base
# ============================================================
# VLogger - 原生日志系统Windows 控制台彩色输出)
#
# 输出格式与 TPC (lib/core/VLogger.py) 对齐:
# ├ INFO: message
# ├ INFO[category]: message
# ├ WARN: message
# ├ ERROR: message
# ├ SUCCESS: message
# ├ DEBUG: message
# ╠ CRITICAL: message (红底白字,致命错误)
# ╠ CRITICAL[category]: message
#
# 分段着色:前缀符号(├/╠) 用级别色LEVEL 标签用亮色,消息用默认色
# CRITICAL 级别使用 ╠ 前缀和红底白字标签,与 TPC critical 对齐
# ============================================================
# 日志级别
class LogLevel(t.CEnum):
DEBUG = 0
INFO = 1
WARNING = 2
ERROR = 3
SUCCESS = 4
CRITICAL = 5
# Win32 控制台前景色属性
FOREGROUND_BLUE: t.CDefine = 0x0001
FOREGROUND_GREEN: t.CDefine = 0x0002
FOREGROUND_RED: t.CDefine = 0x0004
FOREGROUND_INTENSITY: t.CDefine = 0x0008
FOREGROUND_WHITE: t.CDefine = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
FOREGROUND_CYAN: t.CDefine = FOREGROUND_BLUE | FOREGROUND_GREEN
FOREGROUND_YELLOW: t.CDefine = FOREGROUND_RED | FOREGROUND_GREEN
FOREGROUND_MAGENTA: t.CDefine = FOREGROUND_RED | FOREGROUND_BLUE
# Win32 控制台背景色属性
BACKGROUND_RED: t.CDefine = 0x0040
BACKGROUND_GREEN: t.CDefine = 0x0020
BACKGROUND_BLUE: t.CDefine = 0x0010
BACKGROUND_INTENSITY: t.CDefine = 0x0080
BACKGROUND_WHITE: t.CDefine = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
@t.NoVTable
class Logger:
_level: int
_console_handle: win32base.HANDLE
_use_color: int
__mbuddy__: memhub.MemBuddy | t.CPtr
def __init__(self, level: int = 1):
self._level = level
self._console_handle = w32file.GetStdHandle(w32file.STD_OUTPUT_HANDLE)
self._use_color = 1
self.__mbuddy__ = _mbuddy
def _set_color(self, attr: WORD) -> int:
uc: int = self._use_color
if uc:
ch: win32base.HANDLE = self._console_handle
ret: int = w32cmd.SetConsoleTextAttribute(ch, attr)
return ret
return 0
def _reset_color(self) -> int:
if self._use_color:
return w32cmd.SetConsoleTextAttribute(self._console_handle, FOREGROUND_WHITE)
return 0
# ============================================================
# _log - 核心日志输出(分段着色)
#
# 格式: ├ LEVEL: msg 或 ├ LEVEL[category]: msg
# 分三段着色:
# 1. 前缀符号 ├ (sym_color)
# 2. LEVEL 标签 (level_color)
# 3. 消息内容 (默认白色)
# ============================================================
def _log(self, level: int, prefix_sym: str, level_str: str, msg: str,
sym_color: WORD, level_color: WORD,
category: str = "") -> int:
# 前缀符号着色
self._set_color(sym_color)
stdio.printf("%s ", prefix_sym)
# LEVEL 标签着色
self._set_color(level_color)
stdio.printf("%s", level_str)
self._reset_color()
# category 可选
if category is not None and category[0] != 0:
stdio.printf(" [%s]", category)
stdio.printf(": %s\n", msg)
return 0
def debug(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.DEBUG, "├", "DEBUG", msg,
FOREGROUND_INTENSITY, FOREGROUND_INTENSITY, category)
def info(self, msg: str, category: str = "") -> int:
ret: int = self._log(LogLevel.INFO, "├", "INFO", msg,
FOREGROUND_GREEN,
FOREGROUND_GREEN | FOREGROUND_INTENSITY, category)
return ret
def warning(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.WARNING, "├", "WARN", msg,
FOREGROUND_YELLOW,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
category)
def error(self, msg: str, category: str = "") -> int:
ret: int = self._log(LogLevel.ERROR, "├", "ERROR", msg,
FOREGROUND_RED,
FOREGROUND_RED | FOREGROUND_INTENSITY, category)
# 错误立即终止进程(避免错误后继续执行导致连锁崩溃)
sys.exit(1)
return ret
def success(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.SUCCESS, "├", "SUCCESS", msg,
FOREGROUND_GREEN,
FOREGROUND_GREEN | FOREGROUND_INTENSITY, category)
def critical(self, msg: str, category: str = "") -> int:
# CRITICAL 使用 ╠ 前缀(红底白字标签,对齐 TPC critical 风格)
return self._log(LogLevel.CRITICAL, "╠", "CRITICAL", msg,
FOREGROUND_RED,
BACKGROUND_RED | FOREGROUND_WHITE | FOREGROUND_INTENSITY,
category)
def set_level(self, level: int) -> int:
self._level = level
return 0
# ============================================================
# 高级日志方法
# ============================================================
def banner(self, msg: str) -> int:
"""输出分节标题(蓝色高亮,与 TPC banner 风格对齐)。"""
self._set_color(FOREGROUND_BLUE | FOREGROUND_INTENSITY)
stdio.printf("\n=== %s ===\n\n", msg)
self._reset_color()
return 0
def compile_error(self, msg: str, file: str = "", line: int = 0) -> int:
"""格式化编译错误输出(红底白字标题 + 位置 + 错误信息)。"""
self._set_color(BACKGROUND_RED | FOREGROUND_WHITE | FOREGROUND_INTENSITY)
stdio.printf(" 编译错误 ")
self._set_color(FOREGROUND_RED | FOREGROUND_INTENSITY)
stdio.printf("\n")
if file is not None:
if file[0] != 0 and line > 0:
stdio.printf(" 位置: %s:%d\n", file, line)
elif file[0] != 0:
stdio.printf(" 文件: %s\n", file)
stdio.printf(" 错误: %s\n", msg)
self._reset_color()
return 0
def compile_warning(self, msg: str, file: str = "", line: int = 0) -> int:
"""格式化编译警告输出(黄底黑字标题 + 位置 + 警告信息)。"""
self._set_color(BACKGROUND_RED | BACKGROUND_GREEN | FOREGROUND_INTENSITY)
stdio.printf(" 编译警告 ")
self._set_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY)
stdio.printf("\n")
if file is not None:
if file[0] != 0 and line > 0:
stdio.printf(" 位置: %s:%d\n", file, line)
elif file[0] != 0:
stdio.printf(" 文件: %s\n", file)
stdio.printf(" 警告: %s\n", msg)
self._reset_color()
return 0
# 全局 mbuddy 指针(由 lib.InitLib 注入)
_mbuddy: memhub.MemBuddy | t.CPtr
# 全局 logger 指针
_g_logger: Logger | t.CPtr
# 全局格式化缓冲区用于带变量的日志消息1024 字节)
_fmt_buf: t.CChar | t.CPtr
def fmt_buf() -> t.CChar | t.CPtr:
"""获取全局格式化缓冲区1024 字节)。
用法:
buf: t.CChar | t.CPtr = VLogger.fmt_buf()
if buf is not None:
viperlib.snprintf(buf, 1024, "翻译: %s (sha1=%s)", rp, sha1)
log.info(buf, "Phase1")
"""
global _fmt_buf
if _fmt_buf is None:
_fmt_buf = stdlib.malloc(1024)
return _fmt_buf
def get_logger() -> Logger | t.CPtr:
"""获取全局 logger 实例。若不存在则通过 _mbuddy 分配并初始化。"""
global _g_logger
if _g_logger is None:
if _mbuddy is None:
return None
raw: t.CVoid | t.CPtr = _mbuddy.alloc(Logger.__sizeof__())
if raw is None:
return None
_g_logger = raw
_g_logger.__before_init__()
_g_logger.__init__(LogLevel.INFO)
return _g_logger
def set_logger(logger: Logger | t.CPtr) -> int:
"""设置全局 logger 实例。"""
global _g_logger
_g_logger = logger
return 0
# ============================================================
# 模块级便捷函数(与 TPC 的 lib.core.VLogger 对齐)
#
# 调用方式: VLogger.info("msg", "category")
# 无需先 get_logger(),方便各模块直接使用
# ============================================================
def info(msg: str, category: str = "") -> int:
"""输出 INFO 级别日志。"""
log: Logger | t.CPtr = get_logger()
if log is not None:
return log.info(msg, category)
return 0
def warning(msg: str, category: str = "") -> int:
"""输出 WARN 级别日志。"""
log: Logger | t.CPtr = get_logger()
if log is not None:
return log.warning(msg, category)
return 0
def error(msg: str, category: str = "") -> int:
"""输出 ERROR 级别日志并立即终止进程。"""
log: Logger | t.CPtr = get_logger()
if log is not None:
return log.error(msg, category)
# logger 不可用时也直接退出
sys.exit(1)
return 0
def success(msg: str, category: str = "") -> int:
"""输出 SUCCESS 级别日志。"""
log: Logger | t.CPtr = get_logger()
if log is not None:
return log.success(msg, category)
return 0
def critical(msg: str, category: str = "") -> int:
"""输出 CRITICAL 级别日志(致命错误,红底白字)。"""
log: Logger | t.CPtr = get_logger()
if log is not None:
return log.critical(msg, category)
return 0
def debug(msg: str, category: str = "") -> int:
"""输出 DEBUG 级别日志。"""
log: Logger | t.CPtr = get_logger()
if log is not None:
return log.debug(msg, category)
return 0