Files
Viper_VRTE/string.vp
T

418 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from stdint import *
import t, c
import stdio
# 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 concatenate function with limited length
def strncat(dest: str, src: str, n: t.CSizeT) -> str:
if dest == None or src == None or n == 0: return dest
original_dest: str = dest
# Find end of dest
while dest[0] != '\0':
dest += 1
# Copy up to n chars from src
i: t.CSizeT = 0
for s in src:
if i >= n: break
dest[0] = s
dest += 1
i += 1
dest[0] = 0
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 strcmp(str1, str2) == 0
# 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 atof_out(src: str, out: t.CDouble | t.CPtr) -> t.CInt:
"""atof 结果写入 out[0](输出参数方式,避免跨模块 double 返回值传递 bug)
返回值仅表示成功与否(1=成功,0=失败),结果值通过 out 指针传递,
不依赖 double 返回值的跨模块传递。
"""
if out is None:
return 0
v: t.CDouble = atof(src)
out[0] = v
return 1
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 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\f\v"