Files
TransPyC/wiki/11-builtins.md
T

6.1 KiB
Raw Blame History

11 - 内置函数与运算符

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

内置函数

print

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)

注意:裸 sizeof() 为 TPC 支持;TransPyV 以 X.__sizeof__()/len(数组) 为主。

abs

a: t.CInt = abs(x)               # abs(x)

注意:TPC 为硬编码内建;TransPyV 按 C 库裸名调用 @abs(两者并存)。

int / float / bool / char / double(裸内建强转)

i: t.CInt = int(3.14)            # (int)3.14
f: t.CFloat = float(42)          # (float)42
b: t.CBool = 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: t.CChar→int;chr: int→t.CChar;min/max: double 参数,int/float 实参无损提升,返回按调用侧目标类型 coerce),编译器自动关联 builtins 模块,无需显式 import。

m: t.CInt = min(a, b)            # min(a, b)(builtins.vp,double 参数,返回按目标类型 coerce)
m: t.CInt = max(a, b)            # max(a, b)
c: t.CChar = chr(65)             # chr: int → t.CChar
n: t.CInt = ord('A')             # ord: t.CChar → 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)

运算符

算术运算符

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: t.CUInt32T | t.CPtr
buf[i] = value                    # buf[i] = value; (自动计算偏移)

数组下标

buf: t.CArray[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 标准库冲突。