001    import sexp.SEmpty;
002    import sexp.SExp;
003    import sexp.SExpVisitor;
004    import sexp.SList;
005    import sexp.SNonEmpty;
006    import sexp.SString;
007    import sexp.SSymbol;
008    
009    
010    
011    public class SExpUtil {
012    
013        public static SList append(SList l1, SList l2) {
014            if (l1.isEmpty()) return l2;
015            else return new SNonEmpty(l1.first(), append(l1.rest(), l2));
016        }
017        
018        public static SList flatten(SExp sexp) {
019            return sexp.accept(new SExpVisitor<SList>() {
020                public SList visit(SList sexp) {
021                    if (sexp.isEmpty()) return sexp;
022                    return append(sexp.first().accept(this), sexp.rest().accept(this));
023                }
024    
025                public SList visit(SString sexp) {
026                    return new SNonEmpty(sexp, new SEmpty());
027                }
028    
029                public SList visit(SSymbol sexp) {
030                    return new SNonEmpty(sexp, new SEmpty());
031                }
032                
033            });
034        }
035    }