sig
  type lua_const =
      [ `L_Bool of bool | `L_Double of float | `L_Nill | `L_String of string ]
  type rk_source =
      [ `L_Bool of bool
      | `L_Double of float
      | `L_Nill
      | `L_String of string
      | `Register of int ]
  type arith_op_types = Arith_Add | Arith_Sub | Arith_Mul | Arith_Div
  type arith_op = {
    op_type : Assembler.arith_op_types;
    left_src : Assembler.rk_source;
    right_src : Assembler.rk_source;
    dest : int;
  }
  type comparison_type = Comp_Eq | Comp_Lt | Comp_Le
  type comparison_op = {
    skip_if_not : bool;
    right_operand : Assembler.rk_source;
    left_operand : Assembler.rk_source;
    comp_type : Assembler.comparison_type;
  }
  type return_val = No_Value | Return_One of int | Return_Many of int * int
  type lua_ops =
      Load_Const of int * Assembler.lua_const
    | Get_Global of int * string
    | Set_Global of string * int
    | Concat of int * int * int
    | Jump of int
    | Cmp of Assembler.comparison_op
    | Move of int * int
    | Arith of Assembler.arith_op
    | Call of int * int * int
    | Closure of int * int
    | Load_Table of int * int * Assembler.rk_source
    | Set_Table of int * Assembler.rk_source * Assembler.rk_source
    | Set_List of int * int * int
    | Make_Table of int * int * int
    | Return of Assembler.return_val
  type function_unit = {
    instructions : Assembler.lua_ops list;
    num_params : int;
    child_functions : Assembler.function_unit list;
  }
  val assemble : Assembler.function_unit -> Pervasives.out_channel -> unit
end