4

現在、非常に限定されたオブジェクト指向言語のコンパイラを開発中です。すべての値をオブジェクトとして扱い、それらの値の演算子をメソッドとして実装します。コンパイラは、プログラムをスタックベースの仮想マシンのアセンブラに変換します。プロシージャを使用した短絡評価

コンパイル時に、整数リテラルを特殊な「整数」クラスのオブジェクトに変換します。算術演算子は、そのクラスのメソッドとしてインラインアセンブラを使用して実装されます。したがって、4 + 5は、基本的には4.add(5)に等しい。

私が今直面している問題は、ブール値の特殊な場合です。 ifの文がある場合:今、明らかにそれらの整数リテラルも副作用を持つ関数の呼び出しすることができ10.greaterThan(5).or(12.lessThan(10))

if(10 > 5 || 12 < 10) 

これは、現在に変換されるだろう。これらのバイナリ演算子をメソッド呼び出しとして実装すると、短絡評価が不可能になるため、この場合に問題が発生します。

だから私の質問は以下のとおりです。

  1. どのように他の言語は短絡評価を達成しないが、それでもオブジェクトとしてすべての値を処理しますか?

  2. ウィキペディアによると、 "ALGOL 68は"手続き "を使ってユーザ定義の短絡オペレータ&プロシージャを実現しています。" - これはどのように作動しますか?

答えて

4

通常の技術は、私は信じて、call by nameまたはcall by needのいずれかを必要とします。考え方は、orのパラメータは比較の結果ではなく、代わりにthunkに変換された比較自体であり、(名前で呼び出すとき)または最初に呼び出すときに結果の値に変換されます必要)それが必要です。

式をサンクに変換すると、基本的には無名関数が作成され、コンパイルの問題をそのまま扱うことができます。これは、式をコンパイルして、式を評価するコードにします。また、式のコンパイルされたコードへのポインタと共に、式が使用するローカル変数を参照する(またはそのコピーを含む)オブジェクト(thunk自体)を作成することも含まれます。オブジェクトはブール型クラスとインターフェース互換でなければならないので、それを使用しているコードは本物のブール値を持っているかどうか気にする必要はありません。誰かがブール値を必要とするたびに、サンクはコンパイルされた式コードを実行し、結果の値を提供します。

名前で呼ぶだけで十分なら、それだけです。必要に応じてコールする場合、評価の結果をキャッシュすることから複雑さが増します。

1

IIRC ALGOLは名前による呼び出しを使用するため、その解決策が機能します。

||オペレータは、(擬似コード)として実施することができる。

if (cond1) goto label; 
if (cond2) goto label; 

label: 
    <body> 

nomatch: 
    ... 

&&ための上記の逆を行うことができます。

1

再:ウィキペディアによると、「ユーザー 定義された短絡オペレータに&手順を達成するために。 『proceduringを』 ALGOL68使用しました」 - これはどのように作動しますか?

Algol68-r0(元の/未定義の定義)には、短絡評価に関する2つの概念がありました。

コーダは、「短絡評価」を行った行列乗算演算子を定義したいと考えているので、左の引数が "ゼロ"の行列になると、右側の評価がさらに行われます。逆に、コーダは、左と右の引数を並列に評価したいと考えます。このようなユーザー定義の定義は次のようになります。

PRIO TIMESPAR = 7; 
OP TIMESPAR = (MAT a, MAT b)MAT: ¢ insert actual code here ¢ ~; 

コンマが、任意の順序で、あるいは並列に左手と右手を評価するために自由にコンパイラに指示します。シーケンシャルであることを評価を強制することもできます

またはコーダを(これは、評価を最適化するためのオプションコンパイラの葉):

PRIO TIMESSEQ = 7; 
OP TIMESSEQ = (MAT a; MAT b)MAT: ¢ insert actual code here ¢ ~; 

この場合は「;」 "gomma"と呼ばれ、 "on comma"と呼ばれています。

(WindowsおよびLinux用のSourceForgeで入手可能な1974年に改訂され、)Algol68-r1が手動/特に「proceduring」を適用するコーダを残してすべてのこれらの能力を削除...例えば

行列の定義の最初のセットです及び(MAT:C):

print(a TIMESF MAT:b TIMESF MAT:c) ¢ would print 0 without calculating 16*25 ¢ 

透明

MODE MAT = FLEX[0,0]REAL; 
PRIO TIMESF = 7; 
OP TIMESF = (MAT a, PROC MAT in b)MAT: 
    IF ISZERO a THEN a ELSE MAT b = in b; ¢ insert actual code here ¢ ~ FI; 

MAT a = 0, b = 16, c = 25; ¢ 3 1x1 matrices are "widening" from REAL numbers ¢ 

しかし、使用量が異なるが、2つのラムダ(C:TIMES MAT B MAT)の使用に注意してください。同じ脱保護および拡幅はAlgol68-r1に保持されています。

関連する問題