/**
 * This file is part of Erjang - A JVM-based Erlang VM
 *
 * Copyright (c) 2009 by Trifork
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

package erjang;

import java.nio.ByteBuffer;
import java.util.List;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

public class ENil extends ESeq {

	private static final Type ENIL_TYPE = Type.getType(ENil.class);
	private static final Type ERT_TYPE = Type.getType(ERT.class);
	
	public ENil() {
		super();
	}

	public boolean isNil() {
		return true;
	}

	public String stringValue() {
		return "";
	}


	@Override
	public EObject head() {
		throw new UnsupportedOperationException();
	}

	@Override
	public EList tail() {
		throw new UnsupportedOperationException();
	}
	
	public boolean collectIOList(List<ByteBuffer> out) {
		return true;
	}

	@Override
	public void collectCharList(CharCollector out) {
	}

	@Override
	public String toString() {
		return "[]";
	}

	@Override
	public EList cons(EObject h) {
		return new EList(h, this);
	}

	@Override
	public Type emit_const(MethodVisitor fa) {
		fa.visitFieldInsn(Opcodes.GETSTATIC, ERT_TYPE.getInternalName(), "NIL", ENIL_TYPE.getDescriptor());
		return ENIL_TYPE;
	}
	
	public ENil testNil() {
		return this;
	}

	/* (non-Javadoc)
	 * @see erjang.EObject#compare_same(erjang.EObject)
	 */
	@Override
	int compare_same(EObject rhs) {
		if (rhs.testNil() != null) return 0;
		return -1;
	}
	
	@Override
	public void encode(EOutputStream eos) {
		eos.write_nil();
	}
	
	@Override
	public ESeq prepend(ESeq list) {
		return list;
	}
}

@@ -2102,10 +2102,330 @@
 ist;%0A%09%7D%0A
+%09%0A%09@Override%0A%09public boolean equalsExactly(EObject rhs) %7B%0A%09%09return rhs.isNil();%0A%09%7D%0A%09%0A%09@Override%0A%09public boolean equals(EObject other) %7B%0A%09%09return other.isNil();%0A%09%7D%0A%09%0A%09@Override%0A%09public boolean equals(Object other) %7B%0A%09%09if (other instanceof EObject) %7B%0A%09%09%09return ((EObject)other).isNil();%0A%09%09%7D else %7B%0A%09%09%09return false;%0A%09%09%7D%0A%09%7D%0A
 %7D%0A

Fix nil equals; so that it uses isNil on "other" object.