let rec string_of_ir_instruction inst = match inst with
    Instruction i -> string_of_instruction i
  | GetVar s -> concat ["GetVar ";s]
  | SetVar s -> concat ["SetVar ";s]
  | NoteVar (s,i) -> concat ["NoteVar ";s;" ";string_of_int i]
  | If (test,body,elsebody) -> concat 
      ["IF\n";
       string_of_ir_buffer test;
       "\nTHEN\n";
       string_of_ir_buffer body;
       "\nELSE\n";
       string_of_ir_buffer elsebody;
       "\nENDIF\n"]
  | For (init,test,step,body) -> concat
      ["FOR\nINIT\n";
       string_of_ir_buffer init;
       "\nTEST IF TRUE\n";
       string_of_ir_buffer test;
       "\nSTEP\n";
       string_of_ir_buffer step;
       "\nDO\n";
       string_of_ir_buffer body;
       "\nENDFOR\n"]
  | While (test,body) -> concat
      ["WHILE\nTEST IF TRUE\n";
       string_of_ir_buffer test;
       "\nDO\n";
       string_of_ir_buffer body;
       "\nENDWHILE\n"]
  | DoWhile (body,test) -> concat
      ["WHILE\nTEST IF TRUE\n";
       string_of_ir_buffer test;
       "\nDO\n";
       string_of_ir_buffer body;
       "\nENDWHILE\n"]
  | Break -> "Break"
  | Continue -> "Continue"
  | DeclareGlobal s -> concat ["DeclareGlobal ";s]
  | EndScope -> "EndScope"
  | EndScopeSf -> "EndScopeSf"
  | BeginScope -> "BeginScope"
  | EndScopeSfRPC -> "EndScopeSfRPC"
  | NoteFunction s -> concat ["NoteFunction ";s]
  

(** Produces a string representation of the given IR instruction buffer *)

and string_of_ir_buffer buf = match buf with
    cur::rest -> concat [(string_of_ir_instruction cur);"\n";(string_of_ir_buffer rest)]
  | [] -> ""

(** Prints the IR buffer to the given output channel *)

and print_ir_buffer chan buf =
  output_string chan (string_of_ir_buffer buf)