/* $Id$
 *
 * Visitor (intermediate code). Abstract base class for visitors.
 *
 * Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */


// namespace collision
#ifndef __INTERMEDIATE_VISITOR_HPP_INCLUDED
#define __INTERMEDIATE_VISITOR_HPP_INCLUDED

namespace intermediate {

/* forward declaration of classes */
class CodeContainer;
class BeginTransfer;
class EndTransfer;
class GetParam;
class SetParam;
class Connect;
class Mov;
class Je;
class Jne;
class Jb;
class Jbe;
class Jmp;
class Label;
class Abort;
class Add;
class Sub;
class IMul;
class Div;
class Call;
class Return;
class Proc;
class Update;
class GetSig;
class GetSimTime;
class ROffset;
class AOffset;
class Suspend;
class WakeOn;
class WakeAt;
class Log;
class Reference;
class Register;
class ImmediateOperand;
class IndirectOperand;
class Data;
class TypeElement;
class Type;
class Node;


//! Generic interface for intermediate code vistitors.
/** This is an abstract base class for all intermediate code visitors.
 */
class Visitor {
public:
	//! virtual dummy d'tor
	virtual ~Visitor() {}

	//! visit a CodeContainer node
	/** @param node node that gets visited.
	 */
	virtual void visit(CodeContainer &node) = 0;

	//! visit a BeginTransfer node
	/** @param node node that gets visited.
	 */
	virtual void visit(BeginTransfer &node) = 0;

	//! visit an EndTransfer node
	/** @param node node that gets visited.
	 */
	virtual void visit(EndTransfer &node) = 0;

	//! visit a SetParam node
	/** @param node node that gets visited.
	 */
	virtual void visit(SetParam &node) = 0;

	//! visit a GetParam node
	/** @param node node that gets visited.
	 */
	virtual void visit(GetParam &node) = 0;

	//! visit a Connect node
	/** @param node node that gets visited.
	 */
	virtual void visit(Connect &node) = 0;

	//! visit a Mov node
	/** @param node node that gets visited.
	 */
	virtual void visit(Mov &node) = 0;

	//! visit a Je node
	/** @param node node that gets visited.
	 */
	virtual void visit(Je &node) = 0;

	//! visit a Jne node
	/** @param node node that gets visited.
	 */
	virtual void visit(Jne &node) = 0;

	//! visit a Jb node
	/** @param node node that gets visited.
	 */
	virtual void visit(Jb &node) = 0;

	//! visit a Jbe node
	/** @param node node that gets visited.
	 */
	virtual void visit(Jbe &node) = 0;

	//! visit a Jmp node
	/** @param node node that gets visited.
	 */
	virtual void visit(Jmp &node) = 0;

	//! visit a Label node
	/** @param node node that gets visited.
	 */
	virtual void visit(Label &node) = 0;

	//! visit an Abort node
	/** @param node node that gets visited.
	 */
	virtual void visit(Abort &node) = 0;

	//! visit an Add node
	/** @param node node that gets visited.
	 */
	virtual void visit(Add &node) = 0;

	//! visit an Sub node
	/** @param node node that gets visited.
	 */
	virtual void visit(Sub &node) = 0;

	//! visit an IMul node
	/** @param node node that gets visited.
	 */
	virtual void visit(IMul &node) = 0;

	//! visit a Div node
	/** @param node node that gets visited.
	 */
	virtual void visit(Div &node) = 0;

	//! visit a Call node
	/** @param node node that gets visited.
	 */
	virtual void visit(Call &node) = 0;

	//! visit a Return node
	/** @param node node that gets visited.
	 */
	virtual void visit(Return &node) = 0;

	//! visit a Proc node
	/** @param node node that gets visited.
	 */
	virtual void visit(Proc &node) = 0;

	//! visit an Update node
	/** @param node node that gets visited.
	 */
	virtual void visit(Update &node) = 0;

	//! visit a GetSig node
	/** @param node node that gets visited.
	 */
	virtual void visit(GetSig &node) = 0;

	//! visit a GetSimTime node
	/** @param node node that gets visited.
	 */
	virtual void visit(GetSimTime &node) = 0;

	//! visit a ROffset node
	/** @param node node that gets visited.
	 */
	virtual void visit(ROffset &node) = 0;

	//! visit an AOffset node
	/** @param node node that gets visited.
	 */
	virtual void visit(AOffset &node) = 0;

	//! visit a Suspend node
	/** @param node node that gets visited.
	 */
	virtual void visit(Suspend &node) = 0;

	//! visit a WakeOn node
	/** @param node node that gets visited.
	 */
	virtual void visit(WakeOn &node) = 0;

	//! visit a WakeAt node
	/** @param node node that gets visited.
	 */
	virtual void visit(WakeAt &node) = 0;

	//! visit a Log node
	/** @param node node that gets visited.
	 */
	virtual void visit(Log &node) = 0;

	//! visit an ImmediateOperand node
	/** @param node node that gets visited.
	 */
	virtual void visit(ImmediateOperand &node) = 0;

	//! visit an IndirectOperand node
	/** @param node node that gets visited.
	 */
	virtual void visit(IndirectOperand &node) = 0;

	//! visit a Reference node
	/** @param node node that gets visited.
	 */
	virtual void visit(Reference &node) = 0;

	//! visit a Register node
	/** @param node node that gets visited.
	 */
	virtual void visit(Register &node) = 0;

	//! visit a Data node
	/** @param node node that gets visited.
	 */
	virtual void visit(Data &node) = 0;

	//! visit a TypeElement node
	/** @param node node that gets visited.
	 */
	virtual void visit(TypeElement &node) = 0;

	//! visit a Type node
	/** @param node node that gets visited.
	 */
	virtual void visit(Type &node) = 0;

protected:
	//! Travers a list of nodes.
	/** Traverse the the list l.
	 *  @param l list to traverse. Must be of any type that supports
	 *         a forward const_iterator.
	 */
	template <typename T>
	void listTraverse(T &l);
};

}; /* namespace intermediate */

#include "intermediate/visitor/Visitor.tpp"

#endif /* __VISITOR_HPP_INCLUDED */
