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

exception Error of string
open Ident

(* Pattern algebra *)

type descr
type node
module Node: Custom.T with type t = node

val make: fv -> node
val define: node -> descr -> unit

val constr : Types.t -> descr
val cup    : descr -> descr -> descr
val cap    : descr -> descr -> descr

val times  : node -> node -> descr 
val xml    : node -> node -> descr
val record : label -> node -> descr

val capture : id -> descr
val constant: id -> Types.const -> descr

val id: node -> int
val descr: node -> descr
val fv : node -> fv

(* Pretty-printing *)

module Print : sig
  val print: Format.formatter -> descr -> unit
end

(* Pattern matching: static semantics *)

val accept : node -> Types.Node.t
val filter : Types.t -> node -> Types.Node.t id_map


(* Pattern matching: compilation *)

module Compile: sig
  type dispatcher

  type source =
    | Catch | Const of Types.const 
    | Stack of int | Left | Right | Nil | Recompose of int * int

  type result = int * source array * int
      (* Return code, result values, number of values to pop *)

  type actions =
    | AIgnore of result
    | AKind of actions_kind
  and actions_kind = {
    basic: (Types.t * result) list;
    atoms: result Atoms.map;
    chars: result Chars.map;
    prod: result dispatch dispatch;
    xml: result dispatch dispatch;
    record: record option;
  }
  and record =
    | RecLabel of label * result dispatch dispatch
    | RecNolabel of result option * result option
  and 'a dispatch =
    | Dispatch of dispatcher * 'a array
    | TailCall of dispatcher
    | Ignore of 'a
    | Impossible


  val actions: dispatcher -> actions
  val types_of_codes: dispatcher -> Types.t array

  type 'a rhs = Match of (id * int) list * 'a | Fail
      (* ids are listed in the same order as returned by fv_list,
	 not fv ! *)
	 

  val make_branches : Types.t -> (node * 'a) list -> dispatcher * 'a rhs array

  val print_dispatcher: Format.formatter -> dispatcher -> unit

  val debug_compile : Format.formatter -> Types.Node.t -> node list -> unit
end
