将 .py 和 .pyi 后缀名改为了 .vp 和 .vpi 后缀名
This commit is contained in:
385
includes/string.vp
Normal file
385
includes/string.vp
Normal file
@@ -0,0 +1,385 @@
|
||||
from stdint import *
|
||||
import t, c
|
||||
|
||||
|
||||
# String copy function
|
||||
def strcpy(dest: str, src: str) -> str:
|
||||
if dest == None or src == None: return None
|
||||
original_dest: str = dest
|
||||
for s in src:
|
||||
dest[0] = s
|
||||
dest += 1
|
||||
dest[0] = 0
|
||||
return original_dest
|
||||
|
||||
|
||||
# String concatenate function
|
||||
def strcat(dest: str, src: str) -> str:
|
||||
if dest == None or src == None: return dest
|
||||
original_dest: str = dest
|
||||
# Find end of dest
|
||||
while dest[0] != '\0':
|
||||
dest += 1
|
||||
# Copy src
|
||||
for s in src:
|
||||
dest[0] = s
|
||||
dest += 1
|
||||
dest[0] = 0
|
||||
return original_dest
|
||||
|
||||
|
||||
# String copy function with limited length
|
||||
def strncpy(dest: str, src: str, n: t.CSizeT) -> str:
|
||||
if dest == None or src == None or n == 0: return dest
|
||||
original_dest: str = dest
|
||||
i: t.CSizeT = 0
|
||||
for s in src:
|
||||
if i >= n: break
|
||||
dest[0] = s
|
||||
dest += 1
|
||||
i += 1
|
||||
# Fill remaining space with '\0'
|
||||
while i < n:
|
||||
dest[0] = 0
|
||||
dest += 1
|
||||
i += 1
|
||||
return original_dest
|
||||
|
||||
|
||||
# String length function
|
||||
def strlen(src: str) -> t.CSizeT | t.CExport:
|
||||
length: t.CSizeT = 0
|
||||
for _ in src:
|
||||
length += 1
|
||||
return length
|
||||
|
||||
# String comparison function
|
||||
def strcmp(str1: str, str2: str) -> t.CInt:
|
||||
while str1[0] != '\0' and str2[0] != '\0':
|
||||
if str1[0] != str2[0]:
|
||||
return str1[0] - str2[0]
|
||||
str1 += 1
|
||||
str2 += 1
|
||||
return str1[0] - str2[0]
|
||||
|
||||
def samestr(str1: str, str2: str) -> bool:
|
||||
return str1 == str2
|
||||
|
||||
|
||||
# String compare function with limited length
|
||||
def strncmp(str1: str, str2: str, n: t.CSizeT) -> t.CInt:
|
||||
i: t.CSizeT = 0
|
||||
while str1[0] != '\0' and str2[0] != '\0' and i < n:
|
||||
if str1[0] != str2[0]:
|
||||
return str1[0] - str2[0]
|
||||
str1 += 1
|
||||
str2 += 1
|
||||
i += 1
|
||||
if i < n:
|
||||
return str1[0] - str2[0]
|
||||
return 0
|
||||
|
||||
|
||||
# Memory compare function
|
||||
def memcmp(ptr1: t.CVoid | t.CPtr, ptr2: t.CVoid | t.CPtr, n: t.CSizeT) -> t.CInt:
|
||||
p1: BYTEPTR = BYTEPTR(ptr1)
|
||||
p2: BYTEPTR = BYTEPTR(ptr2)
|
||||
i: t.CSizeT = 0
|
||||
while i < n:
|
||||
if p1[i] != p2[i]:
|
||||
return t.CInt(p1[i]) - t.CInt(p2[i])
|
||||
i += 1
|
||||
return 0
|
||||
|
||||
|
||||
# String find function
|
||||
def strchr(s: str, cr: t.CInt) -> str:
|
||||
while s[0] != '\0':
|
||||
if s[0] == t.CChar(cr):
|
||||
return str(s)
|
||||
s += 1
|
||||
if cr == '\0':
|
||||
return str(s)
|
||||
return None
|
||||
|
||||
# String reverse find function (find last occurrence of character)
|
||||
def strrchr(s: str, cr: t.CInt) -> str:
|
||||
last: str = None
|
||||
while s[0] != '\0':
|
||||
if s[0] == t.CChar(cr):
|
||||
last = s
|
||||
s += 1
|
||||
if cr == '\0': return s
|
||||
return last
|
||||
|
||||
|
||||
# Substring search function (find first occurrence of needle in s, return pointer to that position, or None if not found)
|
||||
def strstr(s: str, needle: str) -> str:
|
||||
if needle[0] == 0:
|
||||
return s
|
||||
needle_len: t.CSizeT = strlen(needle)
|
||||
if needle_len == 0:
|
||||
return s
|
||||
i: t.CSizeT = 0
|
||||
s_len: t.CSizeT = strlen(s)
|
||||
while i + needle_len <= s_len:
|
||||
if strncmp(s + i, needle, needle_len) == 0:
|
||||
return s + i
|
||||
i += 1
|
||||
return None
|
||||
|
||||
# String skip function
|
||||
def strspn(s: str, skip: str = " ") -> int:
|
||||
si: int = 0
|
||||
while s[si] != 0:
|
||||
found: int = 0
|
||||
sj: int = 0
|
||||
while skip[sj] != 0:
|
||||
if s[si] == skip[sj]:
|
||||
found = 1
|
||||
break
|
||||
sj += 1
|
||||
if found == 0:
|
||||
break
|
||||
si += 1
|
||||
return si
|
||||
|
||||
# Memory set function
|
||||
def memset(ptr: t.CVoid | t.CPtr, value: t.CInt, num: t.CSizeT) -> t.CVoid | t.CPtr | t.CExport:
|
||||
# Original implementation:
|
||||
# p: BYTEPTR = BYTEPTR(ptr)
|
||||
# i: t.CSizeT
|
||||
# for i in range(num):
|
||||
# p[i] = t.CUnsignedChar(value)
|
||||
if num == 0: return ptr
|
||||
c.Asm(f"""mov rdi, {c.AsmInp(ptr, t.ASM_DESCR.REG_ANY)}
|
||||
mov eax, {c.AsmInp(value, t.ASM_DESCR.REG_ANY)}
|
||||
mov rcx, {c.AsmInp(num, t.ASM_DESCR.REG_ANY)}
|
||||
rep stosb""",
|
||||
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
||||
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDI])
|
||||
return ptr
|
||||
|
||||
|
||||
def memset32(ptr: t.CVoid | t.CPtr, value: t.CUInt32T, count: t.CSizeT) -> t.CVoid | t.CPtr:
|
||||
# Original implementation:
|
||||
# p: UINT32PTR = UINT32PTR(ptr)
|
||||
# i: t.CSizeT
|
||||
# for i in range(count):
|
||||
# p[i] = value
|
||||
if count == 0: return ptr
|
||||
c.Asm(f"""mov rdi, {c.AsmInp(ptr, t.ASM_DESCR.REG_ANY)}
|
||||
mov eax, {c.AsmInp(value, t.ASM_DESCR.REG_ANY)}
|
||||
mov rcx, {c.AsmInp(count, t.ASM_DESCR.REG_ANY)}
|
||||
rep stosd""",
|
||||
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
||||
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDI])
|
||||
return ptr
|
||||
|
||||
|
||||
# Memory copy function
|
||||
def memcpy(dest: t.CVoid | t.CPtr, src: t.CVoid | t.CPtr, num: t.CSizeT) -> t.CVoid | t.CPtr | t.CExport:
|
||||
# Original implementation:
|
||||
# d: BYTEPTR = BYTEPTR(dest)
|
||||
# s: BYTEPTR = BYTEPTR(src)
|
||||
# i: t.CSizeT
|
||||
# for i in range(num):
|
||||
# d[i] = s[i]
|
||||
if num == 0: return dest
|
||||
c.Asm(f"""mov rdi, {c.AsmInp(dest, t.ASM_DESCR.REG_ANY)}
|
||||
mov rsi, {c.AsmInp(src, t.ASM_DESCR.REG_ANY)}
|
||||
mov rcx, {c.AsmInp(num, t.ASM_DESCR.REG_ANY)}
|
||||
rep movsb""",
|
||||
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RCX,
|
||||
t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_RSI])
|
||||
return dest
|
||||
|
||||
|
||||
# 内存移动函数
|
||||
def memmove(dest: t.CVoid | t.CPtr, src: t.CVoid | t.CPtr, num: t.CSizeT) -> t.CVoid | t.CPtr:
|
||||
# 原始实现:
|
||||
# d: BYTEPTR = BYTEPTR(dest)
|
||||
# s: BYTEPTR = BYTEPTR(src)
|
||||
# i: t.CSizeT
|
||||
# if d < s:
|
||||
# for i in range(num):
|
||||
# d[i] = s[i]
|
||||
# elif d > s:
|
||||
# for i in range(num, 0, -1):
|
||||
# d[i - 1] = s[i - 1]
|
||||
if num == 0: return dest
|
||||
c.Asm(f"""mov rdi, {c.AsmInp(dest, t.ASM_DESCR.REG_ANY)}
|
||||
mov rsi, {c.AsmInp(src, t.ASM_DESCR.REG_ANY)}
|
||||
mov rcx, {c.AsmInp(num, t.ASM_DESCR.REG_ANY)}
|
||||
cmp rdi, rsi
|
||||
jb 2f
|
||||
std
|
||||
add rdi, rcx
|
||||
dec rdi
|
||||
add rsi, rcx
|
||||
dec rsi
|
||||
rep movsb
|
||||
cld
|
||||
jmp 3f
|
||||
2:
|
||||
rep movsb
|
||||
3:""",
|
||||
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RCX,
|
||||
t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_RSI])
|
||||
return dest
|
||||
|
||||
|
||||
def atoi(src: str) -> t.CInt:
|
||||
num: t.CInt = 0
|
||||
sign: t.CInt = 1
|
||||
s: str = src
|
||||
if s == None: return 0
|
||||
# 跳过空白
|
||||
while s[0] == ' ' or s[0] == '\t' or s[0] == '\n' or s[0] == '\r':
|
||||
s += 1
|
||||
# 符号
|
||||
if s[0] == '-':
|
||||
sign = -1
|
||||
s += 1
|
||||
elif s[0] == '+':
|
||||
s += 1
|
||||
for ch in s:
|
||||
if ch < '0' or ch > '9': break
|
||||
digit: t.CInt = ch - '0'
|
||||
num = num * 10 + digit
|
||||
return num * sign
|
||||
|
||||
|
||||
def atoll(src: str) -> t.CInt64T:
|
||||
num: t.CInt64T = 0
|
||||
sign: t.CInt64T = 1
|
||||
s: str = src
|
||||
if s == None: return 0
|
||||
while s[0] == ' ' or s[0] == '\t' or s[0] == '\n' or s[0] == '\r':
|
||||
s += 1
|
||||
if s[0] == '-':
|
||||
sign = -1
|
||||
s += 1
|
||||
elif s[0] == '+':
|
||||
s += 1
|
||||
# 十六进制前缀 0x / 0X
|
||||
is_hex: t.CInt = 0
|
||||
if s[0] == '0' and (s[1] == 'x' or s[1] == 'X'):
|
||||
is_hex = 1
|
||||
s += 2
|
||||
if is_hex:
|
||||
for ch in s:
|
||||
d: t.CInt = 0
|
||||
if ch >= '0' and ch <= '9':
|
||||
d = ch - '0'
|
||||
elif ch >= 'a' and ch <= 'f':
|
||||
d = ch - 'a' + 10
|
||||
elif ch >= 'A' and ch <= 'F':
|
||||
d = ch - 'A' + 10
|
||||
else:
|
||||
break
|
||||
digit: t.CInt64T = t.CInt64T(d)
|
||||
num = num * 16 + digit
|
||||
else:
|
||||
for ch in s:
|
||||
if ch < '0' or ch > '9': break
|
||||
d: t.CInt = ch - '0'
|
||||
digit: t.CInt64T = t.CInt64T(d)
|
||||
num = num * 10 + digit
|
||||
return num * sign
|
||||
|
||||
|
||||
def atof(src: str) -> t.CDouble:
|
||||
s: str = src
|
||||
if s == None: return 0.0
|
||||
# 跳过空白
|
||||
while s[0] == ' ' or s[0] == '\t' or s[0] == '\n' or s[0] == '\r':
|
||||
s += 1
|
||||
# 符号
|
||||
sign: t.CDouble = 1.0
|
||||
if s[0] == '-':
|
||||
sign = -1.0
|
||||
s += 1
|
||||
elif s[0] == '+':
|
||||
s += 1
|
||||
# 整数部分
|
||||
int_part: t.CDouble = 0.0
|
||||
for ch in s:
|
||||
if ch < '0' or ch > '9': break
|
||||
d1: t.CInt = ch - '0'
|
||||
int_part = int_part * 10.0 + t.CDouble(d1)
|
||||
s += 1
|
||||
# 小数部分
|
||||
frac_part: t.CDouble = 0.0
|
||||
frac_div: t.CDouble = 1.0
|
||||
if s[0] == '.':
|
||||
s += 1
|
||||
for ch in s:
|
||||
if ch < '0' or ch > '9': break
|
||||
d2: t.CInt = ch - '0'
|
||||
frac_div = frac_div * 10.0
|
||||
frac_part = frac_part * 10.0 + t.CDouble(d2)
|
||||
s += 1
|
||||
# 指数部分
|
||||
exp: t.CInt = 0
|
||||
exp_sign: t.CInt = 1
|
||||
if s[0] == 'e' or s[0] == 'E':
|
||||
s += 1
|
||||
if s[0] == '-':
|
||||
exp_sign = -1
|
||||
s += 1
|
||||
elif s[0] == '+':
|
||||
s += 1
|
||||
for ch in s:
|
||||
if ch < '0' or ch > '9': break
|
||||
d3: t.CInt = ch - '0'
|
||||
exp = exp * 10 + d3
|
||||
s += 1
|
||||
exp = exp * exp_sign
|
||||
result: t.CDouble = sign * (int_part + frac_part / frac_div)
|
||||
# 应用指数
|
||||
if exp > 0:
|
||||
while exp > 0:
|
||||
result = result * 10.0
|
||||
exp -= 1
|
||||
elif exp < 0:
|
||||
while exp < 0:
|
||||
result = result / 10.0
|
||||
exp += 1
|
||||
return result
|
||||
|
||||
def split(s: str, delim: str, result: t.CArray[str]) -> int:
|
||||
count: int = 0
|
||||
start: str = s
|
||||
if not s or not delim or not result:
|
||||
return 0
|
||||
d: t.CChar = delim[0] # 单分隔符
|
||||
|
||||
while start[0]:
|
||||
# 跳过分隔符
|
||||
while start[0] == d: start += 1
|
||||
if not start[0]: break
|
||||
|
||||
# 记录token起始
|
||||
result[count] = start
|
||||
count += 1
|
||||
|
||||
# 找到下一个分隔符,截断
|
||||
while start[0] and start[0] != d: start += 1
|
||||
if start[0]:
|
||||
start[0] = '\0'
|
||||
start += 1
|
||||
result[count] = None # 结尾标记
|
||||
return count
|
||||
|
||||
|
||||
ascii_lowercase: str = "abcdefghijklmnopqrstuvwxyz"
|
||||
ascii_uppercase: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
ascii_letters: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
digits: str = "0123456789"
|
||||
hexdigits: str = "0123456789abcdefABCDEF"
|
||||
octdigits: str = "01234567"
|
||||
punctuation: str = "!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~"
|
||||
whitespace: str = " \t\n\r\f\v"
|
||||
printable: str = "01234567890123456789abcdefABCDEF01234567!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~ \t\n\r\f\v"
|
||||
Reference in New Issue
Block a user