// Copyright (c) 2002 Hitoshi Guutara Maruyama. // This is free software; for terms and warranty disclaimer see ./COPYING. package jp.sourceforge.glj.lisp; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import gnu.expr.Language; import kawa.standard.Scheme; import gnu.kawa.lispexpr.LispReader; import gnu.mapping.InPort; import gnu.text.SyntaxException; import gnu.lists.LList; import gnu.lists.Pair; public class Lisp { public static final Object nil = (Object)LList.Empty; public static LList read(Reader reader) throws IOException, SyntaxException { if (reader == null) { return (LList)nil; } InPort port = new InPort(reader); return read(port); } public static LList read(InputStream stream) throws IOException, SyntaxException { if (stream == null) { return (LList)nil; } InPort port = new InPort(stream); return read(port); } static LList read(InPort port) throws IOException, SyntaxException { Object obj = null; Language.setDefaultLanguage(new Scheme()); LispReader lispReader = new LispReader(port); obj = lispReader.readObject(); return (LList)obj; } public static boolean isAtom(Object obj) { return !(obj instanceof Pair); } public static boolean isList(Object obj) { return (obj instanceof LList); } public static boolean isNil(Object obj) { return (obj instanceof LList && ((LList)obj).isEmpty()); } public static boolean isPair(Object obj) { return (isList(obj) && !isNil(obj)); } public static Object car(Object list) { if (list instanceof Pair) { return ((Pair)list).car; } else { return nil; } } public static Object cdr(Object list) { if (list instanceof Pair) { return ((Pair)list).cdr; } else { return nil; } } public static Pair cons(Object car, Object cdr) { return new Pair(car, cdr); } public static Pair list(Object car, Object cadr) { return new Pair(car, new Pair(cadr, LList.Empty)); } public static LList remove(Object obj, LList list) { if (list.isEmpty()) { return list; } if (obj.equals(((Pair)list).car)) { return remove(obj, (LList)cdr(list)); } return new Pair(car(list), remove(obj, (LList)cdr(list))); } public static LList merge(LList list1, LList list2) { if (list1.isEmpty()) { return list2; } return merge((LList)cdr(list1), insert(car(list1), list2)); } public static LList insert(Object obj, LList list) { if (list.contains(obj)) { return list; } return ((LList)(new Pair(obj, list))); } public static LList append(LList list1, LList list2) { if (list1.isEmpty()) { return list2; } if (list2.isEmpty()) { return list1; } LList revList = reverse(list1); for (int i = 0; i < list2.size(); i++) { revList = new Pair(list2.get(i), revList); } return reverse(revList); } public static LList reverse(LList list) { if (list.isEmpty()) { return list; } LList retList = LList.Empty; for (int i = 0, n = list.size(); i < n; i++) { retList = new Pair(list.get(i), retList); } return retList; } public static LList assoc(Object obj, LList list) { if (list == null || list.isEmpty()) { return (LList)nil; } for (int i = 0; i < ((Pair)list).size(); i++) { Object part = list.get(i); if (!(part instanceof Pair)) { return (LList)nil; } if (obj.equals(car(part))) { return ((LList)part); } } return (LList)nil; } public static LList member(Object obj, LList list) { if (list == null || list.isEmpty()) { return (LList)nil; } if (car(list).equals(obj)) { return list; } for (list = (LList)cdr(list); list instanceof Pair; list = (LList)cdr(list)) { if (car(list).equals(obj)) { return list; } } return (LList)nil; } public static LList subst(Object newObj, Object oldObj, LList list) { if (list.isEmpty()) { return list; } LList retList = LList.Empty; for (int i = 0; i < list.size(); i++) { if (((Pair)list).get(i) instanceof LList) { retList = append(retList, new Pair(subst(newObj, oldObj, (LList)((Pair)list).get(i)), LList.Empty)); } else if (oldObj.equals(((Pair)list).get(i))) { retList = append(retList, new Pair(newObj, LList.Empty)); } else { retList = append(retList, new Pair(((Pair)list).get(i), LList.Empty)); } } return retList; } public static LList lastPair(LList list) { if (list.isEmpty()) { return list; } if (isPair(cdr(list))) { return lastPair((LList)cdr(list)); } return list; } public static Object nthCdr(int count, Object list) { if (!isList(list)) { return list; } for (int i = 0; i < count; i++) { if (isNil(list)) { return list; } list = cdr(list); } return list; } }