package code.term;

import code.instr.Instruction;
import code.table.UndefinedSymbol;
import code.term.visitor.TermVisitor;

/**
 * The interface that all term implmentation must implement.
 * This interface just has data accessor methods (except for accept).
 * All methods that perform "actions" on the implementation
 * are put into vistors and utilize the implementations
 * accept method.
 *
 * @author Sergio Antoy
 * @since June 17, 2003
 */
public interface TermImpl {

    /**
     * Returns the root id for this term.
     *
     * @return The root value
     */
    int getRoot();

    /**
     * Returns the root symbol.
     *
     * @return The rootSymbol value
     */
    String getRootSymbol();


    /**
     * Returns the list of arguments for this term.
     *
     * @return The argument value
     */
    Term[] getArgument();


    /**
     * Gets the argument attribute of the TermImpl object
     *
     * @param number Description of the Parameter
     * @return The argument value
     */
    Term getArgument(byte number);


    /**
     * Gets the kind attribute of the TermImpl object
     *
     * @return The kind value
     * @throws UndefinedSymbol Description of the Exception
     */
    byte getKind() throws UndefinedSymbol;


    /**
     * Gets the hNF attribute of the TermImpl object
     *
     * @return The hNF value
     */
    boolean isHNF();


    /**
     * Gets the nF attribute of the TermImpl object
     *
     * @return The nF value
     */
    boolean isNF();


    /**
     * Gets the code attribute of the TermImpl object
     *
     * @return The code value
     * @throws UndefinedSymbol Description of the Exception
     */
    Instruction[] getCode() throws UndefinedSymbol;

    /**
     * This method accepts the visitor.  The code for
     * this method should be return v.accept(this,o);
     *
     * @param v
     * @param o
     * @return Object
     */
    <R,T> R accept(TermVisitor<R,T> v, T o);

}

