// Path: src/main/java/net/liujiacai/jcscheme/util/JCConstants.java
// public class JCConstants {
// 		
// 	public static final String START_TOKEN = "(";
// 	public static final String END_TOKEN = ")";
// 
//     // bool functions
//     public static final String AND = "and";
//     public static final String OR = "or";
//     public static final String NOT = "not";
// 
//     // number functions
// 	public static final String ADD = "+";
// 	public static final String SUB = "-";
// 	public static final String MUL = "*";
// 	public static final String DIV = "/";
//     public static final String GT = ">";
//     public static final String LT = "<";
//     public static final String EQ = "=";
//     // pair functions
//     public static final String CONS = "cons";
//     public static final String CAR = "car";
// 	public static final String CDR = "cdr";
// 	public static final String LIST = "list";
// 	public static final String NULL = "null?";
//     // string functions
// 	public static final String STR_EQ = "str=?";
// 
//     // builtin helper functions
//     public static final String PRINT = "print";
// 
// 	// builtin keywords
// 	public static final String DEF = "def";
// 	public static final String IF = "if";
// 	public static final String LAMBDA = "lambda";
// 
// 	// builtin literals
// 	public static final String NIL = "nil";
// 	public static final String TRUE = "true";
// 	public static final String FALSE = "false";
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/exception/IllegalExpressionException.java
// public class IllegalExpressionException extends Exception {
//     public IllegalExpressionException() {
//     }
// 
//     public IllegalExpressionException(String message) {
//         super(message);
//     }
// 
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/exception/WrongNumberArgsException.java
// public class WrongNumberArgsException extends Exception {
// 
//     private String methodName;
//     private int expected;
//     private int actual;
// 
//     public WrongNumberArgsException(String methodName, int actual, int expected) {
//         this.methodName = methodName;
//         this.actual = actual;
//         this.expected = expected;
// 
//     }
// 
//     @Override
//     public String toString() {
//         return methodName + " need " + actual + " params, but passed in " + expected;
//     }
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/type/JCList.java
// public class JCList extends JCPair {
// 
//     private static final JCList NIL = new JCList(null, null);
//     public  static JCList getNullList() {
//         return NIL;
//     }
// 
//     public JCList(JCObject first, JCObject second) {
//         super(first, second);
//     }
// 
//     @Override
//     public String toString() {
//         JCObject first = this.getFirst();
//         StringBuffer buffer;
//         if (first == null) {
//             buffer = new StringBuffer("(");
//         } else {
//             buffer = new StringBuffer("(" + first);
//         }
// 
//         JCPair rest = (JCPair) this.getSecond();
//         while (rest != null && rest.getFirst() != null) {
//             buffer.append(", " + rest.getFirst().toString());
//             rest = (JCPair) rest.getSecond();
//         }
//         buffer.append(")");
//         return buffer.toString();
//     }
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/type/JCObject.java
// public abstract class JCObject {
// 
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/type/JCPair.java
// public class JCPair extends JCObject {
// 	private JCObject first;
// 	private JCObject second;
// 
// 	public JCPair(JCObject first, JCObject second) {
// 		this.first = first;
// 		this.second = second;
// 	}
// 
// 	public JCObject getFirst() {
// 		return first;
// 	}
// 
// 	public JCObject getSecond() {
// 		return second;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "[" + first + ", " + second + "]";
// 
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (obj != null && (obj instanceof JCPair)) {
//             JCPair pair = (JCPair) obj;
//             return pair.toString().equals(this.toString());
//         } else {
//             return false;
//         }
// 	}
// 
// }


import net.liujiacai.jcscheme.util.JCConstants;
import net.liujiacai.jcscheme.exception.IllegalExpressionException;
import net.liujiacai.jcscheme.exception.WrongNumberArgsException;
import net.liujiacai.jcscheme.type.JCList;
import net.liujiacai.jcscheme.type.JCObject;
import net.liujiacai.jcscheme.type.JCPair;
package net.liujiacai.jcscheme.builtin;


public class JCPairFuncs {

    public static JCPair cons(JCObject... args) {
        if (args.length == 2) {
            JCObject fir = args[0];
            JCObject sec = args[1];
            if (sec instanceof JCList) {
                return new JCList(fir, sec);
            } else {
                return new JCPair(fir, sec);
            }
        } else {
            try {
                throw new IllegalExpressionException("illegal " + JCConstants.CONS +
                        " exp. (cons <first> <second>)");
            } catch (IllegalExpressionException e) {
                e.printStackTrace();

            } finally {
// Path: src/main/java/net/liujiacai/jcscheme/util/JCConstants.java
// public class JCConstants {
// 		
// 	public static final String START_TOKEN = "(";
// 	public static final String END_TOKEN = ")";
// 
//     // bool functions
//     public static final String AND = "and";
//     public static final String OR = "or";
//     public static final String NOT = "not";
// 
//     // number functions
// 	public static final String ADD = "+";
// 	public static final String SUB = "-";
// 	public static final String MUL = "*";
// 	public static final String DIV = "/";
//     public static final String GT = ">";
//     public static final String LT = "<";
//     public static final String EQ = "=";
//     // pair functions
//     public static final String CONS = "cons";
//     public static final String CAR = "car";
// 	public static final String CDR = "cdr";
// 	public static final String LIST = "list";
// 	public static final String NULL = "null?";
//     // string functions
// 	public static final String STR_EQ = "str=?";
// 
//     // builtin helper functions
//     public static final String PRINT = "print";
// 
// 	// builtin keywords
// 	public static final String DEF = "def";
// 	public static final String IF = "if";
// 	public static final String LAMBDA = "lambda";
// 
// 	// builtin literals
// 	public static final String NIL = "nil";
// 	public static final String TRUE = "true";
// 	public static final String FALSE = "false";
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/exception/IllegalExpressionException.java
// public class IllegalExpressionException extends Exception {
//     public IllegalExpressionException() {
//     }
// 
//     public IllegalExpressionException(String message) {
//         super(message);
//     }
// 
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/exception/WrongNumberArgsException.java
// public class WrongNumberArgsException extends Exception {
// 
//     private String methodName;
//     private int expected;
//     private int actual;
// 
//     public WrongNumberArgsException(String methodName, int actual, int expected) {
//         this.methodName = methodName;
//         this.actual = actual;
//         this.expected = expected;
// 
//     }
// 
//     @Override
//     public String toString() {
//         return methodName + " need " + actual + " params, but passed in " + expected;
//     }
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/type/JCList.java
// public class JCList extends JCPair {
// 
//     private static final JCList NIL = new JCList(null, null);
//     public  static JCList getNullList() {
//         return NIL;
//     }
// 
//     public JCList(JCObject first, JCObject second) {
//         super(first, second);
//     }
// 
//     @Override
//     public String toString() {
//         JCObject first = this.getFirst();
//         StringBuffer buffer;
//         if (first == null) {
//             buffer = new StringBuffer("(");
//         } else {
//             buffer = new StringBuffer("(" + first);
//         }
// 
//         JCPair rest = (JCPair) this.getSecond();
//         while (rest != null && rest.getFirst() != null) {
//             buffer.append(", " + rest.getFirst().toString());
//             rest = (JCPair) rest.getSecond();
//         }
//         buffer.append(")");
//         return buffer.toString();
//     }
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/type/JCObject.java
// public abstract class JCObject {
// 
// }
// 
// Path: src/main/java/net/liujiacai/jcscheme/type/JCPair.java
// public class JCPair extends JCObject {
// 	private JCObject first;
// 	private JCObject second;
// 
// 	public JCPair(JCObject first, JCObject second) {
// 		this.first = first;
// 		this.second = second;
// 	}
// 
// 	public JCObject getFirst() {
// 		return first;
// 	}
// 
// 	public JCObject getSecond() {
// 		return second;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "[" + first + ", " + second + "]";
// 
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (obj != null && (obj instanceof JCPair)) {
//             JCPair pair = (JCPair) obj;
//             return pair.toString().equals(this.toString());
//         } else {
//             return false;
//         }
// 	}
// 
// }


// Path: src/main/java/net/liujiacai/jcscheme/builtin/JCPairFuncs.java
import net.liujiacai.jcscheme.util.JCConstants;
import net.liujiacai.jcscheme.exception.IllegalExpressionException;
import net.liujiacai.jcscheme.exception.WrongNumberArgsException;
import net.liujiacai.jcscheme.type.JCList;
import net.liujiacai.jcscheme.type.JCObject;
import net.liujiacai.jcscheme.type.JCPair;

package net.liujiacai.jcscheme.builtin;


public class JCPairFuncs {

    public static JCPair cons(JCObject... args) {
        if (args.length == 2) {
            JCObject fir = args[0];
            JCObject sec = args[1];
            if (sec instanceof JCList) {
                return new JCList(fir, sec);
            } else {
                return new JCPair(fir, sec);
            }
        } else {
            try {
                throw new IllegalExpressionException("illegal " + JCConstants.CONS +
                        " exp. (cons <first> <second>)");
            } catch (IllegalExpressionException e) {
                e.printStackTrace();

            } finally {
                System.exit(1);