按规范「注释只讲解作用,不掺杂历史原因,尽量英文」:把 includes 下 75 个 .vp 的中文 # 注释与三引号 docstring 改写为英文,每个注释块压到 2 行以内。 保留要点:作用、约束、危险警告(不得/必须/注意)、ABI 与类型约定(如 BYTEPTR | t.CPtr = i8** 的跨模块坍缩坑)、位宽/长度约定、fail-fast 要求、内存与句柄所有权。 未动:文件头注释(规范豁免,仍是中文)、运行时中文字符串常量(printf / fatal_error / MlirFail 等用户可见消息,属代码字面量)。 验证:独立脚本比对 HEAD 与工作区的代码骨架(剥离 # 注释与三引号 docstring 后的非空行)——75 个文件逐字节一致;行尾 CRLF/LF 未被改动;全文剩余中文仅 547 行头注释、0 条行尾注释。bootstrap 三重重编 SUCCESS;全量 77/77 顺序回归通过。
162 lines
5.3 KiB
Plaintext
162 lines
5.3 KiB
Plaintext
from stdint import *
|
|
import platmacro
|
|
import memhub
|
|
import stdio
|
|
|
|
# Windows backend dependencies
|
|
import w32.win32base
|
|
import w32.win32process
|
|
|
|
# POSIX backend dependencies
|
|
import posix
|
|
|
|
# Module global MBuddy pointer (initialized in user main), Plans to ban
|
|
_mbuddy: memhub.MemBuddy*
|
|
|
|
|
|
# =============================================================================
|
|
# C Standard Library IO Declarations
|
|
# =============================================================================
|
|
extern def fgets(buf: bytes, size: int, stream: rawptr) -> str
|
|
extern def fflush(stream: rawptr) -> int
|
|
# C standard library exit (terminates the process after flushing the buffer, cross-platform)
|
|
extern def exit(status: int)
|
|
|
|
|
|
# =============================================================================
|
|
# Platform Information
|
|
# =============================================================================
|
|
# Maximum integer value (64-bit platform ssize_t upper limit)
|
|
define maxsize = 9223372036854775807 # 2^63 - 1
|
|
|
|
|
|
def platform() -> str:
|
|
"""Returns the platform identifier string ('win32' or 'linux')."""
|
|
if platmacro.IS_WINDOWS: return "win32"
|
|
return "linux"
|
|
|
|
|
|
# =============================================================================
|
|
# Process Information
|
|
# =============================================================================
|
|
def get_pid() -> int:
|
|
"""Return the current process ID"""
|
|
if platmacro.IS_WINDOWS: return w32.win32process.GetCurrentProcessId()
|
|
return posix.getpid()
|
|
|
|
|
|
# =============================================================================
|
|
# Command Line Arguments (argv)
|
|
# =============================================================================
|
|
# global argv status (initialized on first access)
|
|
_argc: int = 0
|
|
_argv: str*
|
|
|
|
|
|
def _init_argv():
|
|
"""Initialize global argv once on first access"""
|
|
global _argc, _argv
|
|
if _argc != 0: return
|
|
# Must dispatch with if/else: the compiler only translates call-expression statements; a ternary statement is dropped (argv stays empty)
|
|
if platmacro.IS_WINDOWS:
|
|
_init_argv_win32()
|
|
else:
|
|
_init_argv_posix()
|
|
|
|
|
|
def _init_argv_win32():
|
|
"""Windows: GetCommandLineA + manual parsing (handle spaces/double quotes/backslashes)"""
|
|
global _argc, _argv
|
|
cmdline: str = w32.win32base.GetCommandLineA()
|
|
if cmdline == None:
|
|
stdio.printf("ERROR: GetCommandLineA 返回 NULL,无法获取命令行,argv 将为空\n")
|
|
return
|
|
cmdlen: sizet = len(cmdline)
|
|
if cmdlen == 0:
|
|
stdio.printf("ERROR: 命令行字符串为空,无法获取参数,argv 将为空\n")
|
|
return
|
|
# Allocate buffer for parameter strings (worst case: entire command line + argc \0s)
|
|
buf: bytes = _mbuddy.alloc(cmdlen + 1)
|
|
if buf == None: return
|
|
# Allocate pointer array for argv (worst case: each character is a parameter)
|
|
max_args: sizet = cmdlen + 1
|
|
argv_arr: str* = str*(_mbuddy.alloc(max_args * platmacro.SIZEOF_POINTER))
|
|
if argv_arr == None: return
|
|
argc: int = 0
|
|
j: sizet = 0
|
|
in_quote: bool = False
|
|
in_arg: bool = False
|
|
for i in range(cmdlen):
|
|
ch: int = cmdline[i]
|
|
if ch == 34: # Double quote
|
|
in_quote = not in_quote
|
|
if not in_arg:
|
|
argv_arr[argc] = str(buf + j)
|
|
argc += 1
|
|
in_arg = True
|
|
elif (ch == 32 or ch == 9) and not in_quote:
|
|
# Space or Tab (outside quotes): parameter delimiter
|
|
if in_arg:
|
|
buf[j] = 0
|
|
j += 1
|
|
in_arg = False
|
|
else:
|
|
if not in_arg:
|
|
argv_arr[argc] = str(buf + j)
|
|
argc += 1
|
|
in_arg = True
|
|
buf[j] = ch
|
|
j += 1
|
|
if in_arg: buf[j] = 0
|
|
_argc = argc
|
|
_argv = argv_arr
|
|
|
|
|
|
def _init_argv_posix():
|
|
"""POSIX: Read cmdline from /proc/self/cmdline (\0) separated parameters"""
|
|
global _argc, _argv
|
|
fd: int = posix.open("/proc/self/cmdline", posix.O_RDONLY, 0)
|
|
if fd < 0: return
|
|
# Read cmdline (4KB)
|
|
buf: bytes = _mbuddy.alloc(4096) # Need to verify size of buffer
|
|
if buf == None:
|
|
posix.close(fd)
|
|
return
|
|
total: ssize_t = posix.read(fd, buf, 4096)
|
|
posix.close(fd)
|
|
if total <= 0: return
|
|
# Calculate argument count (\0 delimited)
|
|
argc: int = 0
|
|
total_size: sizet = sizet(total)
|
|
for i in range(total_size):
|
|
if buf[i] == 0: argc += 1
|
|
if argc == 0: return
|
|
# Allocate pointer array for argv (argc pointers)
|
|
argv_arr: str* = str*(_mbuddy.alloc(argc * platmacro.SIZEOF_POINTER))
|
|
if argv_arr == None: return
|
|
# Populate pointer array (start address of each parameter)
|
|
argv_arr[0] = str(buf)
|
|
idx: int = 1
|
|
i = 0
|
|
while i < total_size and idx < argc:
|
|
if buf[i] == 0:
|
|
argv_arr[idx] = str(buf + i + 1)
|
|
idx += 1
|
|
i += 1
|
|
_argc = argc
|
|
_argv = argv_arr
|
|
|
|
|
|
def argc() -> int:
|
|
"""Returns the number of command line arguments. Automatically initializes on the first call."""
|
|
if _argc == 0: _init_argv()
|
|
return _argc
|
|
|
|
|
|
def argv(index: int) -> str:
|
|
"""Returns the command line argument at index `index` (starting from 0).
|
|
Automatically initializes on first call. Returns None if the index is out of range."""
|
|
if _argc == 0: _init_argv()
|
|
if index < 0 or index >= _argc: return None
|
|
return _argv[index]
|