「關於編譯器的一些想法」修訂間的差異
跳至導覽
跳至搜尋
Tankianting(討論 | 貢獻) |
Tankianting(討論 | 貢獻) |
||
(未顯示同一使用者於中間所作的 19 次修訂) | |||
行 1: | 行 1: | ||
{{Nav|程式語言、邏輯學}} | |||
==coding:style== | |||
<pre> | |||
Type Felix struct{ | |||
Str name, | |||
Int age}; | |||
Int a = 2 + 2; | |||
(Int Int -> Int) add = lmd(x, y) { | |||
if (x == 0){ | |||
return y; | |||
}else{ | |||
return x + y; | |||
} | |||
}; | |||
</pre> | |||
bool a = (20 == (lmd(int x, int y){return x * y;}(12, 6)) + 2); | |||
Felix (Str name, Int age) | |||
Int a = 2 + 2; | |||
add = l int x ,int y | |||
==迴圈== | ==迴圈== | ||
行 5: | 行 32: | ||
<math>for(idVar = initValue;~~cond(idVar); ~~idVar:=updateIdVar(i))\{ | <math> | ||
\begin{align} | |||
& for(idVar = initValue;~~cond(idVar); ~~idVar:=updateIdVar(i))\{ \\ | |||
& body... \\ | |||
\} | |||
\end{align}</math> | |||
可以轉換成 | |||
<math> | |||
\} | \begin{align} | ||
& idVar = initValue \\ | |||
& while(cond(i))\{\ \\ | |||
& body... \\ | |||
& idVar:=updateIdVar(i) \\ | |||
& \}\end{align} | |||
</math> | |||
===迴圈如何變成尾遞迴=== | |||
<math> | |||
\begin{align} | |||
& while(condFunction(x~[,y,...]))\{\\ | |||
& bodyExp_1[, bodyExp_2,...]\\ | |||
& \}\\ | |||
\end{align} | |||
</math> | |||
== | 其中 $bodyExp_n$ 可以為下列之一: | ||
* <math>oldVar_j := f(calledVar_1, [calledVar_2,...])</math> | |||
* <math>newVar_j = f(calledVar_1, [calledVar_2,...])</math> | |||
* <math>f(expression_i)</math> 當然還有部分調用、全部調用 | |||
* <math>isolatedVar</math> | |||
* <math>consonant</math> | |||
可以分析 <math>oldVar_j</math> 有哪些?<math>newVar_j</math>有哪些? | |||
設<math>oldVarSet = \{oldVar_i|i = 1,2,...,n\}</math>,<math>calledVarSet = \{calledVar_i|i = 1,2,...,n\}</math> 則 | |||
<math>iteratedVarSet = oldVarSet\cap calledVarSet</math> | |||
while 迴圈就可以變成新的遞迴函數 <math>recFunc</math>,如下: | |||
<math> | |||
\begin{align} | |||
& recFunc(all~x~from~iteratedVarSet)\{ \\ | |||
& if(condFunction)\{ \\ | |||
& newBodyExp_i \\ | |||
& return~~recFunc(...) \\ | |||
& \} \\ | |||
& \} | |||
\end{align} | |||
</math> | |||
==對字串的思考== | ==對字串的思考== | ||
字串是什麼? →其實可以表示為很大的數字。 | |||
所以,要用鏈表表示也是可行的。 | |||
==閉包== | |||
<pre> | |||
(x)=>{foo(x, free_vars)} | (x)=>{foo(x, free_vars)} | ||
</pre> | |||
轉換 | |||
<pre> | |||
ThunkAnony8964 thunkanony8964(TypeOfX x ,TypeFreeVars env){ | |||
foo(x, env[free_vars]); | foo(x, env[free_vars]); | ||
} | } | ||
行 78: | 行 116: | ||
struct ClosureTypei1r1 { | struct ClosureTypei1r1 { | ||
TypeFreeVars env, # 可以用鏈表 | TypeFreeVars env, # 可以用鏈表 | ||
* | *ThunkAnony8964 thunk, | ||
}; | }; | ||
ClosureTypei1r1 | ClosureTypei1r1 anony8964; | ||
TypeFreeVars env = free_vars; | TypeFreeVars env = free_vars; | ||
anony8964.env = env; | |||
anony8964.thunk = *thunkanony8964; | |||
</pre> | |||
執行函數 | |||
<pre> | |||
lambda(x){body}(n); | lambda(x){body}(n); | ||
</pre> | |||
改為 | 改為 | ||
<pre> | |||
anony9864.thunk(n, anony8964.env); | |||
</pre> | |||
== 如何代碼刪除不須存在的變數或函數? == | |||
* 通常來說,下列兩個條件均滿足下,只要變(函)數不出現在作用域的任何獨立表達式(須化簡)和定義式的右手邊(須化簡),則可以刪掉: | |||
*# 不可變 | |||
*# 不為外部引用 | |||
[[category:資訊]] |
於 2022年2月18日 (五) 06:09 的最新修訂
coding:style
Type Felix struct{ Str name, Int age}; Int a = 2 + 2; (Int Int -> Int) add = lmd(x, y) { if (x == 0){ return y; }else{ return x + y; } };
bool a = (20 == (lmd(int x, int y){return x * y;}(12, 6)) + 2);
Felix (Str name, Int age)
Int a = 2 + 2;
add = l int x ,int y
迴圈
for 到 while
可以轉換成
迴圈如何變成尾遞迴
其中 $bodyExp_n$ 可以為下列之一:
- 當然還有部分調用、全部調用
可以分析 有哪些?有哪些?
設, 則
while 迴圈就可以變成新的遞迴函數 ,如下:
對字串的思考
字串是什麼? →其實可以表示為很大的數字。
所以,要用鏈表表示也是可行的。
閉包
(x)=>{foo(x, free_vars)}
轉換
ThunkAnony8964 thunkanony8964(TypeOfX x ,TypeFreeVars env){ foo(x, env[free_vars]); } struct ClosureTypei1r1 { TypeFreeVars env, # 可以用鏈表 *ThunkAnony8964 thunk, }; ClosureTypei1r1 anony8964; TypeFreeVars env = free_vars; anony8964.env = env; anony8964.thunk = *thunkanony8964;
執行函數
lambda(x){body}(n);
改為
anony9864.thunk(n, anony8964.env);
如何代碼刪除不須存在的變數或函數?
- 通常來說,下列兩個條件均滿足下,只要變(函)數不出現在作用域的任何獨立表達式(須化簡)和定義式的右手邊(須化簡),則可以刪掉:
- 不可變
- 不為外部引用