ソースを参照

Refactoring ConsOperator + ajout operateur car et cdr

Arthur Brandao 6 年 前
コミット
71f8ae2a7a
1 ファイル変更54 行追加23 行削除
  1. 54 23
      src/migl/lisp/operator/ConsOperator.java

+ 54 - 23
src/migl/lisp/operator/ConsOperator.java

@@ -3,47 +3,78 @@ package migl.lisp.operator;
 import migl.lisp.LispElement;
 import migl.lisp.LispError;
 import migl.lisp.LispEval;
+import migl.lisp.LispList;
 import migl.lisp.LispOperator;
+import migl.util.Cons;
 import migl.util.ConsList;
-import migl.util.ConsListFactory;
 
 public class ConsOperator implements LispOperator {
 
 	@Override
 	public LispElement apply(LispEval eval, String operator, ConsList<Object> lisp) throws LispError {
+		switch(operator) {
+			case "cons":
+				return this.cons(eval, lisp);
+			case "car":
+				return this.car(eval, lisp);
+			case "cdr":
+				return this.cdr(eval, lisp);
+			default:
+				throw new LispError(operator + LispError.ERR_UNKNOW);
+		}
+	}
+	
+	public LispElement cons(LispEval eval, ConsList<Object> lisp) throws LispError {
 		if(lisp.size() != 2) {
 			throw new LispError(LispError.ERR_NUM_ARG);
 		}
-		ConsList<Object> cl;
 		if(lisp.cdr().car() instanceof ConsList) {
 			//Recup + evaluation de la liste
-			cl = this.parseList(eval.getElement(lisp.cdr().car()).toString());
-			//Ajoute la valeur de gauche devant
-			cl = cl.prepend(eval.getElement(lisp.car()).value);
+			String listStr = eval.getElement(lisp.cdr().car()).toString();
+			LispList list = LispList.valueOf(listStr);
+			list.prepend(eval.getElement(lisp.car()).value);
+			return LispElement.generate(list);
 		} else {
-			LispElement le;
-			le = eval.getElement(lisp.car());
-			cl = ConsListFactory.asList(le + " . " + lisp.cdr().car());
+			LispElement elt = eval.getElement(lisp.car());
+			Cons<LispElement, Object> c = new Cons<>(elt, lisp.cdr().car());
+			return LispElement.generate(c);
 		}
-		return LispElement.generate(cl.toString());
 	}
 	
-	/**
-	 * Parse une chaine en ConsList
-	 * @param expr L'expression à parser
-	 * @return
-	 */
-	public ConsList<Object> parseList(String expr){
-		ConsList<Object> list = ConsListFactory.nil();
-		//Parse d'une liste simple - ToDO parse toutes sorte de liste
-		String[] tmp = expr.trim().split("[ |\t]");
-		for(String str : tmp) {
-			str = str.replaceAll("[\\(|\\)]", "").trim();
-			if(str.length() > 0) {
-				list = list.append(str);
+	public LispElement car(LispEval eval, ConsList<Object> lisp) throws LispError {
+		if(lisp.size() != 1) {
+			throw new LispError(LispError.ERR_NUM_ARG);
+		}
+		LispElement elt = eval.getElement(lisp.car());
+		if(elt.isList()) {
+			LispList list = elt.toList();
+			if(list.size() < 1) {
+				return  LispElement.generate(LispList.nil());
 			}
+			return LispElement.generate(list.get(0));
+		} else if(elt.isCons()) {
+			return LispElement.generate(elt.toCons().left());
+		} else {
+			throw new LispError(elt + LispError.ERR_INVALID);
+		}
+	}
+	
+	public LispElement cdr(LispEval eval, ConsList<Object> lisp) throws LispError {
+		if(lisp.size() != 1) {
+			throw new LispError(LispError.ERR_NUM_ARG);
+		}
+		LispElement elt = eval.getElement(lisp.car());
+		if(elt.isList()) {
+			LispList list = elt.toList();
+			if(list.size() < 2) {
+				return  LispElement.generate(LispList.nil());
+			}
+			return LispElement.generate(list.getSubList(1));
+		} else if(elt.isCons()) {
+			return LispElement.generate(elt.toCons().right());
+		} else {
+			throw new LispError(elt + LispError.ERR_INVALID);
 		}
-		return list;
 	}
 
 }