Ver Fonte

Ajout opérateur map, car et cdr

Arthur Brandao há 6 anos atrás
pai
commit
c68fbf4fb7
1 ficheiros alterados com 40 adições e 1 exclusões
  1. 40 1
      src/migl/lisp/LispEval.java

+ 40 - 1
src/migl/lisp/LispEval.java

@@ -10,6 +10,7 @@ import migl.lisp.operator.DefineOperator;
 import migl.lisp.operator.MathOperator;
 import migl.lisp.operator.MinMaxOperator;
 import migl.util.ConsList;
+import migl.util.ConsListFactory;
 
 /**
  * Evaluateur lisp
@@ -85,7 +86,10 @@ public class LispEval {
 		operators.put("define", this.define);
 		operators.put("set!", this.define);
 		operators.put("lambda", this.define);
-		operators.put("cons", new ConsOperator());
+		ConsOperator cons = new ConsOperator();
+		operators.put("cons", cons);
+		operators.put("car", cons);
+		operators.put("cdr", cons);
 		ComparatorOperator comp = new ComparatorOperator();
 		operators.put(">", comp);
 		operators.put(">=", comp);
@@ -230,6 +234,41 @@ public class LispEval {
 			}
 			return LispElement.generate(Math.pow(eval.getElement(lisp.car()).toNumber(), eval.getElement(lisp.cdr().car()).toNumber()));
 		});
+		operators.put("list", (eval, op, lisp) -> {
+			LispList list = LispList.nil();
+			while(!lisp.isEmpty()) {
+				list.append(eval.getElement(lisp.car()));
+				lisp = lisp.cdr();
+			}
+			return LispElement.generate(list);
+		});
+		operators.put("map", (eval, op, lisp) -> {
+			if(lisp.size() != 2) {
+				throw new LispError(LispError.ERR_NUM_ARG);
+			}
+			//Regarde si le parametre est une fonction lambda
+			if(!eval.getDefine().isLambda(lisp.car())) {
+				throw new LispError(lisp.car() + LispError.ERR_INVALID);
+			}
+			//Regarde si le second parametre est une expression lisp à evaluer
+			if(!(lisp.cdr().car() instanceof ConsList)) {
+				throw new LispError(lisp.cdr().car() + LispError.ERR_INVALID);
+			}
+			//Evalue l'expression la valeurs des parametres
+			@SuppressWarnings("unchecked")
+			LispElement res = eval.evaluateList((ConsList<Object>) lisp.cdr().car());
+			if(!res.isList()) {
+				return LispElement.generate(LispList.nil());
+			}
+			//Pour chaque element de la liste evalue la fonction
+			LispList result = LispList.nil();
+			LispList list = res.toList();
+			for(int i = 0; i < list.size(); i++) {
+				ConsList<Object> cl = ConsListFactory.asList(lisp.car(), list.get(i));
+				result.append(eval.evaluateList(cl));
+			}
+			return LispElement.generate(result);
+		});
 	}
 
 	/**