# 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 标准库冲突。
