# 11 - 内置函数与运算符 Viper 支持 Python 内置函数和运算符,编译为对应的 C/LLVM 操作。 ## 内置函数 ### print ```python print("Hello, World!") print(x, y) # 多参数输出 ``` `print` 目前是**编译器内建**:类型感知格式化(按实参静态类型选格式)+ 默认换行,最终经 `printf` 族输出;**后续计划下降到标准库**用 Viper 实现。详见 [README.MD 的「print 是编译器内建」](README.MD#print-是编译器内建)。 ### len ```python n: int = len(array) # 获取数组长度(编译时常量) ``` ### sizeof ```python s: size_t = sizeof(int) # sizeof(int) s: size_t = obj.__sizeof__() # sizeof(obj) ``` > **注意**:裸 `sizeof()` 为 TPC 支持;ViperC 以 `X.__sizeof__()`/`len(数组)` 为主。 ### abs ```python a: int = abs(x) # abs(x) ``` > **注意**:TPC 为硬编码内建;ViperC 按 C 库裸名调用 `@abs`(两者并存)。 ### int / float / bool / char / double(裸内建强转) ```python 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。 ```python 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` 循环: ```python 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 的数组指针与函数指针](02-type-system.md#数组指针与函数指针)。 ### isinstance `isinstance(obj, Cls)` / `isinstance(obj, (A, B))`:编译器内建(返回 `i1`)——对带 vtable 的对象做**运行时子类判定**,无 vtable 时回退编译期静态判定。详见 [06-oop.md 的 isinstance 章节](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` ## 指针算术 指针与整数的加法支持自动计算偏移: ```python buf: uint32* buf[i] = value # buf[i] = value; (自动计算偏移) ``` ## 数组下标 ```python buf: [64]char buf[0] = 'H' # buf[0] = 'H'; buf[i] = value # buf[i] = value; info.fname[0] # info.fname[0] (结构体数组成员访问) ``` ## 成员访问 ```python obj.x # obj.x (直接成员) obj.method() # obj.method() (方法调用) ptr.x # ptr->x (指针自动解引用) ``` ## 字符串字面量 字符串字面量编译为 C 字符串常量(`const char*`),其为只读: ```python serial.puts("Hello") # 传递 const char* ``` ### 字符串索引 ```python 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 标准库冲突。