+exception T of t
+
+let raise t =
+ raise (T t)
+
+let to_string =
+ let s = Printf.sprintf in
+ function
+ | Invalid_syntax pos ->
+ s "Invalid syntax in %s" (Pos.to_string pos)
+ | Break_outside_loop pos ->
+ s "Break statement is not within a loop. In %s" (Pos.to_string pos)
+ | Cycle_in_type_decs {from_id; from_pos; to_id; to_pos} ->
+ s ( "Circular type declaration between %S and %S."
+ ^^"Locations: %S (in %s), %S (in %s).")
+ (Sym.to_string from_id)
+ (Sym.to_string to_id)
+ (Sym.to_string from_id)
+ (Pos.to_string from_pos)
+ (Sym.to_string to_id)
+ (Pos.to_string to_pos)
+ | Unknown_id {id; pos} ->
+ s "Unknown identifier %S in %s" (Sym.to_string id) (Pos.to_string pos)
+ | Unknown_type {ty_id; pos} ->
+ s "Unknown type %S in %s" (Sym.to_string ty_id) (Pos.to_string pos)
+ | Id_is_a_function {id; pos} ->
+ s "Identifier %S is a function, it cannot be used as a variable in %s"
+ (Sym.to_string id) (Pos.to_string pos)
+ | Id_not_a_function {id; pos} ->
+ s "Identifier %S is not a function, it cannot be called in %s"
+ (Sym.to_string id) (Pos.to_string pos)
+ | No_such_field_in_record {field; record; pos} ->
+ s "No field %S in record %S in %s"
+ (Sym.to_string field) (Typ.to_string record) (Pos.to_string pos)
+ | Exp_not_a_record {ty; pos} ->
+ s ( "The expression of type %S is not a record, it cannot be"
+ ^^"accessed in %s")
+ (Typ.to_string ty) (Pos.to_string pos)
+ | Exp_not_an_array {ty; pos} ->
+ s ( "The expression of type %S is not an array, it cannot be"
+ ^^"accessed in %s")
+ (Typ.to_string ty) (Pos.to_string pos)
+ | Wrong_type {expected; given; pos} ->
+ s "Type error: expected: %S, but given: %S, in %s"
+ (Typ.to_string expected)
+ (Typ.to_string given)
+ (Pos.to_string pos)
+ | Wrong_type_of_expression_in_var_dec {var_id; expected; given; pos} ->
+ s ( "Wrong type of expression in declaration of %S. "
+ ^^"Expected: %S, given: %S. In %s")
+ (Sym.to_string var_id)
+ (Typ.to_string expected)
+ (Typ.to_string given)
+ (Pos.to_string pos)
+ | Wrong_type_used_as_array {ty_id; ty; pos} ->
+ s ( "Identifier %S is bound to type %S, not an array. "
+ ^^"It cannot be used in %s")
+ (Sym.to_string ty_id) (Typ.to_string ty) (Pos.to_string pos)
+ | Wrong_type_used_as_record {ty_id; ty; pos} ->
+ s ( "Identifier %S is bound to type %S, not a record. "
+ ^^"It cannot be used in %s")
+ (Sym.to_string ty_id) (Typ.to_string ty) (Pos.to_string pos)
+ | Wrong_type_of_field_value {field_id; expected; given; pos} ->
+ s ( "Field %S is declared to be of type %S, but is bound to expression "
+ ^^"of type %S in %s")
+ (Sym.to_string field_id)
+ (Typ.to_string expected)
+ (Typ.to_string given)
+ (Pos.to_string pos)
+ | Wrong_type_of_arg {func; expected; given; pos} ->
+ s ( "Incorrect type of argument to function %S, expected: %S, given: %S,"
+ ^^" in %s")
+ (Sym.to_string func)
+ (Typ.to_string expected)
+ (Typ.to_string given)
+ (Pos.to_string pos)
+ | Wrong_number_of_args {func; expected; given; pos} ->
+ s ( "Incorrect number of arguments to function %S, "
+ ^^"expected: %d, given: %d,"
+ ^^" in %s")
+ (Sym.to_string func) expected given (Pos.to_string pos)
+ | Invalid_operand_type {oper; valid; given; pos} ->
+ s ( "Invalid operand type %S for operator %S, which expects only: %s"
+ ^^". In %s")
+ (Typ.to_string given)
+ (Abs.op_show oper)
+ (String.concat ", " valid)
+ (Pos.to_string pos)
+ | Different_operand_types {oper; left; right; pos} ->
+ s "Operands of different types (%S %S %S) given in %s"
+ (Typ.to_string left)
+ (Abs.op_show oper)
+ (Typ.to_string right)
+ (Pos.to_string pos)
+
+let is_unknown_id t =
+ match t with
+ | Unknown_id _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Invalid_syntax _
+ | Unknown_type _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | No_such_field_in_record _
+ | Exp_not_a_record _
+ | Exp_not_an_array _
+ | Wrong_type _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_unknown_type t =
+ match t with
+ | Unknown_type _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Unknown_id _
+ | Invalid_syntax _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | No_such_field_in_record _
+ | Exp_not_a_record _
+ | Exp_not_an_array _
+ | Wrong_type _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_wrong_type t =
+ match t with
+ | Wrong_type _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Unknown_type _
+ | Unknown_id _
+ | Invalid_syntax _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | No_such_field_in_record _
+ | Exp_not_a_record _
+ | Exp_not_an_array _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_wrong_number_of_args t =
+ match t with
+ | Wrong_number_of_args _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Wrong_type _
+ | Unknown_type _
+ | Unknown_id _
+ | Invalid_syntax _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | No_such_field_in_record _
+ | Exp_not_a_record _
+ | Exp_not_an_array _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_invalid_syntax t =
+ match t with
+ | Invalid_syntax _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Wrong_type _
+ | Unknown_type _
+ | Unknown_id _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | No_such_field_in_record _
+ | Exp_not_a_record _
+ | Exp_not_an_array _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_not_a_record t =
+ match t with
+ | Exp_not_a_record _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Invalid_syntax _
+ | Wrong_type _
+ | Unknown_type _
+ | Unknown_id _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | No_such_field_in_record _
+ | Exp_not_an_array _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_not_an_array t =
+ match t with
+ | Exp_not_an_array _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Exp_not_a_record _
+ | Invalid_syntax _
+ | Wrong_type _
+ | Unknown_type _
+ | Unknown_id _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | No_such_field_in_record _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_no_such_field_in_record t =
+ match t with
+ | No_such_field_in_record _ ->
+ true
+ | Break_outside_loop _
+ | Cycle_in_type_decs _
+ | Exp_not_an_array _
+ | Exp_not_a_record _
+ | Invalid_syntax _
+ | Wrong_type _
+ | Unknown_type _
+ | Unknown_id _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_cycle_in_type_dec t =
+ match t with
+ | Cycle_in_type_decs _ ->
+ true
+ | Break_outside_loop _
+ | No_such_field_in_record _
+ | Exp_not_an_array _
+ | Exp_not_a_record _
+ | Invalid_syntax _
+ | Wrong_type _
+ | Unknown_type _
+ | Unknown_id _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false
+
+let is_break_outside_loop t =
+ match t with
+ | Break_outside_loop _ ->
+ true
+ | Cycle_in_type_decs _
+ | No_such_field_in_record _
+ | Exp_not_an_array _
+ | Exp_not_a_record _
+ | Invalid_syntax _
+ | Wrong_type _
+ | Unknown_type _
+ | Unknown_id _
+ | Id_is_a_function _
+ | Id_not_a_function _
+ | Wrong_type_of_expression_in_var_dec _
+ | Wrong_type_used_as_array _
+ | Wrong_type_used_as_record _
+ | Wrong_type_of_field_value _
+ | Wrong_type_of_arg _
+ | Wrong_number_of_args _
+ | Invalid_operand_type _
+ | Different_operand_types _ ->
+ false