5.2 KiB
5.2 KiB
11 - 内置函数与运算符
Viper 支持 Python 内置函数和运算符,编译为对应的 C/LLVM 操作。
内置函数
print("Hello, World!") # 调用 puts 或 printf
print(x, y) # 多参数输出
len
n: t.CInt = len(array) # 获取数组长度(编译时常量)
sizeof
s: t.CSizeT = sizeof(t.CInt) # sizeof(int)
s: t.CSizeT = obj.__sizeof__() # sizeof(obj)
abs
a: t.CInt = abs(x) # abs(x)
int / float / bool
i: t.CInt = int(3.14) # (int)3.14
f: t.CFloat = float(42) # (float)42
b: t.CBool = bool(x) # x != 0
min / max
m: t.CInt = min(a, b) # a < b ? a : b
m: t.CInt = max(a, b) # a > b ? a : b
chr / ord
c: t.CChar = chr(65) # 'A' (整数转字符)
n: t.CInt = ord('A') # 65 (字符转整数)
range
用于 for 循环:
for i in range(10): pass # for (int i = 0; i < 10; i++)
for i in range(5, 10): pass # for (int i = 5; i < 10; i++)
for i in range(0, 10, 2): pass # for (int i = 0; i < 10; i += 2)
运算符
算术运算符
| Viper | C 等价 | 说明 |
|---|---|---|
a + b |
a + b |
加法 |
a - b |
a - b |
减法 |
a * b |
a * b |
乘法 |
a / b |
a / b |
浮点除法 |
a // b |
a / b |
整数除法 |
a % b |
a % b |
取模 |
a ** b |
pow(a, b) |
幂运算 |
-a |
-a |
取负 |
+a |
+a |
正号 |
位运算符
| Viper | C 等价 | 说明 |
|---|---|---|
a & b |
a & b |
按位与 |
a | b |
a | b |
按位或 |
a ^ b |
a ^ b |
按位异或 |
~a |
~a |
按位取反 |
a << n |
a << n |
左移 |
a >> n |
a >> n |
右移 |
注意:
|运算符在类型注解中表示类型组合,在表达式中表示按位或。编译器根据上下文区分。
比较运算符
| Viper | C 等价 | 说明 |
|---|---|---|
a == b |
a == b |
等于 |
a != b |
a != b |
不等于 |
a < b |
a < b |
小于 |
a > b |
a > b |
大于 |
a <= b |
a <= b |
小于等于 |
a >= b |
a >= b |
大于等于 |
逻辑运算符
| Viper | C 等价 | 说明 |
|---|---|---|
a and b |
a && b |
逻辑与 |
a or b |
a || b |
逻辑或 |
not a |
!a |
逻辑非 |
增强赋值运算符
| Viper | C 等价 |
|---|---|
a += b |
a += b |
a -= b |
a -= b |
a *= b |
a *= b |
a //= b |
a /= b |
a %= b |
a %= b |
a <<= b |
a <<= b |
a >>= b |
a >>= b |
a &= b |
a &= b |
a |= b |
a |= b |
a ^= b |
a ^= b |
类型自动转换
Viper 在算术运算中自动进行类型提升:
-
整数宽度提升:较窄的整数类型自动扩展为较宽的类型
- 有符号类型使用符号扩展(
sext) - 无符号类型使用零扩展(
zext)
- 有符号类型使用符号扩展(
-
整数到浮点:整数与浮点数运算时,整数自动转换为浮点
-
浮点精度提升:
float与double运算时,float提升为double
指针算术
指针与整数的加法支持自动计算偏移:
buf: t.CUInt32T | t.CPtr
buf[i] = value # buf[i] = value; (自动计算偏移)
数组下标
buf: list[t.CChar, 64]
buf[0] = 'H' # buf[0] = 'H';
buf[i] = value # buf[i] = value;
info.fname[0] # info.fname[0] (结构体数组成员访问)
成员访问
obj.x # obj.x (直接成员)
obj.method() # obj.method() (方法调用)
ptr.x # ptr->x (指针自动解引用)
字符串字面量
字符串字面量编译为 C 字符串常量(const char*),其为只读:
serial.puts("Hello") # 传递 const char*
字符串索引
msg: t.CConst | str = "Hello"
serial.puts(c.Addr(msg[4])) # 访问 msg[4] 的地址,输出 'o'
C 标准库函数
Viper 内置支持以下 C 标准库函数的直接调用:
| 函数 | 签名 |
|---|---|
strlen(s) |
size_t strlen(const char* s) |
memset(s, c, n) |
void* memset(void* s, int c, size_t n) |
memcpy(d, s, n) |
void* memcpy(void* d, const void* s, size_t n) |
memmove(d, s, n) |
void* memmove(void* d, const void* s, size_t n) |
memcmp(a, b, n) |
int memcmp(const void* a, const void* b, size_t n) |
strcmp(a, b) |
int strcmp(const char* a, const char* b) |
strncmp(a, b, n) |
int strncmp(const char* a, const char* b, size_t n) |
strcpy(d, s) |
char* strcpy(char* d, const char* s) |
strncpy(d, s, n) |
char* strncpy(char* d, const char* s, size_t n) |
strcat(d, s) |
char* strcat(char* d, const char* s) |
puts(s) |
int puts(const char* s) |
atoi(s) |
int atoi(const char* s) |
atol(s) |
long atol(const char* s) |
abs(x) |
int abs(int x) |
labs(x) |
long labs(long x) |
部分模式比如裸机没有 libc,则不能使用这些函数,即使环境满足,Viper 标准库也可能和 C 标准库冲突。