# 11 - 内置函数与运算符 Viper 支持 Python 内置函数和运算符,编译为对应的 C/LLVM 操作。 ## 内置函数 ### print ```python print("Hello, World!") # 调用 puts 或 printf print(x, y) # 多参数输出 ``` ### len ```python n: t.CInt = len(array) # 获取数组长度(编译时常量) ``` ### sizeof ```python s: t.CSizeT = sizeof(t.CInt) # sizeof(int) s: t.CSizeT = obj.__sizeof__() # sizeof(obj) ``` ### abs ```python a: t.CInt = abs(x) # abs(x) ``` ### int / float / bool ```python 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 ```python m: t.CInt = min(a, b) # a < b ? a : b m: t.CInt = max(a, b) # a > b ? a : b ``` ### chr / ord ```python c: t.CChar = chr(65) # 'A' (整数转字符) n: t.CInt = ord('A') # 65 (字符转整数) ``` ### 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) ``` ## 运算符 ### 算术运算符 | 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 在算术运算中自动进行类型提升: 1. **整数宽度提升**:较窄的整数类型自动扩展为较宽的类型 - 有符号类型使用符号扩展(`sext`) - 无符号类型使用零扩展(`zext`) 2. **整数到浮点**:整数与浮点数运算时,整数自动转换为浮点 3. **浮点精度提升**:`float` 与 `double` 运算时,`float` 提升为 `double` ## 指针算术 指针与整数的加法支持自动计算偏移: ```python buf: t.CUInt32T | t.CPtr buf[i] = value # buf[i] = value; (自动计算偏移) ``` ## 数组下标 ```python buf: list[t.CChar, 64] 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: 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 标准库冲突。