(* Types *)

(* Type des expressions *)
type typ = 
  | Tvar of tvar (* pour les elts ([]) non encore typees *)
  | Tint
  | Tbool
  | Tunit
  | Tlist of typ
  | Tref of typ
and tvar={id:int ; mutable t:typ option}


(* AST *)

type comp = Ast.comp
(*  | Ge | Le | Gt | Lt | Eq | Neq *)

type binop = Ast.binop
(*  | Add | Sub | Mul | Div | Mod
  | Comp of comp
  | And | Or | Concat | Assert | Semi *)

type unop = Ast.unop
(*  | Minus | Excl *)

type cst = Ast.cst
(*  | Int of int
  | Bool of bool
  | Unit
  | EmptyList *)

type path = string list

type fargs = (bool*path) list
type margs = path list

type program = elt list

and elt =
  | LetIgnore of expr
  | Let of path * fargs * expr
  | Module of path * margs * mexpr

and expr =
  | Cst of cst
  | Var of path
  | App of path * ((bool*expr) list)
  | Ref of expr
  | Binop of binop * expr * expr
  | Unop of unop * expr
  | IfThenElse of expr * expr * expr
  | LetIn of path * expr * expr
  | MatchWith of expr * expr * path * path * expr

and mexpr =
  | Struct of elt list
  | Functor of path * (path list)


(* Types des modules *)


(* Map renvoyant un nom unique et son type pour chaque variable/module
 * Les clés sont les noms des variables/modules
 * Attention le nom unique peut être un path transformé en chaîne ! *)

type type_env = (path * typ2) Map.Make(String).t
(* Type des signatures *)
and typ2 =
  | Tval of (typ list) * typ
  | Tmod of ((string*type_env) list) * type_env


