vx-toolkit 1.16.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vx_toolkit/__init__.py +10 -0
- vx_toolkit/_bin/headers/collections/vec.c +8 -0
- vx_toolkit/_bin/headers/collections/vec.vxh +2 -0
- vx_toolkit/_bin/headers/cpp/greet.cpp +11 -0
- vx_toolkit/_bin/headers/cpp/greet.hpp +6 -0
- vx_toolkit/_bin/headers/cpp/greet.vxh +4 -0
- vx_toolkit/_bin/headers/fmath.c +3 -0
- vx_toolkit/_bin/headers/fmath.vxh +5 -0
- vx_toolkit/_bin/headers/math.c +6 -0
- vx_toolkit/_bin/headers/math.vxh +4 -0
- vx_toolkit/_bin/headers/sys.c +9 -0
- vx_toolkit/_bin/headers/sys.vxh +3 -0
- vx_toolkit/_bin/headers/text.c +17 -0
- vx_toolkit/_bin/headers/text.vxh +6 -0
- vx_toolkit/_bin/libvxrt.a +0 -0
- vx_toolkit/_bin/libvxtidy.dylib +0 -0
- vx_toolkit/_bin/std/README.md +90 -0
- vx_toolkit/_bin/std/bytes.vx +65 -0
- vx_toolkit/_bin/std/char.vx +83 -0
- vx_toolkit/_bin/std/collections/hashmap.vx +31 -0
- vx_toolkit/_bin/std/collections/linked_list.vx +166 -0
- vx_toolkit/_bin/std/collections/mod.vx +8 -0
- vx_toolkit/_bin/std/collections/set.vx +102 -0
- vx_toolkit/_bin/std/collections/vec.vx +40 -0
- vx_toolkit/_bin/std/conv.vx +57 -0
- vx_toolkit/_bin/std/error.vx +165 -0
- vx_toolkit/_bin/std/io/dir.vx +50 -0
- vx_toolkit/_bin/std/io/file.vx +154 -0
- vx_toolkit/_bin/std/io/mod.vx +5 -0
- vx_toolkit/_bin/std/io/path.vx +105 -0
- vx_toolkit/_bin/std/io/stream.vx +82 -0
- vx_toolkit/_bin/std/io.vx +6 -0
- vx_toolkit/_bin/std/iter.vx +67 -0
- vx_toolkit/_bin/std/macros.vx +117 -0
- vx_toolkit/_bin/std/math/math.vx +341 -0
- vx_toolkit/_bin/std/math/mod.vx +6 -0
- vx_toolkit/_bin/std/math/random.vx +104 -0
- vx_toolkit/_bin/std/mem/allocator.vx +9 -0
- vx_toolkit/_bin/std/mem/arena.vx +41 -0
- vx_toolkit/_bin/std/mem/general.vx +35 -0
- vx_toolkit/_bin/std/mem/mod.vx +11 -0
- vx_toolkit/_bin/std/mem/page.vx +23 -0
- vx_toolkit/_bin/std/mod.vx +5 -0
- vx_toolkit/_bin/std/option.vx +68 -0
- vx_toolkit/_bin/std/prelude.vx +13 -0
- vx_toolkit/_bin/std/reflect/mod.vx +129 -0
- vx_toolkit/_bin/std/string/codec.vx +146 -0
- vx_toolkit/_bin/std/string/core.vx +28 -0
- vx_toolkit/_bin/std/string/iter.vx +49 -0
- vx_toolkit/_bin/std/string/mod.vx +7 -0
- vx_toolkit/_bin/std/string/pattern.vx +84 -0
- vx_toolkit/_bin/std/string/util.vx +369 -0
- vx_toolkit/_bin/std/sys/coroutine.vx +46 -0
- vx_toolkit/_bin/std/sys/datetime.vx +160 -0
- vx_toolkit/_bin/std/sys/duration.vx +53 -0
- vx_toolkit/_bin/std/sys/env.vx +43 -0
- vx_toolkit/_bin/std/sys/mod.vx +10 -0
- vx_toolkit/_bin/std/sys/sync.vx +132 -0
- vx_toolkit/_bin/std/sys/time.vx +28 -0
- vx_toolkit/_bin/std/sys.vx +6 -0
- vx_toolkit/_bin/std/tests/run_all.vx +627 -0
- vx_toolkit/_bin/std/tests/smoke.vx +4 -0
- vx_toolkit/_bin/std/tests/test_collections.vx +42 -0
- vx_toolkit/_bin/std/tests/test_string_io.vx +202 -0
- vx_toolkit/_bin/vfmt +0 -0
- vx_toolkit/_bin/vlnk +0 -0
- vx_toolkit/_bin/vmake +0 -0
- vx_toolkit/_bin/vmake-lsp +0 -0
- vx_toolkit/_bin/vx +0 -0
- vx_toolkit/_bin/vxc +0 -0
- vx_toolkit/_bin/vxls +0 -0
- vx_toolkit/_dispatch.py +121 -0
- vx_toolkit-1.16.2.dist-info/METADATA +13 -0
- vx_toolkit-1.16.2.dist-info/RECORD +77 -0
- vx_toolkit-1.16.2.dist-info/WHEEL +4 -0
- vx_toolkit-1.16.2.dist-info/entry_points.txt +8 -0
- vx_toolkit-1.16.2.dist-info/licenses/LICENSE +198 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::collections::vec —— 动态数组 Vec
|
|
3
|
+
# Zig 风格:显式分配器传参
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.mem.allocator
|
|
7
|
+
|
|
8
|
+
# Vec 内存布局(每个槽位 8 字节,64 位平台):
|
|
9
|
+
# buf[0] = capacity (int)
|
|
10
|
+
# buf[1] = size (int)
|
|
11
|
+
# buf[2..] = 元素数组
|
|
12
|
+
|
|
13
|
+
func Vec_new(alloc: var) -> int:
|
|
14
|
+
var buf = malloc(2048)
|
|
15
|
+
buf[0] = 254
|
|
16
|
+
buf[1] = 0
|
|
17
|
+
return buf
|
|
18
|
+
|
|
19
|
+
func Vec_push(alloc: var, v: int, val: int) -> int:
|
|
20
|
+
var size = v[1]
|
|
21
|
+
var cap = v[0]
|
|
22
|
+
if size >= cap:
|
|
23
|
+
return v
|
|
24
|
+
v[size + 2] = val
|
|
25
|
+
v[1] = size + 1
|
|
26
|
+
return v
|
|
27
|
+
|
|
28
|
+
func Vec_get(v: int, index: int) -> int:
|
|
29
|
+
if index < 0 or index >= v[1]:
|
|
30
|
+
return 0
|
|
31
|
+
return v[index + 2]
|
|
32
|
+
|
|
33
|
+
func Vec_size(v: int) -> int:
|
|
34
|
+
return v[1]
|
|
35
|
+
|
|
36
|
+
func Vec_is_empty(v: int) -> bool:
|
|
37
|
+
return v[1] == 0
|
|
38
|
+
|
|
39
|
+
func Vec_dealloc(alloc: var, v: int):
|
|
40
|
+
c_free(v)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::conv —— 类型转换工具
|
|
3
|
+
# 依赖 VM 内建 int/float/str/parse_int/parse_float
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
|
|
8
|
+
class Conv:
|
|
9
|
+
# 字符串 -> 整数,失败返回 nil
|
|
10
|
+
func parse_int(s: var) -> var:
|
|
11
|
+
return parse_int(s)
|
|
12
|
+
|
|
13
|
+
# 字符串 -> 浮点数,失败返回 nil
|
|
14
|
+
func parse_float(s: var) -> var:
|
|
15
|
+
return parse_float(s)
|
|
16
|
+
|
|
17
|
+
# 任意 -> 整数(与 int 内建等价)
|
|
18
|
+
func to_int(v: var) -> int:
|
|
19
|
+
return int(v)
|
|
20
|
+
|
|
21
|
+
# 任意 -> 浮点数(与 float 内建等价)
|
|
22
|
+
func to_float(v: var) -> float:
|
|
23
|
+
return float(v)
|
|
24
|
+
|
|
25
|
+
# 任意 -> 字符串(与 str 内建等价)
|
|
26
|
+
func to_str(v: var) -> var:
|
|
27
|
+
return str(v)
|
|
28
|
+
|
|
29
|
+
# 安全解析整数,返回 Result
|
|
30
|
+
func parse_int_result(s: var) -> var:
|
|
31
|
+
var r = parse_int(s)
|
|
32
|
+
if r == nil:
|
|
33
|
+
return Result.err(error.value_error("Conv.parse_int: invalid integer '" + s + "'"))
|
|
34
|
+
return Result.ok(r)
|
|
35
|
+
|
|
36
|
+
# 安全解析浮点数,返回 Result
|
|
37
|
+
func parse_float_result(s: var) -> var:
|
|
38
|
+
var r = parse_float(s)
|
|
39
|
+
if r == nil:
|
|
40
|
+
return Result.err(error.value_error("Conv.parse_float: invalid float '" + s + "'"))
|
|
41
|
+
return Result.ok(r)
|
|
42
|
+
|
|
43
|
+
# 顶层便捷函数
|
|
44
|
+
func parse_int(s: var) -> var:
|
|
45
|
+
return Conv.parse_int(s)
|
|
46
|
+
|
|
47
|
+
func parse_float(s: var) -> var:
|
|
48
|
+
return Conv.parse_float(s)
|
|
49
|
+
|
|
50
|
+
func to_int(v: var) -> int:
|
|
51
|
+
return Conv.to_int(v)
|
|
52
|
+
|
|
53
|
+
func to_float(v: var) -> float:
|
|
54
|
+
return Conv.to_float(v)
|
|
55
|
+
|
|
56
|
+
func to_str(v: var) -> var:
|
|
57
|
+
return Conv.to_str(v)
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::error —— 错误处理模块(零依赖基础模块)
|
|
3
|
+
# ============================================================
|
|
4
|
+
|
|
5
|
+
# ---- ErrorKind 枚举:错误类别标签 ----
|
|
6
|
+
enum ErrorKind:
|
|
7
|
+
None = 0
|
|
8
|
+
IO = 1
|
|
9
|
+
Parse = 2
|
|
10
|
+
TypeError = 3
|
|
11
|
+
Runtime = 4
|
|
12
|
+
ValueError = 5
|
|
13
|
+
Index = 6
|
|
14
|
+
Key = 7
|
|
15
|
+
Math = 8
|
|
16
|
+
System = 9
|
|
17
|
+
Other = 99
|
|
18
|
+
|
|
19
|
+
# ---- Error 类:标准错误类型 ----
|
|
20
|
+
class Error:
|
|
21
|
+
kind: int # ErrorKind 值
|
|
22
|
+
msg: var # 人类可读的错误描述
|
|
23
|
+
code: int # 错误码(0 表示无错误)
|
|
24
|
+
source: var # 源文件路径(字符串或空串)
|
|
25
|
+
line: int # 出错行号(0 表示未知)
|
|
26
|
+
col: int # 出错列号(0 表示未知)
|
|
27
|
+
|
|
28
|
+
# 构造器:创建基本错误
|
|
29
|
+
func new(kind: int, msg: var) -> var:
|
|
30
|
+
var e = new Error()
|
|
31
|
+
e.kind = kind
|
|
32
|
+
e.msg = msg
|
|
33
|
+
e.code = 0
|
|
34
|
+
e.source = ""
|
|
35
|
+
e.line = 0
|
|
36
|
+
e.col = 0
|
|
37
|
+
return e
|
|
38
|
+
|
|
39
|
+
# 设置错误码,返回自身(链式调用)
|
|
40
|
+
func with_code(code: int) -> var:
|
|
41
|
+
self.code = code
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
# 设置源码位置,返回自身
|
|
45
|
+
func with_location(file: var, line: int, col: int) -> var:
|
|
46
|
+
self.source = file
|
|
47
|
+
self.line = line
|
|
48
|
+
self.col = col
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
# 是否为严重错误(code != 0)
|
|
52
|
+
func is_critical() -> bool:
|
|
53
|
+
if self.code != 0:
|
|
54
|
+
return true
|
|
55
|
+
return false
|
|
56
|
+
|
|
57
|
+
# 格式化输出
|
|
58
|
+
func to_string() -> var:
|
|
59
|
+
var result = ""
|
|
60
|
+
if self.source != "":
|
|
61
|
+
result = result + self.source
|
|
62
|
+
if self.line > 0:
|
|
63
|
+
result = result + ":" + self.line
|
|
64
|
+
if self.col > 0:
|
|
65
|
+
result = result + ":" + self.col
|
|
66
|
+
result = result + " "
|
|
67
|
+
result = result + "[" + self.kind + "] "
|
|
68
|
+
result = result + self.msg
|
|
69
|
+
if self.code != 0:
|
|
70
|
+
result = result + " (code=" + self.code + ")"
|
|
71
|
+
return result
|
|
72
|
+
|
|
73
|
+
# ---- Result 类:替代泛型枚举 Result[T, E] ----
|
|
74
|
+
# 使用方式:
|
|
75
|
+
# 成功:var r = Result.ok(value)
|
|
76
|
+
# 失败:var r = Result.err(error)
|
|
77
|
+
# 检查:if r.is_ok: ... else: ...
|
|
78
|
+
class Result:
|
|
79
|
+
is_ok: bool
|
|
80
|
+
value: var # 成功时的值
|
|
81
|
+
error: var # 失败时的 Error 对象
|
|
82
|
+
|
|
83
|
+
# 创建成功结果
|
|
84
|
+
func ok(val: var) -> var:
|
|
85
|
+
var r = new Result()
|
|
86
|
+
r.is_ok = true
|
|
87
|
+
r.value = val
|
|
88
|
+
r.error = nil
|
|
89
|
+
return r
|
|
90
|
+
|
|
91
|
+
# 创建失败结果
|
|
92
|
+
func err(err: var) -> var:
|
|
93
|
+
var r = new Result()
|
|
94
|
+
r.is_ok = false
|
|
95
|
+
r.value = nil
|
|
96
|
+
r.error = err
|
|
97
|
+
return r
|
|
98
|
+
|
|
99
|
+
# 如果成功则解包值,否则返回默认值
|
|
100
|
+
func unwrap_or(default_val: var) -> var:
|
|
101
|
+
if self.is_ok:
|
|
102
|
+
return self.value
|
|
103
|
+
return default_val
|
|
104
|
+
|
|
105
|
+
# 解包值,失败时触发错误
|
|
106
|
+
func unwrap() -> var:
|
|
107
|
+
if self.is_ok:
|
|
108
|
+
return self.value
|
|
109
|
+
return self.error
|
|
110
|
+
|
|
111
|
+
# ---- Backtrace 类:堆栈追踪 ----
|
|
112
|
+
# 第一版简化实现:存储函数名和位置的字符串列表
|
|
113
|
+
class Backtrace:
|
|
114
|
+
frames: var # 字符串列表,每帧 "func @ file:line"
|
|
115
|
+
depth: int
|
|
116
|
+
|
|
117
|
+
func new() -> var:
|
|
118
|
+
var bt = new Backtrace()
|
|
119
|
+
bt.frames = []
|
|
120
|
+
bt.depth = 0
|
|
121
|
+
return bt
|
|
122
|
+
|
|
123
|
+
# 捕获当前堆栈(VM 内建支持,当前用占位实现)
|
|
124
|
+
func capture() -> var:
|
|
125
|
+
var bt = new Backtrace()
|
|
126
|
+
bt.frames = []
|
|
127
|
+
bt.depth = 0
|
|
128
|
+
# TODO: VM 层支持 CallFrame 内省时替换为实际捕获
|
|
129
|
+
return bt
|
|
130
|
+
|
|
131
|
+
# 添加一帧
|
|
132
|
+
func push_frame(frame_info: var):
|
|
133
|
+
# frame_info 格式:"func_name @ file:line"
|
|
134
|
+
self.frames = self.frames + [frame_info]
|
|
135
|
+
self.depth = self.depth + 1
|
|
136
|
+
|
|
137
|
+
# 格式化输出堆栈
|
|
138
|
+
func render() -> var:
|
|
139
|
+
var output = "Stack trace (depth=" + self.depth + "):\n"
|
|
140
|
+
var i = 0
|
|
141
|
+
while i < self.depth:
|
|
142
|
+
output = output + " #" + i + " " + self.frames[i] + "\n"
|
|
143
|
+
i = i + 1
|
|
144
|
+
return output
|
|
145
|
+
|
|
146
|
+
# ---- 快捷构造函数 ----
|
|
147
|
+
# 创建 IO 错误
|
|
148
|
+
func io_error(msg: var) -> var:
|
|
149
|
+
return new Error(ErrorKind.IO, msg)
|
|
150
|
+
|
|
151
|
+
# 创建解析错误
|
|
152
|
+
func parse_error(msg: var) -> var:
|
|
153
|
+
return new Error(ErrorKind.Parse, msg)
|
|
154
|
+
|
|
155
|
+
# 创建类型错误
|
|
156
|
+
func type_error(msg: var) -> var:
|
|
157
|
+
return new Error(ErrorKind.TypeError, msg)
|
|
158
|
+
|
|
159
|
+
# 创建运行时错误
|
|
160
|
+
func runtime_error(msg: var) -> var:
|
|
161
|
+
return new Error(ErrorKind.Runtime, msg)
|
|
162
|
+
|
|
163
|
+
# 创建值错误
|
|
164
|
+
func value_error(msg: var) -> var:
|
|
165
|
+
return new Error(ErrorKind.ValueError, msg)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::io::dir —— 目录遍历
|
|
3
|
+
# ============================================================
|
|
4
|
+
|
|
5
|
+
import std.error
|
|
6
|
+
import std.collections.vec
|
|
7
|
+
|
|
8
|
+
# ---- Dir 类:目录操作 ----
|
|
9
|
+
class Dir:
|
|
10
|
+
path: var # 目录路径
|
|
11
|
+
|
|
12
|
+
# 打开目录
|
|
13
|
+
func open(path: var) -> var:
|
|
14
|
+
var d = new Dir()
|
|
15
|
+
d.path = path
|
|
16
|
+
return d
|
|
17
|
+
|
|
18
|
+
# 创建目录(占位:需要 VM 支持)
|
|
19
|
+
func create(path: var) -> var:
|
|
20
|
+
# TODO: 需要 VM 内建 mkdir 指令
|
|
21
|
+
return Result.err(error.io_error("Dir.create: not implemented"))
|
|
22
|
+
|
|
23
|
+
# 递归创建目录
|
|
24
|
+
func create_all(path: var) -> var:
|
|
25
|
+
return Result.err(error.io_error("Dir.create_all: not implemented"))
|
|
26
|
+
|
|
27
|
+
# 获取目录下的条目列表(占位)
|
|
28
|
+
func entries() -> var:
|
|
29
|
+
# TODO: 需要 VM 内建 read_dir 指令
|
|
30
|
+
return Result.err(error.io_error("Dir.entries: not implemented"))
|
|
31
|
+
|
|
32
|
+
# 获取目录下的文件列表
|
|
33
|
+
func files() -> var:
|
|
34
|
+
return Result.err(error.io_error("Dir.files: not implemented"))
|
|
35
|
+
|
|
36
|
+
# 获取目录下的子目录列表
|
|
37
|
+
func dirs() -> var:
|
|
38
|
+
return Result.err(error.io_error("Dir.dirs: not implemented"))
|
|
39
|
+
|
|
40
|
+
# 递归遍历(占位)
|
|
41
|
+
func walk() -> var:
|
|
42
|
+
return Result.err(error.io_error("Dir.walk: not implemented"))
|
|
43
|
+
|
|
44
|
+
# 删除目录
|
|
45
|
+
func remove(path: var) -> var:
|
|
46
|
+
return Result.err(error.io_error("Dir.remove: not implemented"))
|
|
47
|
+
|
|
48
|
+
# 递归删除
|
|
49
|
+
func remove_all(path: var) -> var:
|
|
50
|
+
return Result.err(error.io_error("Dir.remove_all: not implemented"))
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::io::file —— 文件操作
|
|
3
|
+
# 封装 VM 内建的 file_read/file_write/file_exists 指令
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
import std.collections.vec
|
|
8
|
+
import std.string.util
|
|
9
|
+
|
|
10
|
+
# ---- File 类:文件操作 ----
|
|
11
|
+
class File:
|
|
12
|
+
path: var # 文件路径
|
|
13
|
+
mode: var # 打开模式:"r" | "w" | "a"
|
|
14
|
+
open: bool # 是否已打开
|
|
15
|
+
|
|
16
|
+
# ========== 构造器/析构 ==========
|
|
17
|
+
|
|
18
|
+
func new() -> var:
|
|
19
|
+
var f = new File()
|
|
20
|
+
f.path = ""
|
|
21
|
+
f.mode = ""
|
|
22
|
+
f.open = false
|
|
23
|
+
return f
|
|
24
|
+
|
|
25
|
+
# 打开文件
|
|
26
|
+
func open(path: var, mode: var) -> var:
|
|
27
|
+
var f = new File()
|
|
28
|
+
f.path = path
|
|
29
|
+
f.mode = mode
|
|
30
|
+
f.open = true
|
|
31
|
+
return f
|
|
32
|
+
|
|
33
|
+
# 关闭文件
|
|
34
|
+
func close():
|
|
35
|
+
self.open = false
|
|
36
|
+
|
|
37
|
+
# 是否打开
|
|
38
|
+
func is_open() -> bool:
|
|
39
|
+
return self.open
|
|
40
|
+
|
|
41
|
+
# ========== 读取操作 ==========
|
|
42
|
+
|
|
43
|
+
# 读取全部文本内容
|
|
44
|
+
func read_all() -> var:
|
|
45
|
+
if self.open == false:
|
|
46
|
+
return Result.err(error.io_error("File.read_all: file not open"))
|
|
47
|
+
var content = file_read(self.path)
|
|
48
|
+
if content == nil:
|
|
49
|
+
return Result.err(error.io_error("File.read_all: failed to read '" + self.path + "'"))
|
|
50
|
+
return Result.ok(content)
|
|
51
|
+
|
|
52
|
+
# 读取全部字节(返回整数数组)
|
|
53
|
+
func read_bytes() -> var:
|
|
54
|
+
if self.open == false:
|
|
55
|
+
return Result.err(error.io_error("File.read_bytes: file not open"))
|
|
56
|
+
var content = file_read(self.path)
|
|
57
|
+
if content == nil:
|
|
58
|
+
return Result.err(error.io_error("File.read_bytes: failed to read '" + self.path + "'"))
|
|
59
|
+
# 转换为字节数组
|
|
60
|
+
var bytes = []
|
|
61
|
+
var i = 0
|
|
62
|
+
var n = len(content)
|
|
63
|
+
while i < n:
|
|
64
|
+
bytes = bytes + [content[i]]
|
|
65
|
+
i = i + 1
|
|
66
|
+
return Result.ok(bytes)
|
|
67
|
+
|
|
68
|
+
# 读取一行
|
|
69
|
+
func read_line() -> var:
|
|
70
|
+
var r = self.read_all()
|
|
71
|
+
if r.is_ok == false:
|
|
72
|
+
return r
|
|
73
|
+
var content = r.value
|
|
74
|
+
var lines = StringUtil.lines(content)
|
|
75
|
+
if lines.size() > 0:
|
|
76
|
+
return Result.ok(lines.get(0).unwrap())
|
|
77
|
+
return Result.ok("")
|
|
78
|
+
|
|
79
|
+
# 读取所有行
|
|
80
|
+
func read_lines() -> var:
|
|
81
|
+
var r = self.read_all()
|
|
82
|
+
if r.is_ok == false:
|
|
83
|
+
return r
|
|
84
|
+
return Result.ok(StringUtil.lines(r.value))
|
|
85
|
+
|
|
86
|
+
# ========== 写入操作 ==========
|
|
87
|
+
|
|
88
|
+
# 写入文本
|
|
89
|
+
func write(content: var) -> var:
|
|
90
|
+
if self.open == false:
|
|
91
|
+
return Result.err(error.io_error("File.write: file not open"))
|
|
92
|
+
file_write(self.path, content)
|
|
93
|
+
return Result.ok(nil)
|
|
94
|
+
|
|
95
|
+
# 写入字节
|
|
96
|
+
func write_bytes(data: var) -> var:
|
|
97
|
+
if self.open == false:
|
|
98
|
+
return Result.err(error.io_error("File.write_bytes: file not open"))
|
|
99
|
+
# 将字节数组转为字符串写入
|
|
100
|
+
var s = ""
|
|
101
|
+
var i = 0
|
|
102
|
+
while i < len(data):
|
|
103
|
+
s = s + data[i]
|
|
104
|
+
i = i + 1
|
|
105
|
+
file_write(self.path, s)
|
|
106
|
+
return Result.ok(nil)
|
|
107
|
+
|
|
108
|
+
# 写入行(自动添加换行)
|
|
109
|
+
func write_line(line: var) -> var:
|
|
110
|
+
if self.open == false:
|
|
111
|
+
return Result.err(error.io_error("File.write_line: file not open"))
|
|
112
|
+
file_write(self.path, line + "\n")
|
|
113
|
+
return Result.ok(nil)
|
|
114
|
+
|
|
115
|
+
# ========== 静态方法:元数据与文件操作 ==========
|
|
116
|
+
|
|
117
|
+
# 检查文件是否存在
|
|
118
|
+
func exists(path: var) -> bool:
|
|
119
|
+
return file_exists(path)
|
|
120
|
+
|
|
121
|
+
# 检查是否为目录(简化判断:无扩展名且不存在文件)
|
|
122
|
+
func is_dir(path: var) -> bool:
|
|
123
|
+
if file_exists(path):
|
|
124
|
+
return false
|
|
125
|
+
return true
|
|
126
|
+
|
|
127
|
+
# 检查是否为文件
|
|
128
|
+
func is_file(path: var) -> bool:
|
|
129
|
+
return file_exists(path)
|
|
130
|
+
|
|
131
|
+
# 删除文件
|
|
132
|
+
func delete(path: var) -> var:
|
|
133
|
+
if file_exists(path) == false:
|
|
134
|
+
return Result.err(error.io_error("File.delete: file not found: '" + path + "'"))
|
|
135
|
+
# 通过写入空内容来"删除"
|
|
136
|
+
file_write(path, "")
|
|
137
|
+
return Result.ok(nil)
|
|
138
|
+
|
|
139
|
+
# 重命名(通过读+写+删实现)
|
|
140
|
+
func rename(from: var, to: var) -> var:
|
|
141
|
+
if file_exists(from) == false:
|
|
142
|
+
return Result.err(error.io_error("File.rename: source not found: '" + from + "'"))
|
|
143
|
+
var content = file_read(from)
|
|
144
|
+
file_write(to, content)
|
|
145
|
+
file_write(from, "")
|
|
146
|
+
return Result.ok(nil)
|
|
147
|
+
|
|
148
|
+
# 复制文件
|
|
149
|
+
func copy(src: var, dst: var) -> var:
|
|
150
|
+
if file_exists(src) == false:
|
|
151
|
+
return Result.err(error.io_error("File.copy: source not found: '" + src + "'"))
|
|
152
|
+
var content = file_read(src)
|
|
153
|
+
file_write(dst, content)
|
|
154
|
+
return Result.ok(nil)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::io::path —— 路径操作
|
|
3
|
+
# 纯字符串操作,无 I/O
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
import std.string.util
|
|
8
|
+
|
|
9
|
+
# ---- Path 类:路径处理工具(静态方法)----
|
|
10
|
+
class Path:
|
|
11
|
+
|
|
12
|
+
# 连接路径片段
|
|
13
|
+
func join(base: var, child: var) -> var:
|
|
14
|
+
if base == "":
|
|
15
|
+
return child
|
|
16
|
+
if child == "":
|
|
17
|
+
return base
|
|
18
|
+
var sep = Path.separator()
|
|
19
|
+
var base_len = len(base)
|
|
20
|
+
if base[base_len - 1] == sep[0]:
|
|
21
|
+
return base + child
|
|
22
|
+
return base + sep + child
|
|
23
|
+
|
|
24
|
+
# 获取父目录
|
|
25
|
+
func parent(path: var) -> var:
|
|
26
|
+
var sep = Path.separator()
|
|
27
|
+
var idx = StringUtil.rfind(path, sep)
|
|
28
|
+
if idx < 0:
|
|
29
|
+
return Result.err(error.value_error("Path.parent: no parent for '" + path + "'"))
|
|
30
|
+
if idx == 0:
|
|
31
|
+
return Result.ok(sep)
|
|
32
|
+
return Result.ok(StringUtil.slice_to(path, idx))
|
|
33
|
+
|
|
34
|
+
# 获取文件名(含扩展名)
|
|
35
|
+
func file_name(path: var) -> var:
|
|
36
|
+
var sep = Path.separator()
|
|
37
|
+
var idx = StringUtil.rfind(path, sep)
|
|
38
|
+
if idx < 0:
|
|
39
|
+
return Result.ok(path)
|
|
40
|
+
return Result.ok(StringUtil.slice_from(path, idx + 1))
|
|
41
|
+
|
|
42
|
+
# 获取扩展名(含点号)
|
|
43
|
+
func extension(path: var) -> var:
|
|
44
|
+
var name_r = Path.file_name(path)
|
|
45
|
+
if name_r.is_ok == false:
|
|
46
|
+
return name_r
|
|
47
|
+
var name = name_r.value
|
|
48
|
+
var idx = StringUtil.rfind(name, ".")
|
|
49
|
+
if idx < 0:
|
|
50
|
+
return Result.err(error.value_error("Path.extension: no extension for '" + path + "'"))
|
|
51
|
+
return Result.ok(StringUtil.slice_from(name, idx))
|
|
52
|
+
|
|
53
|
+
# 获取不含扩展名的文件名
|
|
54
|
+
func stem(path: var) -> var:
|
|
55
|
+
var name_r = Path.file_name(path)
|
|
56
|
+
if name_r.is_ok == false:
|
|
57
|
+
return name_r
|
|
58
|
+
var name = name_r.value
|
|
59
|
+
var idx = StringUtil.rfind(name, ".")
|
|
60
|
+
if idx < 0:
|
|
61
|
+
return Result.ok(name)
|
|
62
|
+
return Result.ok(StringUtil.slice_to(name, idx))
|
|
63
|
+
|
|
64
|
+
# 是否为绝对路径
|
|
65
|
+
func is_absolute(path: var) -> bool:
|
|
66
|
+
if len(path) == 0:
|
|
67
|
+
return false
|
|
68
|
+
var sep = Path.separator()
|
|
69
|
+
if path[0] == sep[0]:
|
|
70
|
+
return true
|
|
71
|
+
# Windows 盘符路径
|
|
72
|
+
if len(path) >= 2:
|
|
73
|
+
if path[1] == ":":
|
|
74
|
+
return true
|
|
75
|
+
return false
|
|
76
|
+
|
|
77
|
+
# 规范化路径(折叠 ../ 和 ./)
|
|
78
|
+
func normalize(path: var) -> var:
|
|
79
|
+
var sep = Path.separator()
|
|
80
|
+
var parts = StringUtil.split(path, sep)
|
|
81
|
+
var result = []
|
|
82
|
+
|
|
83
|
+
var i = 0
|
|
84
|
+
while i < len(parts):
|
|
85
|
+
var part = parts[i]
|
|
86
|
+
if part == ".":
|
|
87
|
+
pass
|
|
88
|
+
elif part == "..":
|
|
89
|
+
var result_len = len(result)
|
|
90
|
+
if result_len > 0:
|
|
91
|
+
var new_result = []
|
|
92
|
+
var j = 0
|
|
93
|
+
while j < result_len - 1:
|
|
94
|
+
new_result = new_result + [result[j]]
|
|
95
|
+
j = j + 1
|
|
96
|
+
result = new_result
|
|
97
|
+
else:
|
|
98
|
+
result = result + [part]
|
|
99
|
+
i = i + 1
|
|
100
|
+
|
|
101
|
+
return StringUtil.join(result, sep)
|
|
102
|
+
|
|
103
|
+
# 路径分隔符
|
|
104
|
+
func separator() -> var:
|
|
105
|
+
return "/"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::io::stream —— 标准输入输出流
|
|
3
|
+
# ============================================================
|
|
4
|
+
|
|
5
|
+
import std.error
|
|
6
|
+
|
|
7
|
+
# ---- Stdin 类:标准输入 ----
|
|
8
|
+
# 第一版通过内建函数实现基本输入
|
|
9
|
+
class Stdin:
|
|
10
|
+
# 读取一行(从标准输入)
|
|
11
|
+
func read_line() -> var:
|
|
12
|
+
# VX 当前无内建 stdin 指令,返回占位
|
|
13
|
+
return Result.err(error.io_error("Stdin.read_line: not implemented"))
|
|
14
|
+
|
|
15
|
+
# 读取全部
|
|
16
|
+
func read_all() -> var:
|
|
17
|
+
return Result.err(error.io_error("Stdin.read_all: not implemented"))
|
|
18
|
+
|
|
19
|
+
# ---- Stdout 类:标准输出 ----
|
|
20
|
+
class Stdout:
|
|
21
|
+
# 输出文本(无换行)
|
|
22
|
+
func write(text: var):
|
|
23
|
+
out(text)
|
|
24
|
+
|
|
25
|
+
# 输出文本并换行
|
|
26
|
+
func write_line(text: var):
|
|
27
|
+
out(text + "\n")
|
|
28
|
+
|
|
29
|
+
# 格式化输出
|
|
30
|
+
func write_fmt(fmt: var, args: var):
|
|
31
|
+
var result = ""
|
|
32
|
+
var i = 0
|
|
33
|
+
var fmt_len = len(fmt)
|
|
34
|
+
var arg_idx = 0
|
|
35
|
+
var arg_len = len(args)
|
|
36
|
+
|
|
37
|
+
while i < fmt_len:
|
|
38
|
+
var ch = fmt[i]
|
|
39
|
+
if ch == "{":
|
|
40
|
+
if i + 1 < fmt_len:
|
|
41
|
+
if fmt[i + 1] == "}":
|
|
42
|
+
if arg_idx < arg_len:
|
|
43
|
+
result = result + args[arg_idx]
|
|
44
|
+
arg_idx = arg_idx + 1
|
|
45
|
+
i = i + 1
|
|
46
|
+
else:
|
|
47
|
+
result = result + ch
|
|
48
|
+
else:
|
|
49
|
+
result = result + ch
|
|
50
|
+
else:
|
|
51
|
+
result = result + ch
|
|
52
|
+
i = i + 1
|
|
53
|
+
out(result)
|
|
54
|
+
|
|
55
|
+
# 刷新缓冲区(stdout 即时刷新,此方法为空操作)
|
|
56
|
+
func flush():
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
# ---- Stderr 类:标准错误输出 ----
|
|
60
|
+
class Stderr:
|
|
61
|
+
# 输出到 stderr
|
|
62
|
+
func write(text: var):
|
|
63
|
+
# VM 当前没有 stderr 专用指令,用 stdout + 标记
|
|
64
|
+
out("[ERR] " + text)
|
|
65
|
+
|
|
66
|
+
# 输出并换行
|
|
67
|
+
func write_line(text: var):
|
|
68
|
+
out("[ERR] " + text + "\n")
|
|
69
|
+
|
|
70
|
+
# ========== 便捷函数 ==========
|
|
71
|
+
|
|
72
|
+
# 打印无换行
|
|
73
|
+
func print(text: var):
|
|
74
|
+
out(text)
|
|
75
|
+
|
|
76
|
+
# 打印并换行
|
|
77
|
+
func println(text: var):
|
|
78
|
+
out(text + "\n")
|
|
79
|
+
|
|
80
|
+
# 打印到 stderr
|
|
81
|
+
func eprint(text: var):
|
|
82
|
+
out("[ERR] " + text)
|