package code.symbols;

import code.instr.Instruction;
import code.type.TypeExpression;
import code.table.ModuleTable;

/**
 * Abstracts a symbol that can produce data.
 *
 * @author jimeng
 * @since October 22, 2002
 */

public abstract class DataSymbol extends Symbol {

    // Constants defined as static data members of this class.
    
    public final static int toplevel = 0;

    // Possible values of kind
    // Individual constructors have an individual kind starting
    // with DataSymbol.Constructor and up.
    public final static int Operation = -1;
    public final static int UnboundVariable = 0;
    public final static int Failure = 1;
    public final static int Constructor = Failure + 1;

    // Associativity constants of infix symbols
    public final static int Left = 0;
    public final static int Right = Left + 1;
    public final static int NonAssoc = Right + 1;
    /**
     * Associativity and Precedence of non-infix symbols
     */
    public final static int NonInfix = NonAssoc + 1;

    // Data Members of each Symbol Object

    public final int staticNestingDepth;
    public final byte arity;
    public final byte kind;
    public final byte associativity;

    /**
     * precedence is an int so that one can leave "gaps" in the assigned precedence values
     * and later when a new operation requires to occupy a position between the gaps it can do so readily.
     * just like Basic :-)
     */
    public final int precedence;

    public final TypeExpression typeExp;
    public final Instruction[] code;

    /*
     *  Indicates if the vm should break every time a
     *  term with this as the root symbol should break.
     */
    public boolean breakOnExec = false;

    /**
     * Constructor for the DataSymbol object
     *
     * @param moduleName         Symbol's ModuleName.
     * @param symbolName         Symbol's Name.
     * @param visibility         Symbol's Visibility.
     * @param typeExp            Symbol's type expression.
     * @param precedence         Symbol's precedence.
     * @param associativity      Symbol's associativity.
     * @param staticNestingDepth Symbol's static nesting depth.
     * @param arity              Symbol's arity.
     * @param kind               Symbol's kind.
     * @param code               Symbol's code.
     */
    public DataSymbol(String moduleName, 
		      String symbolName,
		      int staticNestingDepth,
		      int arity,
		      int kind,
		      int associativity,
		      int precedence,
		      int visibility,
		      TypeExpression typeExp,
		      Instruction[] code) {
        super(moduleName, symbolName, visibility);
        this.staticNestingDepth = staticNestingDepth;
        this.arity = (byte) arity;
        this.kind = (byte) kind;
        this.associativity = (byte) associativity;
        this.precedence = precedence;
        this.typeExp = typeExp;
        this.code = code;
    }

    public abstract Object accept(SymbolVisitor v, Object o);
}

