sig
  type lit = Int of int | Float of float | String of string | Bool of bool
  type arith = Add | Sub | Prod | Div | Mod | Neg | Pow
  type numtest = Eq | Neq | Less | Grtr | Leq | Geq
  type combtest = And | Or | Nand | Nor | Xor | Not
  type op =
      Arithmetic of Ast.arith
    | NumTest of Ast.numtest
    | CombTest of Ast.combtest
  type expr =
      This
    | Null
    | Id of string
    | NewObj of string * Ast.expr list
    | Anonymous of string * Ast.expr list * Ast.func_def list
    | Literal of Ast.lit
    | Assign of Ast.expr * Ast.expr
    | Deref of Ast.expr * Ast.expr
    | Field of Ast.expr * string
    | Invoc of Ast.expr * string * Ast.expr list
    | Unop of Ast.op * Ast.expr
    | Binop of Ast.expr * Ast.op * Ast.expr
    | Refine of string * Ast.expr list * string option
    | Refinable of string
  and var_def = string * string
  and stmt =
      Decl of Ast.var_def * Ast.expr option
    | If of (Ast.expr option * Ast.stmt list) list
    | While of Ast.expr * Ast.stmt list
    | Expr of Ast.expr
    | Return of Ast.expr option
    | Super of Ast.expr list
  and class_section = Publics | Protects | Privates | Refines | Mains
  and func_def = {
    returns : string option;
    host : string option;
    name : string;
    static : bool;
    formals : Ast.var_def list;
    body : Ast.stmt list;
    section : Ast.class_section;
    inklass : string;
    uid : string;
    builtin : bool;
  }
  type member_def =
      VarMem of Ast.var_def
    | MethodMem of Ast.func_def
    | InitMem of Ast.func_def
  type class_sections_def = {
    privates : Ast.member_def list;
    protects : Ast.member_def list;
    publics : Ast.member_def list;
    refines : Ast.func_def list;
    mains : Ast.func_def list;
  }
  type class_def = {
    klass : string;
    parent : string option;
    sections : Ast.class_sections_def;
  }
  type program = Ast.class_def list
end