|  | @@ -2,18 +2,13 @@ package migl.lisp;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import java.math.BigInteger;
 | 
	
		
			
				|  |  |  import java.util.HashMap;
 | 
	
		
			
				|  |  | -import java.util.LinkedList;
 | 
	
		
			
				|  |  |  import java.util.Map;
 | 
	
		
			
				|  |  | -import java.util.Queue;
 | 
	
		
			
				|  |  | -import java.util.regex.Matcher;
 | 
	
		
			
				|  |  | -import java.util.regex.Pattern;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import migl.lisp.operator.ComparatorOperator;
 | 
	
		
			
				|  |  |  import migl.lisp.operator.ConsOperator;
 | 
	
		
			
				|  |  |  import migl.lisp.operator.DefineOperator;
 | 
	
		
			
				|  |  |  import migl.lisp.operator.MinMaxOperator;
 | 
	
		
			
				|  |  |  import migl.util.ConsList;
 | 
	
		
			
				|  |  | -import migl.util.ConsListFactory;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  public class LispImpl implements Lisp {
 | 
	
		
			
				|  |  |  	
 | 
	
	
		
			
				|  | @@ -152,25 +147,11 @@ public class LispImpl implements Lisp {
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	@Override
 | 
	
		
			
				|  |  |  	public Object parse(String expr) throws LispError {
 | 
	
		
			
				|  |  | -		//Analyse l'expression
 | 
	
		
			
				|  |  | -		if(!this.verify(expr)) {
 | 
	
		
			
				|  |  | +		LispParser lp = new LispParser(expr);
 | 
	
		
			
				|  |  | +		if(!lp.verify()) {
 | 
	
		
			
				|  |  |  			throw new LispError("Invalid Format");
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		//Remplace les nil par ()
 | 
	
		
			
				|  |  | -		expr = expr.replaceAll(" nil ", " () ").replaceAll("\\(nil ", "(() ").replaceAll(" nil\\)", " ())");
 | 
	
		
			
				|  |  | -		//Explose l'expression
 | 
	
		
			
				|  |  | -		Queue<String> explode = this.explode(expr);
 | 
	
		
			
				|  |  | -		//Analyse le type d'expression
 | 
	
		
			
				|  |  | -		String val = explode.poll();
 | 
	
		
			
				|  |  | -		if("(".equals(val)){
 | 
	
		
			
				|  |  | -			return this.parseList(explode);
 | 
	
		
			
				|  |  | -		} else {
 | 
	
		
			
				|  |  | -			//Element seul
 | 
	
		
			
				|  |  | -			if(explode.size() > 0) {
 | 
	
		
			
				|  |  | -				throw new LispError("Invalid Format");
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			return LispElement.valueOf(val).value;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | +		return lp.parse();
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	@Override
 | 
	
	
		
			
				|  | @@ -189,130 +170,6 @@ public class LispImpl implements Lisp {
 | 
	
		
			
				|  |  |  		
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | -	/* --- Verification --- */
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	/**
 | 
	
		
			
				|  |  | -	 * Verifie que le format d'un String correspond bien à une expression Lisp
 | 
	
		
			
				|  |  | -	 * 
 | 
	
		
			
				|  |  | -	 * @param expr Le String à examiner
 | 
	
		
			
				|  |  | -	 * @return
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	private boolean verify(String expr) {
 | 
	
		
			
				|  |  | -		expr = expr.trim();
 | 
	
		
			
				|  |  | -		//Pas vide
 | 
	
		
			
				|  |  | -		if(expr.length() == 0) {
 | 
	
		
			
				|  |  | -			return false;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		//Liste ou element
 | 
	
		
			
				|  |  | -		if(expr.charAt(0) == '(') {
 | 
	
		
			
				|  |  | -			return this.verifyList(expr);
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		return this.verifyElement(expr);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	/**
 | 
	
		
			
				|  |  | -	 * Verifie que le format d'un String correspond bien à une liste Lisp
 | 
	
		
			
				|  |  | -	 * 
 | 
	
		
			
				|  |  | -	 * @param expr Le String à examiner
 | 
	
		
			
				|  |  | -	 * @return
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	private boolean verifyList(String expr) {
 | 
	
		
			
				|  |  | -		Pattern p = Pattern.compile("\\(([ |\t]*[A-Za-z0-9\\.\\+\\-\\/\\*<>=#!]+[ |\t]*)*\\)");
 | 
	
		
			
				|  |  | -		Matcher m = p.matcher(expr);
 | 
	
		
			
				|  |  | -		//Si pas de correspondance
 | 
	
		
			
				|  |  | -		if(!m.find()) {
 | 
	
		
			
				|  |  | -			return false;
 | 
	
		
			
				|  |  | -		} 
 | 
	
		
			
				|  |  | -		//Si toute la chaine
 | 
	
		
			
				|  |  | -		else if(m.end() - m.start() == expr.length()) {
 | 
	
		
			
				|  |  | -			return true;
 | 
	
		
			
				|  |  | -		} 
 | 
	
		
			
				|  |  | -		//Si commence au debut mais finit avant la fin il y a alors des elements hors de la liste
 | 
	
		
			
				|  |  | -		else if(m.start() == 0) {
 | 
	
		
			
				|  |  | -			return false;
 | 
	
		
			
				|  |  | -		} 
 | 
	
		
			
				|  |  | -		//Si il y a une liste dans la liste
 | 
	
		
			
				|  |  | -		else {
 | 
	
		
			
				|  |  | -			StringBuilder builder = new StringBuilder();
 | 
	
		
			
				|  |  | -			builder.append(expr.substring(0, m.start())).append("list").append(expr.substring(m.end()));
 | 
	
		
			
				|  |  | -			return this.verifyList(builder.toString());
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	/**
 | 
	
		
			
				|  |  | -	 * Verifie que le format d'un String correspond bien à un element Lisp
 | 
	
		
			
				|  |  | -	 * 
 | 
	
		
			
				|  |  | -	 * @param expr Le String à examiner
 | 
	
		
			
				|  |  | -	 * @return
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	private boolean verifyElement(String expr) {
 | 
	
		
			
				|  |  | -		Pattern p = Pattern.compile("[ |\t]*[A-Za-z0-9\\.\\+\\-\\/\\*<>=#]+[ |\t]*");
 | 
	
		
			
				|  |  | -		Matcher m = p.matcher(expr);
 | 
	
		
			
				|  |  | -		return m.find();
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	/* --- Parser --- */
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	/**
 | 
	
		
			
				|  |  | -	 * Découpe un string pour l'analyse Lisp
 | 
	
		
			
				|  |  | -	 * 
 | 
	
		
			
				|  |  | -	 * @param expr L'expression à analyser
 | 
	
		
			
				|  |  | -	 * @return L'expression découpée
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	private Queue<String> explode(String expr) {
 | 
	
		
			
				|  |  | -		String[] tmp = expr.trim().split("[ |\t]");
 | 
	
		
			
				|  |  | -		Queue<String> result = new LinkedList<>();
 | 
	
		
			
				|  |  | -		for(String str : tmp) {
 | 
	
		
			
				|  |  | -			char[] charArray = str.toCharArray();
 | 
	
		
			
				|  |  | -			StringBuilder builder = new StringBuilder();
 | 
	
		
			
				|  |  | -			for(char c : charArray) {
 | 
	
		
			
				|  |  | -				if(c == '(') {
 | 
	
		
			
				|  |  | -					//Si il y a une chaine dans le builder à mettre avant
 | 
	
		
			
				|  |  | -					if(builder.length() != 0) {
 | 
	
		
			
				|  |  | -						result.add(builder.toString());
 | 
	
		
			
				|  |  | -						builder = new StringBuilder();
 | 
	
		
			
				|  |  | -					}
 | 
	
		
			
				|  |  | -					result.add("" + c);
 | 
	
		
			
				|  |  | -				} else if(c == ')') {
 | 
	
		
			
				|  |  | -					//Si il y a une chaine dans le builder à mettre avant
 | 
	
		
			
				|  |  | -					if(builder.length() != 0) {
 | 
	
		
			
				|  |  | -						result.add(builder.toString());
 | 
	
		
			
				|  |  | -						builder = new StringBuilder();
 | 
	
		
			
				|  |  | -					}
 | 
	
		
			
				|  |  | -					result.add("" + c);
 | 
	
		
			
				|  |  | -				} else {
 | 
	
		
			
				|  |  | -					builder.append(c);
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			//Si il reste une chaine dans le builder à la fin
 | 
	
		
			
				|  |  | -			if(builder.length() != 0) {
 | 
	
		
			
				|  |  | -				result.add(builder.toString());
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		return result;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	/**
 | 
	
		
			
				|  |  | -	 * Parse une file d'element en Lisp
 | 
	
		
			
				|  |  | -	 * 
 | 
	
		
			
				|  |  | -	 * @param queue La file avec les valeurs récupérées {@link #explode(String)}
 | 
	
		
			
				|  |  | -	 * @return Liste d'element
 | 
	
		
			
				|  |  | -	 * @throws LispError Format invalide
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	private Object parseList(Queue<String> queue) throws LispError {
 | 
	
		
			
				|  |  | -		ConsList<Object> list = ConsListFactory.nil();
 | 
	
		
			
				|  |  | -		String val = queue.poll();
 | 
	
		
			
				|  |  | -		while(!")".equals(val)) {
 | 
	
		
			
				|  |  | -			if("(".equals(val)) {
 | 
	
		
			
				|  |  | -				list = list.append(this.parseList(queue));
 | 
	
		
			
				|  |  | -			} else {
 | 
	
		
			
				|  |  | -				list = list.append(LispElement.valueOf(val).value);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			val = queue.poll();
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		return list;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  |  	/* --- Evaluation --- */
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	/**
 |