(**************************************************************************)
(*  The CDuce compiler                                                    *)
(*  Alain Frisch <Alain.Frisch@inria.fr> and the CDuce team               *)
(*  Copyright CNRS,INRIA, 2003,2004 (see LICENSE for details)             *)
(**************************************************************************)

open Ident
open Encodings

type t =
(* Canonical representation *)
  | Pair of t * t
  | Xml of t * t * t
  | XmlNs of t * t * t * Ns.table
  | Record of t label_map
  | Atom of Atoms.V.t
  | Integer of Intervals.V.t
  | Char of Chars.V.t
  | Abstraction of (Types.descr * Types.descr) list option * (t -> t)
  | Abstraction2 of t array * (Types.t * Types.t) list * Lambda.branches
  | Abstract of Types.Abstract.V.t

(* Derived forms *)
  | String_latin1 of int * int * string * t
  | String_utf8 of U.uindex * U.uindex * U.t * t
  | Concat of t * t

(* Special value for absent record fields, and failed pattern matching *)
  | Absent

module ValueSet: Set.S with type elt = t

exception CDuceExn of t
val raise': t -> 'a           (* "raise" for CDuce exceptions *)
val failwith': string -> 'a   (* "failwith" for CDuce exceptions *)
val tagged_tuple: string -> t list -> t

val print: Format.formatter -> t -> unit
val dump_xml: Format.formatter -> t -> unit

val normalize: t -> t
  (* Transform a derived form to its canonical equivalent *)

val const : Types.const -> t  (* extract the const value from a const type *)
val inv_const : t -> Types.const  (* build a const type from a const value *)
val string_latin1 : string -> t
val string_utf8 : U.t -> t
val substring_utf8: U.uindex -> U.uindex -> U.t -> t -> t
val nil : t
val vtrue : t
val vfalse : t
val vbool : bool -> t

  (** @return a Record value from an associative list of fields *)
val vrecord : (Ns.qname * t) list -> t

val sequence : t list -> t
val sequence_rev : t list -> t
val get_sequence : t -> t list
val get_sequence_rev : t -> t list

val fold_sequence: ('a -> t -> 'a) -> 'a -> t -> 'a

val atom_ascii : string -> t
val label_ascii : string -> label
val record : (label * t) list -> t
val record_ascii : (string * t) list -> t
val get_field : t -> label -> t
val get_field_ascii : t -> string -> t

val get_variant : t -> string * t option

val abstract : Types.Abstract.abs -> 'a -> t
val get_abstract : t -> 'a

val mk_ref : Types.t -> t -> t
val mk_ext_ref : Types.t option -> (unit -> t) -> (t -> unit) -> t

  (* iterator on the content of an Xml value. First callback is invoked on Utf8
  character children; second callback is invoked on other children values *)
val iter_xml : (U.t -> unit) -> (t -> unit) -> t -> unit

(*
  (* as above for map *)
val map_xml : (U.t -> U.t) -> (t -> t) -> t -> t
*)

val concat : t -> t -> t
val flatten : t -> t
val append : t -> t -> t

val float: float -> t

val get_string_latin1 : t -> string
val get_string_utf8 : t -> U.t * t
val is_str : t -> bool
val is_seq : t -> bool

val get_int : t -> int
val get_integer : t -> Intervals.V.t

  (** @return an associative list of fields from a Record value *)
val get_fields : t -> (Ns.qname * t) list

val get_pair : t -> t * t

val compare : t -> t -> int
val equal : t -> t -> bool
val ( |<| ): t -> t -> bool
val ( |>| ): t -> t -> bool
val ( |<=| ): t -> t -> bool
val ( |>=| ): t -> t -> bool
val ( |=| ): t -> t -> bool
val ( |<>| ): t -> t -> bool


val set_cdr : t -> t -> unit
val append_cdr : t -> t -> t


val ocaml2cduce_int : int -> t
val cduce2ocaml_int : t -> int
val ocaml2cduce_string : string -> t
val cduce2ocaml_string : t -> string
val ocaml2cduce_string_utf8 : U.t -> t
val cduce2ocaml_string_utf8 : t -> U.t
val ocaml2cduce_char : char -> t
val cduce2ocaml_char : t -> char
(*val ocaml2cduce_bigint : Big_int.big_int -> t
val cduce2ocaml_bigint : t -> Big_int.big_int*)
val ocaml2cduce_option: ('a -> t) -> 'a option -> t
val cduce2ocaml_option: (t -> 'a) -> t -> 'a option
val ocaml2cduce_wchar : int -> t
val ocaml2cduce_atom : U.t -> U.t -> t

val print_utf8: U.t -> unit


val add: t -> t -> t
val pair: t -> t -> t
val xml: t -> t -> t -> t
val mk_record: (U.t * U.t) array -> t array -> t
