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

open Ident

type var_loc =
  | Stack of int
  | Env of int
  | Ext of Types.CompUnit.t * int (* If pos < 0, the first arg is the value *)
  | External of Types.CompUnit.t * int 
      (* If pos < 0, the first arg is the value *)
  | Builtin of string
  | Global of int (* Only for the toplevel *)
  | Dummy

type schema_component_kind =
  [ `Type | `Element | `Attribute | `Attribute_group | `Model_group ] option

type expr = 
  | Var of var_loc
  | Apply of bool * expr * expr
  | Abstraction of var_loc array * (Types.t * Types.t) list * branches
  | Check of Types.t * expr * Types.Node.t

  | Const of Types.Const.t
  | Pair of expr * expr
  | Xml of expr * expr * expr
  | XmlNs of expr * expr * expr * Ns.table
  | Record of expr label_map
  | String of U.uindex * U.uindex * U.t * expr

  | Match of expr * branches
  | Map of expr * branches
  | Transform of expr * branches
  | Xtrans of expr * branches
  | Try of expr * branches
  | Validate of expr * string * Ns.qname
  | RemoveField of expr * label
  | Dot of expr * label
  | Ref of expr * Types.Node.t
  | Op of string * expr list  
  | OpResolved of Obj.t * expr list
      (* the first arg is the eval function *)
      (* type Value.t is not available here ... *)
  | NsTable of Ns.table * expr

and branches = {
  brs: (Patterns.node * expr) list;
  brs_tail: bool;
  brs_input: Types.t;
  brs_accept_chars: bool;
  mutable brs_compiled: 
    (Patterns.Compile.dispatcher * expr Patterns.Compile.rhs array) option;
}

type code_item =
  | Push of expr
  | Pop
  | Split of Patterns.node
  | SetGlobal of Types.CompUnit.t * int

type code = code_item list

module Put :
  sig
    val unary_op : (Serialize.Put.t -> int -> unit) ref
    val binary_op : (Serialize.Put.t -> int -> unit) ref
    val var_loc : Serialize.Put.t -> var_loc -> unit
    val expr : expr Serialize.Put.f
    val branches : Serialize.Put.t -> branches -> unit
    val code_item : Serialize.Put.t -> code_item -> unit
    val codes : code_item list Serialize.Put.f
    val compunit : Serialize.Put.t -> code_item list -> unit
  end
module Get :
  sig
    val unary_op : (Serialize.Get.t -> int) ref
    val binary_op : (Serialize.Get.t -> int) ref
    val var_loc : Serialize.Get.t -> var_loc
    val expr : expr Serialize.Get.f
    val branches : Serialize.Get.t -> branches
    val code_item : Serialize.Get.t -> code_item
    val codes : code_item list Serialize.Get.f
    val compunit : Serialize.Get.t -> code_item list
  end

val print_var_loc : Format.formatter -> var_loc -> unit
