|
@@ -3,8 +3,10 @@ package migl.lisp.operator;
|
|
|
import java.util.Map;
|
|
|
import java.util.HashMap;
|
|
|
|
|
|
+import migl.lisp.Lisp;
|
|
|
import migl.lisp.LispElement;
|
|
|
import migl.lisp.LispError;
|
|
|
+import migl.lisp.LispFactory;
|
|
|
import migl.lisp.LispImpl;
|
|
|
import migl.lisp.LispOperator;
|
|
|
import migl.util.ConsList;
|
|
@@ -20,6 +22,27 @@ public class DefineOperator implements LispOperator {
|
|
|
define.clear();
|
|
|
}
|
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static boolean isLambda(Object elt) {
|
|
|
+ if(!(elt instanceof String)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ String key = (String) elt;
|
|
|
+ ConsList<Object> cl = define.get(key);
|
|
|
+ if(cl == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(!(cl.car() instanceof ConsList)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ cl = (ConsList<Object>) cl.car();
|
|
|
+ try {
|
|
|
+ return "lambda".equals(LispElement.generate(cl.car()).toStr());
|
|
|
+ } catch (IllegalStateException ex) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@SuppressWarnings("unchecked")
|
|
|
public static LispElement eval(Object elt) throws LispError {
|
|
|
if(elt instanceof ConsList) {
|
|
@@ -50,27 +73,23 @@ public class DefineOperator implements LispOperator {
|
|
|
}
|
|
|
return LispElement.generate(lisp.car());
|
|
|
}
|
|
|
-
|
|
|
- private static LispElement evalLambda(ConsList<Object> lisp) {
|
|
|
- return null;
|
|
|
- }
|
|
|
|
|
|
@Override
|
|
|
public LispElement apply(String operator, ConsList<Object> lisp) throws LispError {
|
|
|
- if(lisp.size() != 2) {
|
|
|
- throw new LispError(LispError.ERR_NUM_ARG);
|
|
|
- }
|
|
|
switch(operator) {
|
|
|
case "define":
|
|
|
return this.define(lisp);
|
|
|
case "set!":
|
|
|
return this.set(lisp);
|
|
|
default:
|
|
|
- throw new LispError(operator + LispError.ERR_UNKNOW);
|
|
|
+ return this.lambda(operator, lisp);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private LispElement define(ConsList<Object> lisp) throws LispError {
|
|
|
+ if(lisp.size() != 2) {
|
|
|
+ throw new LispError(LispError.ERR_NUM_ARG);
|
|
|
+ }
|
|
|
//Recup la clef
|
|
|
LispElement le = LispElement.generate(lisp.car());
|
|
|
String key;
|
|
@@ -88,6 +107,9 @@ public class DefineOperator implements LispOperator {
|
|
|
}
|
|
|
|
|
|
private LispElement set(ConsList<Object> lisp) throws LispError {
|
|
|
+ if(lisp.size() != 2) {
|
|
|
+ throw new LispError(LispError.ERR_NUM_ARG);
|
|
|
+ }
|
|
|
//Recup la clef
|
|
|
String key;
|
|
|
try {
|
|
@@ -106,5 +128,35 @@ public class DefineOperator implements LispOperator {
|
|
|
//Evalue pour le retour
|
|
|
return eval(lisp.cdr());
|
|
|
}
|
|
|
+
|
|
|
+ private LispElement lambda(String operator, ConsList<Object> lisp) throws LispError {
|
|
|
+ if(!isLambda(operator)) {
|
|
|
+ throw new LispError(operator + LispError.ERR_UNKNOW);
|
|
|
+ }
|
|
|
+ //Recup les infos
|
|
|
+ ConsList<Object> lambda = (ConsList<Object>) define.get(operator).car();
|
|
|
+ ConsList<Object> param = (ConsList<Object>) lambda.cdr().car();
|
|
|
+ lambda = (ConsList<Object>) lambda.cdr().cdr().car();
|
|
|
+ System.out.println(operator);
|
|
|
+ System.out.println(lambda);
|
|
|
+ System.out.println(param);
|
|
|
+ System.out.println(lisp);
|
|
|
+ if(param.size() != lisp.size()) {
|
|
|
+ throw new LispError(LispError.ERR_NUM_ARG);
|
|
|
+ }
|
|
|
+ //Remplace les parametres
|
|
|
+ String lispExpr = lambda.toString();
|
|
|
+ while(!param.isEmpty()) {
|
|
|
+ lispExpr = lispExpr.replaceAll(" " + param.car() + " ", " " + lisp.car() + " ")
|
|
|
+ .replaceAll("\\(" + param.car() + " ", "\\(" + lisp.car() + " ")
|
|
|
+ .replaceAll(" " + param.car() + "\\)", " " + lisp.car() + "\\)");
|
|
|
+ param = param.cdr();
|
|
|
+ lisp = lisp.cdr();
|
|
|
+ }
|
|
|
+ System.out.println(lispExpr);
|
|
|
+ //Evalue le resultat
|
|
|
+ Lisp l = LispFactory.getInterpreter();
|
|
|
+ return LispElement.generate(l.eval(lispExpr));
|
|
|
+ }
|
|
|
|
|
|
}
|