Типы выражений в компиляторе, написанном на Ocaml - PullRequest
4 голосов
/ 18 июня 2011

Я пишу небольшой компилятор в Ocaml.В ast.mli я определил 2 вида выражений

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

В interp.ml я хочу определить функцию с именем eval_expression для оценки любого выражения, которое может быть int_expr или bool_expr

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) -> ...

Но он возвращает ошибку при компиляции:

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

Может кто-нибудь сказать мне, как я мог бы изменить структуру своих типов выражений, чтобы eval_expression работал?Большое спасибо!

1 Ответ

4 голосов
/ 18 июня 2011

Вам потребуется написать другой тип для выражений произвольного типа:

type expr = Iexpr of int_expr
          | Bexpr of bool_expr

и тип для конечных значений, которые могут быть целыми или логическими

type value = Ivalue of int
           | Bvalue of bool

, и написатьfunction evaluate : expr -> value.

Несмотря на это, я никогда не чувствовал, что статическое разделение допустимых выражений таким образом на выражения типа int и bool-типа когда-либо действительно стоило того в ML-подобном языке,Вы получите много дублированного синтаксиса после добавления более богатых типов к вашему объектному языку.То, что вы действительно хотите, - это вставить типы объектного языка в страты типов вашего языка реализации, но в ML это выглядит довольно уродливо.Это немного приятнее в более богатых типах и добрых механизмах Haskell, но все равно кажется, что это сильно влияет на стиль программирования.

В конце, для маленьких одноразовых интерпретаторов я обычно просто кодирую отдельные типы tp и exprдля типа и выражений моего объектного языка и напишите eval как expr -> tp -> value

...