Skip to content

Commit e64fae4

Browse files
committed
介紹常數折疊
1 parent 1d108b9 commit e64fae4

4 files changed

Lines changed: 75 additions & 0 deletions

File tree

book/.vitepress/config.mts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ export default defineConfig({
5959
text: "精五真言生成",
6060
link: "/零.一版/精五真言生成",
6161
},
62+
{
63+
text: "優化",
64+
link: "/零.一版/優化",
65+
},
6266
],
6367
},
6468
],
49 KB
Loading
38.4 KB
Loading

book/零.一版/優化.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
![零.一版前中後端](../image/零.一版前後端.png)
2+
3+
上圖展示了當前零.一版音界咒編譯器的各個部件。(除了目的平臺優化,在圖片中淡化)
4+
5+
本章節將介紹零.一版編譯器的最後一步:優化。完成後,全部件如下圖:
6+
7+
![零.一版前中後端](../image/零.一版前中後端.png)
8+
9+
語法樹在實質上扮演了中間碼的角色,優化器輸入語法樹,輸出還是語法樹。這樣一來,優化階段後端完全不需要改。要在命令行指定是否優化也很容易,打開優化參數時,額外應用優化器即可,其餘流程照舊。
10+
11+
## 常數折疊
12+
13+
常數折疊是零.一版音界咒唯一也究極的優化了。
14+
15+
零.一版音界咒沒有使用者輸入、沒有亂數,它的輸出自然是一成不變的,這意味著,編譯器應當有能力在編譯期就計算好輸出。
16+
17+
```音界
18+
元・甲=3*(4-2)+5 # 計算出甲 = 11
19+
元・乙=1+(1+3)*4 # 計算出乙 = 15
20+
甲*乙 # 計算出結果是 11 * 15 = 165
21+
```
22+
23+
在零.一版音界咒做到這件事相當容易,核心概念是維護一張符號表,記錄各個變數當前的值。
24+
25+
遍歷語法樹,遇到`變數宣告式`,求出要賦予給變數的值,寫入符號表;在算式中遇到變數,則去符號表中擷取當前變數值。
26+
27+
### 實作
28+
29+
```rust
30+
pub fn 常數折疊(語法樹: O語法樹) -> O語法樹 {
31+
let mut 環境 = HashMap::<String, i64>::new();
32+
33+
let mut 答案: i64 = 0;
34+
35+
forin 語法樹.句 {
36+
match 句 {
37+
O句::變數宣告(變數宣告) => {
38+
let 算式值 = 求值(&環境, &變數宣告.算式);
39+
答案 = 算式值;
40+
環境.insert(變數宣告.變數名, 算式值);
41+
}
42+
O句::算式(算式) => {
43+
答案 = 求值(&環境, &算式);
44+
}
45+
}
46+
}
47+
48+
// 優化到語法樹裡只剩一個`算式`
49+
O語法樹 {
50+
: vec![O句::算式(O算式::數字(答案))],
51+
}
52+
}
53+
54+
fn 求值(環境: &HashMap<String, i64>, 算式: &O算式) -> i64 {
55+
match 算式 {
56+
O算式::數字(數) => *數,
57+
O算式::變數(變數) => *環境.get(變數).unwrap(),
58+
O算式::二元運算(運算) => {
59+
let 左值 = 求值(環境, 運算..as_ref());
60+
let 右值 = 求值(環境, 運算..as_ref());
61+
match 運算.運算子 {
62+
O運算子::=> 左值 + 右值,
63+
O運算子::=> 左值 - 右值,
64+
O運算子::=> 左值 * 右值,
65+
O運算子::=> 左值 / 右值,
66+
}
67+
}
68+
}
69+
}
70+
71+
```

0 commit comments

Comments
 (0)