(**********************************************************************)
(* (c) Greg Morrisett, Neal Glew, Chris Hawblitzel,                   *)
(*     June 1998, all rights reserved.                                *)
(**********************************************************************)

open Numtypes;;

type location = Gcdfec.seg
type var = string
type type_name = string
type field_name = string
type scope = Static | Public | Extern | Abstract
type capability = ReadOnly | ReadWrite

type typ =
    VoidType
  | Evar of typ option ref  (* used for unification of types only *)
  | OptionEvar of typ option ref (* used for unification of ? types only *)
  | VarType of var
  | IntType
  | BooleanType
  | StringType
  | CharType
  | ArrayType of typ
  | FnType of var list * typ * (typ list)
  | TupleType of (typ list)
  | NamedType of type_name ref * (typ list) (* ref is needed to support open *)
  | ExnType

type const = 
    Int of int32
  | Bool of bool
  | String of string
  | Char of char
  | Null

type primop = 
    Plus | Times | Minus | Div | Mod | Eq | Neq | Gt | Lt | Gte | Lte | Not |
    Bitnot | Bitand | Bitor | Bitxor | Bitlshift | Bitlrshift | Bitarshift |
    Size | Ord | Chr

type raw_exp =
    Const of const
  | ConstArray of exp list * typ option
  | Var of var
  | Primop of primop * (exp list)
  | Conditional of exp * exp * exp
  | Assign of exp * exp
  | AssignOp of exp * primop * exp  (* e.g., x+=1, x[i] *= 3 *)
  | FunCall of exp * ((typ list) option ref) * (exp list)
  | NewStruct of type_name * ((typ list) option ref) * (exp list)
  | StructMember of exp * field_name
  | NewUnion of type_name * ((typ list) option ref) * field_name * (exp option)
  | NewTuple of (exp list)
  | TupleMember of exp * int
  | Subscript of exp * exp
  | NewArray of exp * exp
(* Cyclone *)
  | Codegen of fndecl
  | Fill of exp
(* End Cyclone *)
  | NewExn of var * (exp option)
  | Raise of exp
and exp = 
    { mutable exp_typ: typ option;
      mutable raw_exp: raw_exp; (* use sparingly!!! *)
      exp_loc: location
    } 
and raw_stmt =
    Skip
  | Exp of exp
  | Seq of stmt * stmt
  | Return of exp option
  | IfThenElse of exp * stmt * stmt
  | While of exp * stmt
  | Break 
  | Continue
  | For of exp * exp * exp * stmt
  | IntSwitch of exp * (int32 * stmt) list * stmt
  | CharSwitch of exp * (char * stmt) list * stmt
  | UnionSwitch of 
      exp * (field_name * (var option) * stmt) list * (stmt option) 
  | Decl of var * typ * (exp option) ref * stmt
(* Cyclone *)
  | Cut of stmt
  | Splice of stmt
(* End Cyclone *)
  | Do of stmt * exp
  | Try of stmt * var * stmt
and stmt = raw_stmt * location
and fndecl = { fn_static: bool;
	       fn_name: var;
	       fn_tyvars: var list;
	       fn_ret_type: typ;
	       fn_args: (var * typ) list;
	       fn_body: stmt
	      } 

type struct_field = (field_name * capability * typ)
type union_field = (field_name * typ)

type structdecl = { st_scope: scope;
		    st_name: type_name;
		    st_tyvars: var list;
		    st_possibly_null: bool;
		    st_fields: struct_field list
		  }	
type uniondecl = { un_scope: scope;
		   un_name: type_name;
		   un_tyvars: var list;
		   un_possibly_null: bool;
		   un_fields: union_field list
		 }	

type raw_top_decl =
    FunDecl of fndecl
  | StructDecl of structdecl
  | UnionDecl of uniondecl
  | ExceptionDecl of (var * scope * typ)
  | ExternType of type_name * (var list) * bool  (* bool indicates option *)
  | ExternVal of var * typ
  | GlobalDecl of (scope * var * typ * (exp option) ref)
  | PrefixDecl of var * top_decl list
  | OpenDecl of var * top_decl list
and top_decl = raw_top_decl * location

val typ2string : typ -> string
val eqtype : typ -> typ -> bool
val add_prefix : string -> var -> var
