「PHPに変換」されるプロジェクトの部分は完全には準備ができていません。 しかし、私は今記事を書いています:
- 他に誰がプロジェクトに興味を持っているかを調べます。
- 経験豊富なphpshnikに、PHPコードを改善する方法と、正確に速度が低下するものを測定する方法を尋ねます。
habrokatの下の例と技術的な詳細。
プログラム例:
( display "Hello, world!\n")
またはより複雑:
( define (- -)
( lambda () ( display -)))
( define - ( - "!\n"))
( - )
この例では、関数は関数を返します。 PHPでは、コードは次のようになります(機能しません)。
function _($_) {
return function () {
print $_;
}
}
$_ = _ ("!\n");
$ _ ();
他の例はgithubまたはアーカイブで見ることができます 。 動作確認テスト
*少なくとも何か(例:「Hello、world」)
*再帰(階乗、フィボナッチ、アッカーマン)
*回路
*続き
すべての重要なことが機能します。 R5RS標準が完全に実装されるまで、プリミティブを作成するだけです。 そうそう、偶然に私の擬似コードはScheme R5RS言語と一致します。
私のプロジェクトでは、 Gambit Schemaコンパイラーを使用しています。 その中には、レジスタスタック仮想マシンGVM( 効率的なスキームのコンパイルのための並列仮想マシン )があります。 これは、GVMに関しては、例が次のようになります。
; +N: N
; -N: N
; : +1, +2 ..
; +1
; continuation-passing style, - +0
; , escape sequences
;
; #1
#1 0 entry-point 0 ()
; "-"
|~#-| = '#<procedure |~#-|>
-1 = +0
+1 = '"!\n"
+0 = #3
; #2
jump* 4 #2
#2 4
; . +0 #3, , +1 ()
jump$ 4 |~#-| 1
#3 4 return-point
|~#-| = +1
+0 = -1
jump* 4 #4
#4 4
jump$ 0 |~#-| 0
**** #<procedure |~#-|> =
#1 0 entry-point 1 ()
; --
close -1 = (#2 +1)
+1 = -1
jump 0 +0
;
#2 0 closure-entry-point 0 ()
; +4 , +4(1) --
+1 = +4(1)
jump* 0 #3
#3 0
jump$ 0 display 1
GVMをPHPに変換した結果:
function glo_x20hellowr () {
global $reg0, $reg1, $reg2, $reg3, $reg4, $pc, $fp, $stack, $nargs;
$ GLOBALS['glo_-'] = 'glo__';
$ stack[$fp+1] = $reg0;
$ reg1 = "!\n";
$ reg0 = 'lbl_x20hellowr_3';
$ pc = 'lbl_x20hellowr_2';
$ fp = $fp+4;
}
function lbl_x20hellowr_2 () {
global $reg0, $reg1, $reg2, $reg3, $reg4, $pc, $fp, $stack, $nargs;
$nargs = 1;
$ pc = $GLOBALS['glo_-'];
}
function lbl_x20hellowr_3 () {
global $reg0, $reg1, $reg2, $reg3, $reg4, $pc, $fp, $stack, $nargs;
$ GLOBALS['glo_-'] = $reg1;
$ reg0 = $stack[$fp-3];
$ pc = 'lbl_x20hellowr_4';
}
function lbl_x20hellowr_4 () {
global $reg0, $reg1, $reg2, $reg3, $reg4, $pc, $fp, $stack, $nargs;
$nargs = 0;
$ pc = $GLOBALS['glo_-'];
$ fp = $fp-4;
}
// procedure - =
function glo__ () {
global $reg0, $reg1, $reg2, $reg3, $reg4, $pc, $fp, $stack, $nargs;
$ stack[$fp+1] = array('lbl___2', $reg1);
$ reg1 = $stack[$fp+1];
$ pc = $reg0;
}
function lbl___2 () {
global $reg0, $reg1, $reg2, $reg3, $reg4, $pc, $fp, $stack, $nargs;
$ reg1 = $reg4[1];
$ pc = 'lbl___3';
}
function lbl___3 () {
global $reg0, $reg1, $reg2, $reg3, $reg4, $pc, $fp, $stack, $nargs;
$nargs = 1;
$ pc = $GLOBALS['glo_display'];
}
exec_scheme_code(' glo_x20hellowr ');
1)gotoの実装方法
各GVMブロック(ラベルから遷移まで)は、gotoの移動先を返すPHP関数になります。 プログラム「exec_scheme_code($ pc)」のエグゼキューターは次のようになります。
$ reg0 = 'glo_exit';
while(1){
$ pc = $ pc()
}
コンパイラの代わりに、インタープリターがここで作成されました。 パフォーマンスが低下します。
代替案?
2)スーパーグローバル
各関数は同じグローバル変数をリストする必要があります。 たぶん、デフォルトでグローバルであることをPHPに伝える方法はありますか?
3)スタック
ハードウェアスタックの代わりに、ソフトウェアスタックを使用する必要があります。 当然、私は配列を取りました。 そして、私は少し推測しませんでした。 それらは常に連想的であり、興味深い副作用がたくさんあり、作業も遅くなります。
高速スタックを作成する方法は?
4)パフォーマンス
当然、そのようなPHPコードは遅くなります。 たとえば、Ackermann関数の手動実装と比較すると、30倍遅くなります。 理由は不明(gotoおよびstack)ですが、確認したいです。
測定するツールは何ですか?