package com.kreative.paint.material.shape;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public abstract class Operator {
public final int precedence;
private Operator(int precedence) {
this.precedence = precedence;
}
public abstract double eval(double a, double b);
public static final Operator or = new Operator(0) {
@Override
public double eval(double a, double b) {
return (a != 0 || b != 0) ? 1 : 0;
}
};
public static final Operator and = new Operator(5) {
@Override
public double eval(double a, double b) {
return (a != 0 && b != 0) ? 1 : 0;
}
};
public static final Operator cmp = new Operator(10) {
@Override
public double eval(double a, double b) {
return Double.compare(a, b);
}
};
public static final Operator eq = new Operator(10) {
@Override
public double eval(double a, double b) {
return (a == b) ? 1 : 0;
}
};
public static final Operator ne = new Operator(10) {
@Override
public double eval(double a, double b) {
return (a != b) ? 1 : 0;
}
};
public static final Operator lt = new Operator(15) {
@Override
public double eval(double a, double b) {
return (a < b) ? 1 : 0;
}
};
public static final Operator gt = new Operator(15) {
@Override
public double eval(double a, double b) {
return (a > b) ? 1 : 0;
}
};
public static final Operator le = new Operator(15) {
@Override
public double eval(double a, double b) {
return (a <= b) ? 1 : 0;
}
};
public static final Operator ge = new Operator(15) {
@Override
public double eval(double a, double b) {
return (a >= b) ? 1 : 0;
}
};
public static final Operator add = new Operator(20) {
@Override
public double eval(double a, double b) {
return a + b;
}
};
public static final Operator sub = new Operator(20) {
@Override
public double eval(double a, double b) {
return a - b;
}
};
public static final Operator hypot = new Operator(25) {
@Override
public double eval(double a, double b) {
return Math.hypot(a, b);
}
};
public static final Operator atan2 = new Operator(25) {
@Override
public double eval(double a, double b) {
return Math.atan2(a, b);
}
};
public static final Operator cos2 = new Operator(25) {
@Override
public double eval(double a, double b) {
return b * Math.cos(a);
}
};
public static final Operator sin2 = new Operator(25) {
@Override
public double eval(double a, double b) {
return b * Math.sin(a);
}
};
public static final Operator mul = new Operator(30) {
@Override
public double eval(double a, double b) {
return a * b;
}
};
public static final Operator div = new Operator(30) {
@Override
public double eval(double a, double b) {
return a / b;
}
};
public static final Operator idiv = new Operator(30) {
@Override
public double eval(double a, double b) {
return Math.floor(a / b);
}
};
public static final Operator mod = new Operator(30) {
@Override
public double eval(double a, double b) {
return a - b * Math.floor(a / b);
}
};
public static final Operator quot = new Operator(30) {
@Override
public double eval(double a, double b) {
double q = a / b;
if (q < 0) return Math.ceil(q);
else return Math.floor(q);
}
};
public static final Operator rem = new Operator(30) {
@Override
public double eval(double a, double b) {
double q = a / b;
if (q < 0) q = Math.ceil(q);
else q = Math.floor(q);
return a - b * q;
}
};
public static final Operator pow = new Operator(40) {
@Override
public double eval(double a, double b) {
return Math.pow(a, b);
}
};
public static final Operator root = new Operator(40) {
@Override
public double eval(double a, double b) {
return Math.pow(a, 1 / b);
}
};
public static final Operator log = new Operator(40) {
@Override
public double eval(double a, double b) {
return Math.log(a) / Math.log(b);
}
};
public static final Map<Integer,Map<String,Operator>> operators;
static {
Map<Integer,Map<String,Operator>> ops1 = new HashMap<Integer,Map<String,Operator>>();
add(ops1, or, "|", "||", "or");
add(ops1, and, "&", "&&", "and");
add(ops1, cmp, "#", "<=>", "cmp");
add(ops1, eq, "=", "==");
add(ops1, ne, "\u2260", "!=", "<>");
add(ops1, lt, "<");
add(ops1, gt, ">");
add(ops1, le, "\u2264", "<=");
add(ops1, ge, "\u2265", ">=");
add(ops1, add, "+");
add(ops1, sub, "-");
add(ops1, hypot, "@", "hypot");
add(ops1, atan2, "$", "atan2");
add(ops1, cos2, "cos2");
add(ops1, sin2, "sin2");
add(ops1, mul, "*");
add(ops1, div, "/");
add(ops1, idiv, "\\", "//", "div");
add(ops1, mod, "%", "mod");
add(ops1, quot, "quot");
add(ops1, rem, "rem");
add(ops1, pow, "^", "**", "pow");
add(ops1, root, "!", "root");
add(ops1, log, "_", "log");
Map<Integer,Map<String,Operator>> ops2 = new HashMap<Integer,Map<String,Operator>>();
for (Map.Entry<Integer,Map<String,Operator>> e : ops1.entrySet()) {
ops2.put(e.getKey(), Collections.unmodifiableMap(e.getValue()));
}
operators = Collections.unmodifiableMap(ops2);
};
private static void add(Map<Integer,Map<String,Operator>> ops, Operator op, String... names) {
if (ops.containsKey(op.precedence)) {
Map<String,Operator> o = ops.get(op.precedence);
for (String name : names) o.put(name, op);
} else {
Map<String,Operator> o = new HashMap<String,Operator>();
for (String name : names) o.put(name, op);
ops.put(op.precedence, o);
}
}
}