Arthur Brandao 6 lat temu
rodzic
commit
46c8786d91

+ 9 - 0
src/migl/lisp/LispEval.java

@@ -315,10 +315,19 @@ public class LispEval {
 	 * @return Valeur évaluer
 	 * @throws LispError
 	 */
+	@SuppressWarnings("unchecked")
 	public LispElement evaluateList(ConsList<Object> lisp) throws LispError {
+		//Expression vide
 		if(lisp.isEmpty()) {
 			return LispElement.generate("()");
 		}
+		//LCPF
+		if(lisp.car() instanceof ConsList) {
+			LispElement elt = this.evaluateList((ConsList<Object>) lisp.car());
+			ConsList<Object> cl = ConsListFactory.asList(elt.toStr(), lisp.cdr().car());
+			return this.evaluateList(cl);
+		}
+		//Recherche l'operateur
 		String operator = LispElement.generate(lisp.car()).toStr();
 		LispOperator op = this.operators.get(operator);
 		if(op == null) {

+ 35 - 2
src/migl/lisp/operator/DefineOperator.java

@@ -1,6 +1,8 @@
 package migl.lisp.operator;
 
 import java.util.Map;
+import java.util.Random;
+import java.util.ArrayList;
 import java.util.HashMap;
 
 import migl.lisp.Lisp;
@@ -8,10 +10,19 @@ import migl.lisp.LispElement;
 import migl.lisp.LispError;
 import migl.lisp.LispEval;
 import migl.util.ConsList;
+import migl.util.ConsListFactory;
 
 public class DefineOperator implements LispOperator {
 	
+	/**
+	 * Tableau des variables et fonctions définit
+	 */
 	private final Map<String, ConsList<Object>> define = new HashMap<>();
+	
+	/**
+	 * Liste des nom de variables/fonctions temporaires
+	 */
+	private final ArrayList<String> tmp = new ArrayList<>();
 
 	@Override
 	public LispElement apply(LispEval eval, String operator, ConsList<Object> lisp) throws LispError {
@@ -20,6 +31,12 @@ public class DefineOperator implements LispOperator {
 				return this.define(eval, lisp);
 			case "set!":
 				return this.set(eval, lisp);
+			case "lambda":
+				String name = this.generateRandomName();
+				ConsList<Object> lambda = ConsListFactory.asList("lambda", lisp.car(), lisp.cdr().car());
+				ConsList<Object> cl = ConsListFactory.asList("define", name, lambda);
+				eval.evaluateList(cl);
+				return LispElement.generate(name);
 			default:
 				return this.lambda(eval, operator, lisp);
 		}
@@ -123,9 +140,14 @@ public class DefineOperator implements LispOperator {
 			param = param.cdr();
 			lisp = lisp.cdr();
 		}
+		//Si c'etait une fonction temporaire
+		if(this.tmp.contains(operator)) {
+			this.tmp.remove(operator);
+			this.define.remove(operator);
+		}
 		//Evalue le resultat
-		Lisp l = eval.getInterpreter();
-		return LispElement.generate(l.eval(lispExpr));
+		Lisp interpreter = eval.getInterpreter();
+		return LispElement.generate(interpreter.eval(lispExpr));
 	}
 	
 	/**
@@ -195,5 +217,16 @@ public class DefineOperator implements LispOperator {
 		}
 		return LispElement.generate(lisp.car());
 	}
+	
+	private String generateRandomName() {
+		Random rand = new Random();
+		StringBuilder builder = new StringBuilder();
+		for(int i = 0; i < 8; i++) {
+			builder.append((char) (rand.nextInt(26) + 97));
+		}
+		String str = builder.toString();
+		this.tmp.add(str);
+		return str;
+	}
 
 }