Files
2026-10-13 15:36:42 +08:00

6.8 KiB
Raw Permalink Blame History

11 - 内置函数与运算符

Viper 支持 Python 内置函数和运算符,编译为对应的 C/LLVM 操作。

内置函数

print

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 在算术运算中自动进行类型提升:

  1. 整数宽度提升:较窄的整数类型自动扩展为较宽的类型

    • 有符号类型使用符号扩展(sext)
    • 无符号类型使用零扩展(zext)
  2. 整数到浮点:整数与浮点数运算时,整数自动转换为浮点

  3. 浮点精度提升: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 标准库冲突。