|
@@ -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;
|
|
|
}
|
|
|
|
|
|
}
|