|
@@ -1,14 +1,21 @@
|
|
|
package migl.lisp;
|
|
|
|
|
|
import java.math.BigInteger;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.HashMap;
|
|
|
|
|
|
/**
|
|
|
- * Class pour gérer le parse des elements des expressions lisp
|
|
|
- * Utilisation d'une class pour éviter d'avoir un code smell sur sonar
|
|
|
+ * Class pour gérer les élément des expressions Lisp
|
|
|
*
|
|
|
* @author Arthur Brandao
|
|
|
*/
|
|
|
+@SuppressWarnings("unchecked")
|
|
|
public class LispElement<E> {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Garde en cache les elements deja créer pour eviter de recreer plusieurs fois les meme elements
|
|
|
+ */
|
|
|
+ private static Map<Object, LispElement<?>> cache = new HashMap<>();
|
|
|
|
|
|
/**
|
|
|
* La valeur de l'element
|
|
@@ -21,6 +28,62 @@ public class LispElement<E> {
|
|
|
*/
|
|
|
private LispElement(E val) {
|
|
|
this.value = val;
|
|
|
+ cache.put(val, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Retourne la valeur d'un element sous forme de nombre
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public double getNumber() {
|
|
|
+ if(this.value.getClass() == BigInteger.class) {
|
|
|
+ BigInteger bi = (BigInteger) this.value;
|
|
|
+ return bi.doubleValue();
|
|
|
+ } else if(this.value.getClass() == Double.class) {
|
|
|
+ return (double) this.value;
|
|
|
+ }
|
|
|
+ throw new IllegalStateException("Value is not a number");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Retourne la valeur d'un element sous forme de boolean
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean getBool() {
|
|
|
+ if(this.value.getClass() == LispBoolean.class) {
|
|
|
+ LispBoolean lb = (LispBoolean) this.value;
|
|
|
+ return lb.value();
|
|
|
+ }
|
|
|
+ throw new IllegalStateException("Value is not a Lisp boolean");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Retourne la valeur d'un element sous forme de string
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String getString() {
|
|
|
+ if(this.value.getClass() == String.class) {
|
|
|
+ return (String) this.value;
|
|
|
+ }
|
|
|
+ throw new IllegalStateException("Value is not a String");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int hashCode() {
|
|
|
+ return this.value.hashCode();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean equals(Object obj) {
|
|
|
+ return this.value.equals(obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String toString() {
|
|
|
+ return this.value.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -28,23 +91,44 @@ public class LispElement<E> {
|
|
|
* @param elt L'element à parser
|
|
|
* @return Un LispElement contenant la valeur extraite
|
|
|
*/
|
|
|
- public static LispElement valueOf(String elt) {
|
|
|
+ public static <T> LispElement<T> valueOf(String elt) {
|
|
|
try {
|
|
|
- return new LispElement(new BigInteger(elt));
|
|
|
+ return generate(new BigInteger(elt));
|
|
|
} catch(NumberFormatException ex) {
|
|
|
//Rien
|
|
|
}
|
|
|
try {
|
|
|
- return new LispElement(Double.valueOf(elt));
|
|
|
+ return generate(Double.valueOf(elt));
|
|
|
} catch(NumberFormatException ex) {
|
|
|
//Rien
|
|
|
}
|
|
|
try {
|
|
|
- return new LispElement(LispBoolean.valueOf(elt));
|
|
|
+ return generate(LispBoolean.valueOf(elt));
|
|
|
} catch(IllegalArgumentException ex) {
|
|
|
//Rien
|
|
|
}
|
|
|
- return new LispElement(elt);
|
|
|
+ return generate(elt);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Genere un LispElement correspondant à l'objet
|
|
|
+ * @param elt
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static <T> LispElement<T> generate(Object elt) {
|
|
|
+ if(elt.getClass() == Integer.class) {
|
|
|
+ elt = BigInteger.valueOf((Integer) elt);
|
|
|
+ }
|
|
|
+ else if(elt.getClass() == Boolean.class) {
|
|
|
+ elt = LispBoolean.valueOf((boolean) elt);
|
|
|
+ }
|
|
|
+ else if(elt.getClass() != BigInteger.class && elt.getClass() != Double.class && elt.getClass() != LispBoolean.class && elt.getClass() != String.class) {
|
|
|
+ throw new IllegalArgumentException("Object class is not a Lisp element");
|
|
|
+ }
|
|
|
+ if(cache.containsKey(elt)) {
|
|
|
+ return (LispElement<T>) cache.get(elt);
|
|
|
+ }
|
|
|
+ return new LispElement<>((T) elt);
|
|
|
}
|
|
|
|
|
|
}
|