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,35 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::mem.general —— 通用分配器(GeneralPurposeAllocator)
|
|
3
|
+
#
|
|
4
|
+
# Zig 风格:显式分配/释放,带泄漏检测。
|
|
5
|
+
# 使用模块级全局变量(避免 StructNew 虚拟栈问题)。
|
|
6
|
+
# ============================================================
|
|
7
|
+
|
|
8
|
+
var gpa_alloc_count: int = 0
|
|
9
|
+
var gpa_free_count: int = 0
|
|
10
|
+
|
|
11
|
+
func gpa_reset():
|
|
12
|
+
gpa_alloc_count = 0
|
|
13
|
+
gpa_free_count = 0
|
|
14
|
+
|
|
15
|
+
func gpa_alloc(size: int) -> int:
|
|
16
|
+
gpa_alloc_count = gpa_alloc_count + 1
|
|
17
|
+
return malloc(size)
|
|
18
|
+
|
|
19
|
+
func gpa_dealloc(ptr: int):
|
|
20
|
+
if ptr == 0:
|
|
21
|
+
return
|
|
22
|
+
gpa_free_count = gpa_free_count + 1
|
|
23
|
+
c_free(ptr)
|
|
24
|
+
|
|
25
|
+
func gpa_check_leaks():
|
|
26
|
+
var leaked = gpa_alloc_count - gpa_free_count
|
|
27
|
+
if leaked > 0:
|
|
28
|
+
out("LEAK DETECTED: " + leaked + " unfreed allocations")
|
|
29
|
+
else:
|
|
30
|
+
out("No leaks detected. Allocs=" + gpa_alloc_count + " Frees=" + gpa_free_count)
|
|
31
|
+
|
|
32
|
+
func gpa_dump_stats():
|
|
33
|
+
out("=== GeneralPurposeAllocator Stats ===")
|
|
34
|
+
out("Total allocs: " + gpa_alloc_count)
|
|
35
|
+
out("Total frees: " + gpa_free_count)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::mem —— Zig 风格内存管理模块
|
|
3
|
+
#
|
|
4
|
+
# 核心理念:显式、可控、无隐式开销
|
|
5
|
+
# 所有堆内存操作都必须通过 Allocator 显式传参,无 hidden GC。
|
|
6
|
+
# ============================================================
|
|
7
|
+
|
|
8
|
+
import std.mem.allocator
|
|
9
|
+
import std.mem.arena
|
|
10
|
+
import std.mem.page
|
|
11
|
+
import std.mem.general
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::mem.page —— 页分配器(PageAllocator)
|
|
3
|
+
# ============================================================
|
|
4
|
+
|
|
5
|
+
var page_size: int = 4096
|
|
6
|
+
var page_count: int = 0
|
|
7
|
+
|
|
8
|
+
func page_alloc(size: int) -> int:
|
|
9
|
+
var alloc_size = size
|
|
10
|
+
if alloc_size % page_size != 0:
|
|
11
|
+
alloc_size = alloc_size + (page_size - (alloc_size % page_size))
|
|
12
|
+
var ptr = malloc(alloc_size)
|
|
13
|
+
page_count = page_count + 1
|
|
14
|
+
return ptr
|
|
15
|
+
|
|
16
|
+
func page_dealloc(ptr: int):
|
|
17
|
+
# 页分配器不跟踪单页释放
|
|
18
|
+
|
|
19
|
+
func page_free_all():
|
|
20
|
+
page_count = 0
|
|
21
|
+
|
|
22
|
+
func page_page_count() -> int:
|
|
23
|
+
return page_count
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::option —— Option[T] 替代实现
|
|
3
|
+
# 提供 some/none、map、unwrap_or 等常用操作
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
|
|
8
|
+
class Option:
|
|
9
|
+
is_some: bool
|
|
10
|
+
value: var
|
|
11
|
+
|
|
12
|
+
# 创建 Some 值
|
|
13
|
+
func some(v: var) -> var:
|
|
14
|
+
var o = new Option()
|
|
15
|
+
o.is_some = true
|
|
16
|
+
o.value = v
|
|
17
|
+
return o
|
|
18
|
+
|
|
19
|
+
# 创建 None 值
|
|
20
|
+
func none() -> var:
|
|
21
|
+
var o = new Option()
|
|
22
|
+
o.is_some = false
|
|
23
|
+
o.value = nil
|
|
24
|
+
return o
|
|
25
|
+
|
|
26
|
+
# 是否有值
|
|
27
|
+
func is_some() -> bool:
|
|
28
|
+
return self.is_some
|
|
29
|
+
|
|
30
|
+
# 是否为空
|
|
31
|
+
func is_none() -> bool:
|
|
32
|
+
return self.is_some == false
|
|
33
|
+
|
|
34
|
+
# 解包,失败时返回 default
|
|
35
|
+
func unwrap_or(default: var) -> var:
|
|
36
|
+
if self.is_some:
|
|
37
|
+
return self.value
|
|
38
|
+
return default
|
|
39
|
+
|
|
40
|
+
# 强制解包(失败时返回错误对象)
|
|
41
|
+
func unwrap() -> var:
|
|
42
|
+
if self.is_some:
|
|
43
|
+
return self.value
|
|
44
|
+
return error.value_error("Option.unwrap on None")
|
|
45
|
+
|
|
46
|
+
# 映射函数
|
|
47
|
+
func map(f: var) -> var:
|
|
48
|
+
if self.is_some:
|
|
49
|
+
return Option.some(f(self.value))
|
|
50
|
+
return Option.none()
|
|
51
|
+
|
|
52
|
+
# 若 Some 则执行副作用函数
|
|
53
|
+
func if_some(f: var):
|
|
54
|
+
if self.is_some:
|
|
55
|
+
f(self.value)
|
|
56
|
+
|
|
57
|
+
# 字符串表示
|
|
58
|
+
func to_string() -> var:
|
|
59
|
+
if self.is_some:
|
|
60
|
+
return "Some(" + self.value + ")"
|
|
61
|
+
return "None"
|
|
62
|
+
|
|
63
|
+
# 顶层便捷函数
|
|
64
|
+
func some(v: var) -> var:
|
|
65
|
+
return Option.some(v)
|
|
66
|
+
|
|
67
|
+
func none() -> var:
|
|
68
|
+
return Option.none()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::prelude —— 预导入模块
|
|
3
|
+
# 编译器自动注入,提供最常用的类型和函数
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
import std.collections
|
|
8
|
+
import std.string
|
|
9
|
+
import std.math
|
|
10
|
+
import std.io
|
|
11
|
+
import std.sys
|
|
12
|
+
import std.macros
|
|
13
|
+
import std.reflect
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::reflect —— 反射工具模块
|
|
3
|
+
# 提供运行时类型检查和反射能力,依赖 VM 内建函数
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
|
|
8
|
+
# ---- 类型名称常量 ----
|
|
9
|
+
class TypeNames:
|
|
10
|
+
NIL = "Nil"
|
|
11
|
+
INT = "Int"
|
|
12
|
+
FLOAT = "Float"
|
|
13
|
+
BOOL = "Bool"
|
|
14
|
+
STRING = "String"
|
|
15
|
+
ARRAY = "Array"
|
|
16
|
+
MAP = "Map"
|
|
17
|
+
INSTANCE = "Instance"
|
|
18
|
+
|
|
19
|
+
# ---- Reflect 类:反射工具 ----
|
|
20
|
+
class Reflect:
|
|
21
|
+
# 获取值的类型名称
|
|
22
|
+
func type_name(v: var) -> var:
|
|
23
|
+
return typeof(v)
|
|
24
|
+
|
|
25
|
+
# 检查值是否为 nil
|
|
26
|
+
func is_nil(v: var) -> bool:
|
|
27
|
+
return is_nil(v)
|
|
28
|
+
|
|
29
|
+
# 检查值是否为整数
|
|
30
|
+
func is_int(v: var) -> bool:
|
|
31
|
+
return is_int(v)
|
|
32
|
+
|
|
33
|
+
# 检查值是否为浮点数
|
|
34
|
+
func is_float(v: var) -> bool:
|
|
35
|
+
return is_float(v)
|
|
36
|
+
|
|
37
|
+
# 检查值是否为布尔值
|
|
38
|
+
func is_bool(v: var) -> bool:
|
|
39
|
+
return is_bool(v)
|
|
40
|
+
|
|
41
|
+
# 检查值是否为字符串
|
|
42
|
+
func is_string(v: var) -> bool:
|
|
43
|
+
return is_string(v)
|
|
44
|
+
|
|
45
|
+
# 检查值是否为数组
|
|
46
|
+
func is_array(v: var) -> bool:
|
|
47
|
+
return is_array(v)
|
|
48
|
+
|
|
49
|
+
# 检查值是否为映射(HashMap)
|
|
50
|
+
func is_map(v: var) -> bool:
|
|
51
|
+
return is_map(v)
|
|
52
|
+
|
|
53
|
+
# 检查值是否为实例对象
|
|
54
|
+
func is_instance(v: var) -> bool:
|
|
55
|
+
return is_instance(v)
|
|
56
|
+
|
|
57
|
+
# 检查值是否为数字类型(int 或 float)
|
|
58
|
+
func is_number(v: var) -> bool:
|
|
59
|
+
return is_int(v) or is_float(v)
|
|
60
|
+
|
|
61
|
+
# 检查值是否为基础类型(int/float/bool/string/nil)
|
|
62
|
+
func is_primitive(v: var) -> bool:
|
|
63
|
+
return is_nil(v) or is_int(v) or is_float(v) or is_bool(v) or is_string(v)
|
|
64
|
+
|
|
65
|
+
# 检查值是否为容器类型(array 或 map)
|
|
66
|
+
func is_container(v: var) -> bool:
|
|
67
|
+
return is_array(v) or is_map(v)
|
|
68
|
+
|
|
69
|
+
# 获取类型的字符串表示
|
|
70
|
+
func type_str(v: var) -> var:
|
|
71
|
+
var t = typeof(v)
|
|
72
|
+
if t == TypeNames.INSTANCE:
|
|
73
|
+
return "class instance"
|
|
74
|
+
if t == TypeNames.NIL:
|
|
75
|
+
return "nil"
|
|
76
|
+
if t == TypeNames.INT:
|
|
77
|
+
return "int"
|
|
78
|
+
if t == TypeNames.FLOAT:
|
|
79
|
+
return "float"
|
|
80
|
+
if t == TypeNames.BOOL:
|
|
81
|
+
return "bool"
|
|
82
|
+
if t == TypeNames.STRING:
|
|
83
|
+
return "string"
|
|
84
|
+
if t == TypeNames.ARRAY:
|
|
85
|
+
return "array"
|
|
86
|
+
if t == TypeNames.MAP:
|
|
87
|
+
return "map"
|
|
88
|
+
return t
|
|
89
|
+
|
|
90
|
+
# 断言类型,失败时返回错误
|
|
91
|
+
func assert_type(v: var, expected: var) -> var:
|
|
92
|
+
var actual = typeof(v)
|
|
93
|
+
if actual != expected:
|
|
94
|
+
return Result.err(error.type_error("expected " + expected + ", got " + actual))
|
|
95
|
+
return Result.ok(v)
|
|
96
|
+
|
|
97
|
+
# 断言非 nil
|
|
98
|
+
func assert_not_nil(v: var, msg: var) -> var:
|
|
99
|
+
if is_nil(v):
|
|
100
|
+
return Result.err(error.value_error(msg))
|
|
101
|
+
return Result.ok(v)
|
|
102
|
+
|
|
103
|
+
# ---- 顶层便捷函数 ----
|
|
104
|
+
func typeof(v: var) -> var:
|
|
105
|
+
return typeof(v)
|
|
106
|
+
|
|
107
|
+
func is_nil(v: var) -> bool:
|
|
108
|
+
return is_nil(v)
|
|
109
|
+
|
|
110
|
+
func is_int(v: var) -> bool:
|
|
111
|
+
return is_int(v)
|
|
112
|
+
|
|
113
|
+
func is_float(v: var) -> bool:
|
|
114
|
+
return is_float(v)
|
|
115
|
+
|
|
116
|
+
func is_bool(v: var) -> bool:
|
|
117
|
+
return is_bool(v)
|
|
118
|
+
|
|
119
|
+
func is_string(v: var) -> bool:
|
|
120
|
+
return is_string(v)
|
|
121
|
+
|
|
122
|
+
func is_array(v: var) -> bool:
|
|
123
|
+
return is_array(v)
|
|
124
|
+
|
|
125
|
+
func is_map(v: var) -> bool:
|
|
126
|
+
return is_map(v)
|
|
127
|
+
|
|
128
|
+
func is_instance(v: var) -> bool:
|
|
129
|
+
return is_instance(v)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::string::codec —— 编码转换
|
|
3
|
+
# 支持 hex、base64 编解码
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
import std.collections.vec
|
|
8
|
+
import std.string.util
|
|
9
|
+
|
|
10
|
+
# ---- Codec 类:编码工具(纯静态方法)----
|
|
11
|
+
class Codec:
|
|
12
|
+
|
|
13
|
+
# ========== Hex 编码 ==========
|
|
14
|
+
|
|
15
|
+
# 字节数组转十六进制字符串
|
|
16
|
+
func to_hex(bytes: var) -> var:
|
|
17
|
+
var hex_chars = "0123456789ABCDEF"
|
|
18
|
+
var result = ""
|
|
19
|
+
var i = 0
|
|
20
|
+
var n = len(bytes)
|
|
21
|
+
while i < n:
|
|
22
|
+
var byte_val = bytes[i]
|
|
23
|
+
var hi = byte_val / 16
|
|
24
|
+
var lo = byte_val % 16
|
|
25
|
+
result = result + hex_chars[hi] + hex_chars[lo]
|
|
26
|
+
i = i + 1
|
|
27
|
+
return result
|
|
28
|
+
|
|
29
|
+
# 十六进制字符串转字节数组
|
|
30
|
+
func from_hex(hex_str: var) -> var:
|
|
31
|
+
var s = StringUtil.to_upper(hex_str)
|
|
32
|
+
var s_len = len(s)
|
|
33
|
+
if s_len % 2 != 0:
|
|
34
|
+
return Result.err(error.value_error("from_hex: odd length hex string"))
|
|
35
|
+
|
|
36
|
+
var result = []
|
|
37
|
+
var i = 0
|
|
38
|
+
while i < s_len:
|
|
39
|
+
var hi = Codec._hex_digit(s[i])
|
|
40
|
+
var lo = Codec._hex_digit(s[i + 1])
|
|
41
|
+
if hi < 0:
|
|
42
|
+
return Result.err(error.value_error("from_hex: invalid hex digit '" + s[i] + "'"))
|
|
43
|
+
if lo < 0:
|
|
44
|
+
return Result.err(error.value_error("from_hex: invalid hex digit '" + s[i + 1] + "'"))
|
|
45
|
+
result = result + [(hi * 16 + lo)]
|
|
46
|
+
i = i + 2
|
|
47
|
+
return Result.ok(result)
|
|
48
|
+
|
|
49
|
+
# 十六进制数字值,-1 表示无效
|
|
50
|
+
func _hex_digit(ch: var) -> int:
|
|
51
|
+
if ch >= "0":
|
|
52
|
+
if ch <= "9":
|
|
53
|
+
return ch[0] - "0"[0]
|
|
54
|
+
if ch >= "A":
|
|
55
|
+
if ch <= "F":
|
|
56
|
+
return ch[0] - "A"[0] + 10
|
|
57
|
+
return -1
|
|
58
|
+
|
|
59
|
+
# ========== Base64 编码 ==========
|
|
60
|
+
|
|
61
|
+
# Base64 编码表
|
|
62
|
+
func _b64_table() -> var:
|
|
63
|
+
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
|
64
|
+
|
|
65
|
+
# 字节数组转 Base64 字符串
|
|
66
|
+
func to_base64(bytes: var) -> var:
|
|
67
|
+
var table = Codec._b64_table()
|
|
68
|
+
var result = ""
|
|
69
|
+
var n = len(bytes)
|
|
70
|
+
var i = 0
|
|
71
|
+
while i < n:
|
|
72
|
+
# 取出 3 个字节(或剩余)
|
|
73
|
+
var b0 = bytes[i]
|
|
74
|
+
var b1 = -1
|
|
75
|
+
var b2 = -1
|
|
76
|
+
if i + 1 < n:
|
|
77
|
+
b1 = bytes[i + 1]
|
|
78
|
+
if i + 2 < n:
|
|
79
|
+
b2 = bytes[i + 2]
|
|
80
|
+
|
|
81
|
+
# 编码为 4 个 Base64 字符
|
|
82
|
+
var c0 = (b0 / 4) % 64
|
|
83
|
+
result = result + table[c0]
|
|
84
|
+
|
|
85
|
+
if b1 >= 0:
|
|
86
|
+
var c1 = ((b0 % 4) * 16) + (b1 / 16)
|
|
87
|
+
result = result + table[c1]
|
|
88
|
+
else:
|
|
89
|
+
var c1 = (b0 % 4) * 16
|
|
90
|
+
result = result + table[c1] + "=="
|
|
91
|
+
return result
|
|
92
|
+
|
|
93
|
+
if b2 >= 0:
|
|
94
|
+
var c2 = ((b1 % 16) * 4) + (b2 / 64)
|
|
95
|
+
var c3 = b2 % 64
|
|
96
|
+
result = result + table[c2] + table[c3]
|
|
97
|
+
else:
|
|
98
|
+
var c2 = (b1 % 16) * 4
|
|
99
|
+
result = result + table[c2] + "="
|
|
100
|
+
return result
|
|
101
|
+
|
|
102
|
+
i = i + 3
|
|
103
|
+
|
|
104
|
+
return result
|
|
105
|
+
|
|
106
|
+
# Base64 字符串解码(简化版)
|
|
107
|
+
func from_base64(b64_str: var) -> var:
|
|
108
|
+
var s = b64_str
|
|
109
|
+
# 去除末尾的 =
|
|
110
|
+
var pad = 0
|
|
111
|
+
var s_len = len(s)
|
|
112
|
+
if s_len > 0:
|
|
113
|
+
if s[s_len - 1] == "=":
|
|
114
|
+
pad = pad + 1
|
|
115
|
+
if s_len > 1:
|
|
116
|
+
if s[s_len - 2] == "=":
|
|
117
|
+
pad = pad + 1
|
|
118
|
+
|
|
119
|
+
var table = Codec._b64_table()
|
|
120
|
+
var result = []
|
|
121
|
+
var i = 0
|
|
122
|
+
var byte_count = s_len - pad
|
|
123
|
+
while i < byte_count:
|
|
124
|
+
# 取 4 个 Base64 字符
|
|
125
|
+
if i + 3 >= byte_count:
|
|
126
|
+
return Result.err(error.value_error("from_base64: invalid length"))
|
|
127
|
+
var v0 = StringUtil.find(table, s[i])
|
|
128
|
+
var v1 = StringUtil.find(table, s[i + 1])
|
|
129
|
+
var v2 = StringUtil.find(table, s[i + 2])
|
|
130
|
+
var v3 = StringUtil.find(table, s[i + 3])
|
|
131
|
+
|
|
132
|
+
if v0 < 0:
|
|
133
|
+
if v1 < 0:
|
|
134
|
+
if v2 < 0:
|
|
135
|
+
if v3 < 0:
|
|
136
|
+
return Result.err(error.value_error("from_base64: invalid character"))
|
|
137
|
+
|
|
138
|
+
result = result + [(v0 * 4 + v1 / 16) % 256]
|
|
139
|
+
if s[i + 2] != "=":
|
|
140
|
+
result = result + [((v1 % 16) * 16 + v2 / 4) % 256]
|
|
141
|
+
if s[i + 3] != "=":
|
|
142
|
+
result = result + [((v2 % 4) * 64 + v3) % 256]
|
|
143
|
+
|
|
144
|
+
i = i + 4
|
|
145
|
+
|
|
146
|
+
return Result.ok(result)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Core string operations via extern C functions
|
|
2
|
+
|
|
3
|
+
extern strcmp(a: string, b: string) -> int
|
|
4
|
+
extern strlen(s: string) -> int
|
|
5
|
+
extern memcpy(dst: string, src: string, size: int) -> string
|
|
6
|
+
|
|
7
|
+
func str_eq(a: string, b: string) -> int:
|
|
8
|
+
var r: int = strcmp(a, b)
|
|
9
|
+
if r == 0:
|
|
10
|
+
return 1
|
|
11
|
+
return 0
|
|
12
|
+
|
|
13
|
+
func str_len(s: string) -> int:
|
|
14
|
+
return strlen(s)
|
|
15
|
+
|
|
16
|
+
func str_cat(a: string, b: string) -> string:
|
|
17
|
+
var la: int = strlen(a)
|
|
18
|
+
var lb: int = strlen(b)
|
|
19
|
+
var total: int = la + lb + 1
|
|
20
|
+
var result = malloc(total)
|
|
21
|
+
var _ = memcpy(result, a, la)
|
|
22
|
+
# copy second string after first
|
|
23
|
+
var _ = memcpy(result + la, b, lb)
|
|
24
|
+
# null terminate
|
|
25
|
+
(result + la + lb)[0] = 0
|
|
26
|
+
return result
|
|
27
|
+
|
|
28
|
+
extern malloc(size: int) -> string
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::string::iter —— 字符串迭代器
|
|
3
|
+
# 提供基于索引的字符迭代,避免重复 split
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
|
|
8
|
+
class StringIter:
|
|
9
|
+
source: var
|
|
10
|
+
pos: int
|
|
11
|
+
length: int
|
|
12
|
+
|
|
13
|
+
func new(s: var) -> var:
|
|
14
|
+
var it = new StringIter()
|
|
15
|
+
it.source = s
|
|
16
|
+
it.pos = 0
|
|
17
|
+
it.length = len(s)
|
|
18
|
+
return it
|
|
19
|
+
|
|
20
|
+
# 是否还有下一个字符
|
|
21
|
+
func has_next() -> bool:
|
|
22
|
+
return self.pos < self.length
|
|
23
|
+
|
|
24
|
+
# 返回下一个字符并前进;到达末尾返回 nil
|
|
25
|
+
func next() -> var:
|
|
26
|
+
if self.pos >= self.length:
|
|
27
|
+
return nil
|
|
28
|
+
var c = self.source[self.pos]
|
|
29
|
+
self.pos = self.pos + 1
|
|
30
|
+
return c
|
|
31
|
+
|
|
32
|
+
# 预读下一个字符但不前进;到达末尾返回 nil
|
|
33
|
+
func peek() -> var:
|
|
34
|
+
if self.pos >= self.length:
|
|
35
|
+
return nil
|
|
36
|
+
return self.source[self.pos]
|
|
37
|
+
|
|
38
|
+
# 回退一个字符
|
|
39
|
+
func back():
|
|
40
|
+
if self.pos > 0:
|
|
41
|
+
self.pos = self.pos - 1
|
|
42
|
+
|
|
43
|
+
# 当前索引
|
|
44
|
+
func index() -> int:
|
|
45
|
+
return self.pos
|
|
46
|
+
|
|
47
|
+
# 重置到起始位置
|
|
48
|
+
func reset():
|
|
49
|
+
self.pos = 0
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# std::string::pattern —— 模式匹配
|
|
3
|
+
# 第一版支持基本通配符 * 和 ?
|
|
4
|
+
# ============================================================
|
|
5
|
+
|
|
6
|
+
import std.error
|
|
7
|
+
import std.collections.vec
|
|
8
|
+
|
|
9
|
+
# ---- Pattern 类:通配符/正则匹配 ----
|
|
10
|
+
class Pattern:
|
|
11
|
+
raw: var # 模式字符串
|
|
12
|
+
|
|
13
|
+
func new(pattern_str: var) -> var:
|
|
14
|
+
var p = new Pattern()
|
|
15
|
+
p.raw = pattern_str
|
|
16
|
+
return p
|
|
17
|
+
|
|
18
|
+
# 测试是否匹配(通配符模式)
|
|
19
|
+
# * 匹配任意字符序列(包括空)
|
|
20
|
+
# ? 匹配单个字符
|
|
21
|
+
func test(text: var) -> bool:
|
|
22
|
+
var t_len = len(text)
|
|
23
|
+
var p_len = len(self.raw)
|
|
24
|
+
# dp[i][j] = text[0..i] 是否匹配 pattern[0..j]
|
|
25
|
+
# 简化实现:递归匹配
|
|
26
|
+
return Pattern._match(text, self.raw, 0, 0, t_len, p_len)
|
|
27
|
+
|
|
28
|
+
# 内部递归匹配
|
|
29
|
+
func _match(text: var, pat: var, ti: int, pi: int, t_len: int, p_len: int) -> bool:
|
|
30
|
+
# 到达模式末尾
|
|
31
|
+
if pi >= p_len:
|
|
32
|
+
if ti >= t_len:
|
|
33
|
+
return true
|
|
34
|
+
return false
|
|
35
|
+
|
|
36
|
+
# 处理 *
|
|
37
|
+
if pat[pi] == "*":
|
|
38
|
+
# 匹配 0 个字符
|
|
39
|
+
if Pattern._match(text, pat, ti, pi + 1, t_len, p_len):
|
|
40
|
+
return true
|
|
41
|
+
# 匹配 n 个字符
|
|
42
|
+
if ti < t_len:
|
|
43
|
+
if Pattern._match(text, pat, ti + 1, pi, t_len, p_len):
|
|
44
|
+
return true
|
|
45
|
+
return false
|
|
46
|
+
|
|
47
|
+
if ti >= t_len:
|
|
48
|
+
return false
|
|
49
|
+
|
|
50
|
+
# 处理 ?
|
|
51
|
+
if pat[pi] == "?":
|
|
52
|
+
return Pattern._match(text, pat, ti + 1, pi + 1, t_len, p_len)
|
|
53
|
+
|
|
54
|
+
# 处理普通字符
|
|
55
|
+
if text[ti] == pat[pi]:
|
|
56
|
+
return Pattern._match(text, pat, ti + 1, pi + 1, t_len, p_len)
|
|
57
|
+
|
|
58
|
+
return false
|
|
59
|
+
|
|
60
|
+
# 匹配并返回捕获组(通配符模式下无捕获组,返回单个匹配)
|
|
61
|
+
func match(text: var) -> var:
|
|
62
|
+
if self.test(text):
|
|
63
|
+
# 返回单个匹配(完整文本)
|
|
64
|
+
return Result.ok(text)
|
|
65
|
+
return Result.err(error.value_error("Pattern.match: no match"))
|
|
66
|
+
|
|
67
|
+
# 全局搜索所有匹配(通配符模式简化:返回完整匹配位置)
|
|
68
|
+
func find_all(text: var) -> var:
|
|
69
|
+
var results = new Vec()
|
|
70
|
+
var t_len = len(text)
|
|
71
|
+
var p_len = len(self.raw)
|
|
72
|
+
var start = 0
|
|
73
|
+
while start < t_len:
|
|
74
|
+
if Pattern._match(text, self.raw, start, 0, t_len, p_len):
|
|
75
|
+
# 找到匹配,计算匹配长度
|
|
76
|
+
results.push(start)
|
|
77
|
+
start = start + 1
|
|
78
|
+
return results
|
|
79
|
+
|
|
80
|
+
# 替换匹配
|
|
81
|
+
func replace(text: var, replacement: var) -> var:
|
|
82
|
+
if self.test(text) == false:
|
|
83
|
+
return text
|
|
84
|
+
return replacement
|