# 运算符

## 功能

BT 支持算术、比较、逻辑、位运算、赋值、条件和成员访问等常用运算符。复杂表达式中建议使用括号明确顺序。

## 算术运算符

| 运算符 | 说明 |
| ------ | ------ |
| `+` | 加法或字符串拼接。 |
| `-` | 减法。 |
| `*` | 乘法。 |
| `/` | 除法。 |
| `%` | 取余。 |
| `**` | 幂运算。 |

```bt
x = 12
y = 29 % 5
z = 2 ** 3
```

## 比较运算符

| 运算符 | 说明 |
| ------ | ------ |
| `>` | 大于。 |
| `<` | 小于。 |
| `>=` | 大于等于。 |
| `<=` | 小于等于。 |
| `==` | 宽松等于。 |
| `!=` | 宽松不等于。 |
| `===` | 严格等于，值和类型都一致才返回 true。 |
| `!==` | 严格不等于。 |

```bt
price = 19.99
print price >= 10
print 1 === '1'
```

## 逻辑运算符

| 运算符 | 说明 |
| ------ | ------ |
| `&&` | 左侧为真时才执行并返回右侧，否则直接返回左侧。 |
| `||` | 左侧为真时直接返回左侧，否则执行并返回右侧。 |
| `!` | 按 BT 真值规则取反。 |
| `??` | 左侧为 `null` 或 `empty` 时才执行并返回右侧，否则直接返回左侧。 |

```bt
name = input_name ?? '游客'
count = total || 0
user && login(user)
```

## 位运算符

| 运算符 | 说明 |
| ------ | ------ |
| `&` | 按位与，对两个数的二进制表示进行逐位比较，如果两个相应的位都为1，则该位的结果为1，否则为0 |
| `|` | 按位或，对两个数的二进制表示进行逐位比较，如果两个相应的位中至少有一个为1，则该位的结果为1，否则为0 |
| `^` | 按位异或，对两个数的二进制表示进行逐位比较，如果两个相应的位不同，则该位的结果为1，否则为0|
| `~` | 按位取反，对一个数的二进制表示进行逐位取反，即0变为1，1变为0 |
| `<<` | 左移，将一个数的各二进制位全部左移若干位，由符号位（最左边的位）的空位则以0来填充 |
| `>>` | 右移，将一个数的各二进制位全部右移若干位，正数左补0，负数左补1，右边丢弃 |

```bt
x = 20
y = x | 2
z = y >> 2
n = ~0
```

## 赋值运算符

| 运算符 | 说明 |
| ------ | ------ |
| `=` | 赋值，返回右侧表达式的值。 |
| `+=` | 加后赋值。 |
| `-=` | 减后赋值。 |
| `*=` | 乘后赋值。 |
| `/=` | 除后赋值。 |
| `%=` | 取余后赋值。 |
| `<<=` | 左移后赋值。 |
| `>>=` | 右移后赋值。 |
| `&=` | 按位与后赋值。 |
| `^=` | 按位异或后赋值。 |
| `|=` | 按位或后赋值。 |

```bt
x = 20
x += 10
x %= 3
```

## 自增自减

```bt
i++
i--
++i
--i
```

## 条件运算符

`? :` 根据条件返回两个表达式之一。省略 `:` 右侧时，条件不成立返回 `empty`。

```bt
x = 10
y = x == 10 ? 1 : 2
z = x == 9 ? 7
```

## 成员与调用

| 运算符 | 说明 |
| ------ | ------ |
| `()` | 改变运算顺序或调用函数。 |
| `[]` | 访问数组下标、字符串字符或对象动态字段。 |
| `.` | 访问对象字段或原型方法。 |

```bt
print ['hello'][0].to_uppercase()
```

## 注意事项

- `&&`、`||` 和 `??` 都是短路求值，左侧已经能决定结果时，右侧函数调用、字段访问或其他表达式不会执行。
- `??` 只处理 `null` 和 `empty`，不会把 `0`、`false`、空字符串当成缺失值。
- `||` 使用 BT 真值规则，`null`、`empty`、`0`、`false`、空字符串、空数组和空对象都视为假。
