2011-06-17 7 views
4

Ocamlに小さなコンパイラを書いています。 ast.mliでは、私がOcamlで書かれたコンパイラの式のタイプ

let rec eval_expression env = function 
    | Integer_constant n -> Integer n 
    | Ebinop (op, n, m) -> ... 
    | Evar x -> ... 
    | Ecell (r, c) -> ... 
    | Bool_constant b -> ... 
    | Bnot c -> ... 
    | Bor (c1, c2) -> ... 
    | Band (c1, c2) -> ... 

int_exprまたはbool_expr可能性のいずれかの任意の式を評価するためにeval_expressionという関数を定義したい。しかし、それは返す、式の2種類interp.ml

type int_expr = 
    | Integer_constant of int 
    | Evar of string 
    | Ebinop of binop * int_expr * int_expr 
    | Ecell of int_expr * int_expr (* Sheet[ , ] *) 

type bool_expr = 
    | Bool_constant of bool 
    | Bcmp of cmp * int_expr * int_expr 
    | Band of bool_expr * bool_expr 
    | Bor of bool_expr * bool_expr 
    | Bnot of bool_expr 

を定義していますコンパイル中にエラーが発生しました:

ocamlc -c interp.ml 
File "interp.ml", line 63, characters 4-19: 
Error: This pattern matches values of type Ast.bool_expr 
     but a pattern was expected which matches values of type Ast.int_expr 
make: *** [interp.cmo] Error 2 

どのように私のexpreの構造を変更できるか教えてくださいあなたはeval_expressionが動作するようにssionの種類を教えてください。どうもありがとうございました!

+0

ようにevalを書く少し使い捨て通訳のためにあなたは、障害が報告され、正確なラインを表示することができます周囲の文脈の余分な数行で – dcolish

+0

正確な失敗行(63)は '|私のポストの 'eval_expression'関数で' Bool_constant b - > ... ' – SoftTimur

答えて

4

あなたは、任意の型指定された表現のための別の型記述する必要があります:

type expr = Iexpr of int_expr 
      | Bexpr of bool_expr 

と整数またはブール

type value = Ivalue of int 
      | Bvalue of bool 

のいずれであってもよく、機能evaluate : expr -> valueを書くことができ、最終的な値の型を。

このように許容される式をint型とbool型に静的に分離することは、MLライクな言語では本当に価値があるとは決して考えていませんでした。より豊富な型をオブジェクト言語に追加すると、多くの重複した構文で終わります。あなたが本当に望んでいるのは、オブジェクト言語の型を実装言語の型階層にキックすることですが、それはMLでかなり醜いものになります。 Haskellのより豊富な型と種類の機械ではやや良いですが、それでもやはり影響を受けるプログラミングスタイルのようです。最後に

、私は通常ちょうど私のオブジェクト言語の種類や表現のための独立したtpexpr種類をコーディングしexpr -> tp -> value

関連する問題