6.8 KiB
11 - 内置函数与运算符
Viper 支持 Python 内置函数和运算符,编译为对应的 C/LLVM 操作。
内置函数
print("Hello, World!")
print(x, y) # 多参数输出
print 目前是编译器内建:类型感知格式化(按实参静态类型选格式)+ 默认换行,最终经 printf 族输出;后续计划下降到标准库用 Viper 实现。详见 README.MD 的「print 是编译器内建」。
len
n: int = len(array) # 获取数组长度(编译时常量)
sizeof
s: size_t = sizeof(int) # sizeof(int)
s: size_t = obj.__sizeof__() # sizeof(obj)
注意:裸
sizeof()为 TPC 支持;ViperC 以X.__sizeof__()/len(数组)为主。
abs
a: int = abs(x) # abs(x)
注意:TPC 为硬编码内建;ViperC 按 C 库裸名调用
@abs(两者并存)。
int / float / bool / char / double(裸内建强转)
i: int = int(3.14) # (int)3.14
f: float = float(42) # (float)42
b: bool = bool(x) # x != 0
已实现:编译器硬编码内建强转(
bool(x)=与 0 比较得i1;int(x)=截断/零扩展/浮点转整;char(x)=i8;float/double(x)=sitofp/fpext等)。
min / max / chr / ord
实现说明:min/max/chr/ord 定义于
includes/builtins.vp(ord:char→int;chr:int→char;min/max:double参数,int/float实参无损提升,返回按调用侧目标类型 coerce),编译器自动关联 builtins 模块,无需显式 import。
m: int = min(a, b) # min(a, b)(builtins.vp,double 参数,返回按目标类型 coerce)
m: int = max(a, b) # max(a, b)
c: char = chr(65) # chr: int → char
n: int = ord('A') # ord: char → int
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)
callable / t.Callable
函数指针类型构造子:callable / Callable / t.Callable / c.Callable 在类型域等价,统一为 i8*(带签名形态额外登记返回类型)。详见 02-type-system.md 的数组指针与函数指针。
isinstance
isinstance(obj, Cls) / isinstance(obj, (A, B)):编译器内建(返回 i1)——对带 vtable 的对象做运行时子类判定,无 vtable 时回退编译期静态判定。详见 06-oop.md 的 isinstance 章节。
运算符
算术运算符
| 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__ 重载(__pow__ 属期望实现) |
-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: uint32*
buf[i] = value # buf[i] = value; (自动计算偏移)
数组下标
buf: [64]char
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: const char* = "Hello"
serial.puts(&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 标准库冲突。