私は擬似コードで書いて、それはPHPで動作します

擬似コードでプログラムを作成し、それらをPHPコードに変換できます。 またはポータブルCで または何か他のもの。 リストが更新されます。



「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)ですが、確認したいです。



測定するツールは何ですか?



All Articles