Răsfoiți Sursa

Amélioration LispElement pour faciliter l'evaluation

Arthur Brandao 6 ani în urmă
părinte
comite
ca2247f085
1 a modificat fișierele cu 91 adăugiri și 7 ștergeri
  1. 91 7
      src/migl/lisp/LispElement.java

+ 91 - 7
src/migl/lisp/LispElement.java

@@ -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);
 	}
 
 }