Skip to content

Commit 2f6044d

Browse files
committed
feat: add docs for operators
1 parent c08cc41 commit 2f6044d

File tree

6 files changed

+265
-3
lines changed

6 files changed

+265
-3
lines changed

book/src/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
- [VSC Support](./tutorial/vscsupport.md)
1111
- [References](./references/README.md)
1212
- [Basic](./references/basic.md)
13+
- [Operator](./references/operator/README.md)
14+
- [Type Operator](./references/operator/tyops.md)
1315
- [Array](./references/array.md)
1416
- [closure](./references/closure.md)
1517
- [Module](./references/module.md)

book/src/dev-prepare.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ brew install llvm@18
2222

2323
如果你使用的是ubuntu,可以使用[这里](https://github.com/Pivot-Studio/setup-llvm/blob/main/scripts/install_llvm.sh)的脚本进行安装
2424

25-
# CMake
25+
## CMake
2626

2727
我们的垃圾回收模块使用了LLVM中的StackMap功能,需要使用CMake进行编译。
2828

book/src/references/basic.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,4 @@
9090

9191
例如:
9292

93-
- `let x = (false && true_with_pnanic()) || (true || !true_with_pnanic());`是一个复杂的逻辑运算
93+
- `let x = (false && true_with_panic()) || (true || !true_with_panic());`是一个复杂的逻辑运算
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Operators
2+
3+
本节收录了所有的运算符。
4+
5+
## 算术运算符
6+
7+
| 运算符 | 描述 | 示例 |
8+
| --- | --- | --- |
9+
| `+` | 加法 | `1 + 1` |
10+
| `-` | 减法 | `1 - 1` |
11+
| `*` | 乘法 | `1 * 1` |
12+
| `/` | 除法 | `1 / 1` |
13+
| `%` | 取余 | `1 % 1` |
14+
15+
## 位运算符
16+
17+
| 运算符 | 描述 | 示例 |
18+
| --- | --- | --- |
19+
| `&` || `1 & 1` |
20+
| `\|` || `1 \| 1` |
21+
| `^` | 异或 | `1 ^ 1` |
22+
| `<<` | 左移 | `1 << 1` |
23+
| `>>` | 右移 | `1 >> 1` |
24+
25+
## 逻辑运算符
26+
27+
| 运算符 | 描述 | 示例 |
28+
| --- | --- | --- |
29+
| `&&` | 逻辑与 | `true && false` |
30+
| `\|\|` | 逻辑或 | `true \|\| false` |
31+
| `!` | 逻辑非 | `!true` |
32+
33+
## 比较运算符
34+
35+
| 运算符 | 描述 | 示例 |
36+
| --- | --- | --- |
37+
| `==` | 等于 | `1 == 1` |
38+
| `!=` | 不等于 | `1 != 1` |
39+
| `>` | 大于 | `1 > 1` |
40+
| `<` | 小于 | `1 < 1` |
41+
| `>=` | 大于等于 | `1 >= 1` |
42+
| `<=` | 小于等于 | `1 <= 1` |
43+
44+
## 赋值运算符
45+
46+
| 运算符 | 描述 | 示例 |
47+
| --- | --- | --- |
48+
| `=` | 赋值 | `a = 1` |
49+
50+
## 类型运算符
51+
52+
详见[类型运算符](./tyops.md)
53+
54+
| 运算符 | 描述 | 示例 |
55+
| --- | --- | --- |
56+
| `as` | 类型转换 | `1 as i32` |
57+
| `is` | 类型判断 | `1 is i32` |
58+
| `impl` | 实现 | `a impl TestTrait?` |
59+
60+
## 其他运算符
61+
62+
| 运算符 | 描述 | 示例 |
63+
| --- | --- | --- |
64+
| `&` | 取地址 | `&a` |
65+
| `*` | 取值 | `*a` |
66+
| `()` | 函数调用 | `test_vm()` |
67+
| `[]` | 索引 | `a[1]` |
68+
| `.` | 成员访问 | `a.b` |
69+
| `:` | 类型标注 | `let a: i32 = 1` |
70+
| `;` | 语句结束 | `let a = 1;` |
71+
72+
73+
74+
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# Type Operators 类型运算符
2+
3+
本章节会对三种特殊的运算符进行介绍:`as``is``impl`
4+
5+
## `as` 类型转换运算符
6+
7+
`as` 运算符用于将一个值转换为另一个类型。
8+
9+
### 基础类型转换
10+
11+
在转换一些基础类型的时候(比如int类型之间的转换),`as` 运算符是不会失败的,例如:
12+
13+
```plang
14+
let a: i64 = 1;
15+
let b: i32 = a as i32;
16+
```
17+
18+
在这个例子中,`a` 是一个 `i64` 类型的变量,我们将其转换为 `i32` 类型的变量 `b`。这种转换永远成功,尽管可能会导致精度丢失或者损失一部分数据。
19+
20+
### 和类型转换
21+
22+
`as`也可以进行对`和类型`的转换,假设我们有如下类型:
23+
24+
```plang
25+
struct ST{};
26+
type Test<T> = T | ST;
27+
```
28+
29+
我们可以将任意一个类型用`as`转换为`Option`类型:
30+
31+
```plang
32+
let a: i64 = 1;
33+
let b = a as Test<i64>;
34+
```
35+
36+
将子类型转换为和类型是不可能失败的。如果尝试转化为一个不可能的类型,编译器会报错。
37+
38+
反之,`as`运算符也可以将和类型转换为子类型:
39+
40+
```plang
41+
let a: i64 = 1;
42+
let b = a as Test<i64>;
43+
let c: i64 = b as i64!;
44+
let d: Option<i64> = b as i64?;
45+
```
46+
47+
但是,将和类型转换为子类型可能会失败,编译器不会允许你直接使用常规的`as`语句进行转换,你必须使用`?``!`来标注转换是非强制的还是强制的。
48+
49+
如果使用`?`标注,那么`x as T?`语句会返回一个`Option<T>`类型,如果转换失败,则该返回值是`None`
50+
51+
如果使用`!`标注,那么`x as T!`语句会返回一个`T`类型,如果转换失败,则会导致运行时错误(__cast_panic)。
52+
53+
### 泛型类型转换
54+
55+
`as`运算符也可以用于泛型类型的转换:
56+
57+
```plang
58+
fn test<T>(x: T) i64 {
59+
let y = x as i64!;
60+
return x;
61+
}
62+
```
63+
64+
如果泛型类型转换失败,会导致运行时错误(__cast_panic)。这种转换是编译期进行的,没有运行时开销。
65+
66+
泛型的转换一定是强制的,需要带上`!`标注。
67+
68+
#### if let ... as ... 语法
69+
70+
`if let ... as ...` 语法可以用于安全的对泛型类型进行转换:
71+
72+
```plang
73+
fn test<T>(x: T) i64 {
74+
if let y = x as i64 {
75+
return y;
76+
}
77+
return -1;
78+
}
79+
```
80+
81+
## `is` 类型判断运算符
82+
83+
### 基础类型判断
84+
85+
`is` 运算符用于判断一个值是否是某个类型。例如:
86+
87+
```plang
88+
let a: i64 = 1;
89+
let b = a is i64;
90+
```
91+
92+
在这个例子中,`b` 的值是 `true`,因为 `a` 是一个 `i64` 类型的变量。
93+
94+
### 和类型判断
95+
96+
`is` 运算符也可以用于判断和类型:
97+
98+
```plang
99+
let a: i64 = 1;
100+
let b = a as Test<i64>;
101+
let c = b is i64;
102+
```
103+
104+
在这个例子中,`c` 的值是 `true`,因为 `b` 是一个 `i64` 类型的变量。
105+
106+
### 泛型类型判断
107+
108+
特殊的,`is` 运算符也可以用于判断泛型类型:
109+
110+
```plang
111+
fn test<T>(x: T) T {
112+
if x is i64 {
113+
doSth();
114+
}
115+
return x;
116+
}
117+
```
118+
119+
## `impl` 判断实现运算符
120+
121+
`impl` 运算符用于判断一个泛型是否实现了某个trait。例如:
122+
123+
```plang
124+
trait TestTrait {
125+
fn test();
126+
}
127+
128+
struct TestStruct{};
129+
130+
impl TestTrait for TestStruct {
131+
fn test() {
132+
println("test");
133+
}
134+
}
135+
136+
fn test<T>(x: T) T {
137+
let y = x impl TestTrait?;
138+
let z = x impl TestTrait!;
139+
z.test();
140+
return x;
141+
}
142+
143+
```
144+
145+
普通的`impl`语句必须带上`?``!`标注,否则编译器会报错。
146+
147+
对于`?`标注,如果泛型类型没有实现trait,那么语句会返回`false`,否则返回`true`
148+
149+
对于`!`标注,如果泛型类型没有实现trait,那么语句会导致运行时错误(__impl_panic)。以上方例子举例,如果`x`没有实现`TestTrait`,那么`let z = x impl TestTrait!;`会导致运行时错误。反之,如果`x`实现了`TestTrait``z`将会是是一个特殊的`T`类型,但是他的增加了实现`TestTrait`的约束,使得下一行代码可以调用`TestTrait`trait的`test`方法。请注意,虽然`z`的类型和`x`的类型都是`T`,但是他们的约束是不同的,严格来说并不是同一类型。`z`的类型`T`,也不是上下文中的`T`类型。
150+
151+
### `if let ... impl ...` 语法
152+
153+
`if let ... impl ...` 语法可以用于安全的对泛型类型进行trait实现判断:
154+
155+
```plang
156+
fn test<T>(x: T) T {
157+
if let y = x impl TestTrait {
158+
y.test();
159+
}
160+
return x;
161+
}
162+
```
163+
164+
他等同于
165+
166+
```plang
167+
fn test<T>(x: T) T {
168+
if x impl TestTrait? {
169+
let y = x impl TestTrait!;
170+
y.test();
171+
}
172+
return x;
173+
}
174+
175+
```
176+
177+
178+
179+
180+
181+
182+
183+
184+
185+
186+

src/lsp/wasm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ pub fn get_legend() -> String {
284284

285285
#[wasm_bindgen]
286286
pub fn get_completions() -> String {
287-
log::error!("get_completions {:#?}", &*COMPLETIONS.inner.borrow());
287+
log::trace!("get_completions {:#?}", &*COMPLETIONS.inner.borrow());
288288
return serde_json::to_value(COMPLETIONS.inner.borrow().clone())
289289
.unwrap()
290290
.to_string();

0 commit comments

Comments
 (0)