package uk.me.nxg.unity;

import java.util.List;

/**
 * The class representing the values parsed by the grammar.
 *
 * <p>There is no type-safety managed by this class, since (a) the
 * fields are read and written directly by the generated grammar
 * classes, and (b) it's the grammar's responsibility to manage that
 * type safety (which it does, that being the point of it...).
 */
class UnitVal {
    static final char CHAR_DECA = (char)1;

    public int i;
    public double f;
    public double l10f;         // log10 of a float
    public String s;
    public OneUnit u;
    public List<OneUnit> uList;
    // the VOUnits grammar can produce a UnitExpr from the function_operand production
    public UnitExpr uExpr;
    Type type;

    public UnitVal()             { type = Type.EMPTY; } // parser includes a call to new UnitVal()
    public UnitVal(int v)        { type = Type.INTEGER; i=v; }
    public UnitVal(String v)     { type = Type.STRING;  s=v; }
    public UnitVal(OneUnit v)    { type = Type.UNIT;    u=v; }
    public UnitVal(double v)     { type = Type.DOUBLE;  f=v; }
    public UnitVal(double v, boolean is_log_p) {
        if (is_log_p) {
            type = Type.LOGDOUBLE;
            l10f = v;
        } else {
            type = Type.DOUBLE;
            f = v;
        }
    }

    public Type type() {
        return this.type;
    }

    public String toString() {
        String r = null;

        switch (type) {
          case EMPTY:
            r = "";
            break;
          case INTEGER:
            r = Integer.toString(i);
            break;
          case STRING:
            r = s;
            break;
          case UNIT:
            r = u.toString();
            break;
          case DOUBLE:
            r = Double.toString(f);
            break;
          case LOGDOUBLE:
            r = Double.toString(Math.pow(10, l10f));
            break;
          default:
            assert false;
        }
        assert r != null;
        return r;
    }

    public enum Type {
        EMPTY, INTEGER, STRING, UNIT, DOUBLE, LOGDOUBLE
    };
}
