#ifndef SUIF1_VISITOR_H
#define SUIF1_VISITOR_H

#include <suif1.h>

class suif1_visitor {
public:
  virtual ~suif1_visitor() { }; // avoid warnings;
  virtual boolean do_walk_file() { return TRUE; }
  virtual boolean do_walk_procedure() { return TRUE; }
  virtual boolean do_walk_block() { return TRUE; }
  virtual boolean do_walk_instruction() { return TRUE; }
  virtual boolean do_write_proc() { return TRUE; }
  virtual boolean do_flush_proc() { return TRUE; }
  virtual boolean do_walk_symtab() { return TRUE; }
  virtual boolean do_replace_operand() { return FALSE; }

  virtual void process_fileset(file_set *fs);
  virtual void walk_fileset(file_set *fs);
  virtual void pre_process_fileset(file_set *) {}
  virtual void post_process_fileset(file_set *) {}

  virtual void process_file(file_set_entry *fse);
  virtual void walk_file(file_set_entry *fse);
  virtual void pre_process_file(file_set_entry *) {}
  virtual void post_process_file(file_set_entry *) {}

  virtual void process_procedure(proc_sym *psym);
  virtual void walk_procedure(proc_sym *psym);
  virtual void pre_process_procedure(proc_sym *) {};
  virtual void post_process_procedure(proc_sym *) {};

  virtual void process_block_list(tree_node_list *tnl);
  
  virtual void process_block(tree_node *tn);
  virtual void walk_block(tree_node *tn);
  //virtual void pre_process_block(tree_node *) {}
  //virtual void post_process_block(tree_node *) {}

  virtual void process_block(tree_proc *tp);
  virtual void walk_block(tree_proc *tp);
  virtual void pre_process_block(tree_proc *) {}
  virtual void post_process_block(tree_proc *) {}

  virtual void process_block(tree_block *tb);
  virtual void walk_block(tree_block *tb);
  virtual void pre_process_block(tree_block *) {}
  virtual void post_process_block(tree_block *) {}

  virtual void process_block(tree_loop *tl);
  virtual void walk_block(tree_loop *tl);
  virtual void pre_process_block(tree_loop *) {}
  virtual void post_process_block(tree_loop *) {}

  virtual void process_block(tree_for *tf);
  virtual void walk_block(tree_for *tf);
  virtual void pre_process_block(tree_for *) {}
  virtual void post_process_block(tree_for *) {}

  virtual void process_block(tree_instr *ti);
  virtual void walk_block(tree_instr *ti);
  virtual void pre_process_block(tree_instr *) {}
  virtual void post_process_block(tree_instr *) {}

  virtual void process_block(tree_if *tif);
  virtual void walk_block(tree_if *tif);
  virtual void pre_process_block(tree_if *) {}
  virtual void post_process_block(tree_if *) {}

  virtual void process_instruction(instruction *i);
  virtual void walk_instruction(instruction *i);
  virtual void pre_process_instruction(instruction *) {}
  virtual void post_process_instruction(instruction *) {}

  virtual void process_src_operand(operand op);
  virtual void walk_src_operand(operand op);
  virtual void pre_process_src_operand(operand) {}
  virtual void post_process_src_operand(operand) {}


  virtual void process_dst_operand(operand op);
  virtual void walk_dst_operand(operand op);
  virtual void pre_process_dst_operand(operand) {}
  virtual void post_process_dst_operand(operand) {}


  // Symbol tables
  virtual void process_symtab(global_symtab *gst);
  virtual void walk_symtab(global_symtab *gst);
  virtual void pre_process_symtab(global_symtab *) {}
  virtual void post_process_symtab(global_symtab *) {}

  virtual void process_symtab(file_symtab *fst);
  virtual void walk_symtab(file_symtab *fst);
  virtual void pre_process_symtab(file_symtab *) {}
  virtual void post_process_symtab(file_symtab *) {}

  virtual void process_symtab(proc_symtab *pst);
  virtual void walk_symtab(proc_symtab *pst);
  virtual void pre_process_symtab(proc_symtab *) {}
  virtual void post_process_symtab(proc_symtab *) {}

  virtual void process_symtab(block_symtab *bst);
  virtual void walk_symtab(block_symtab *bst);
  virtual void pre_process_symtab(block_symtab *) {}
  virtual void post_process_symtab(block_symtab *) {}

  virtual operand post_replace_src_operand(operand op) { return(op); }

};

// autoinit functions
extern void init_suif1_visitor(int &, char **);
extern void exit_suif1_visitor(void);
extern void enter_suif1_visitor(int *, char **);

/*
 * To do list:
 * Visitor for the symbol table types
 * Visitor for Symbols
 * Visitor for all labels
 * Visitor for all types
 */

#endif /* VISITOR_H */
