/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Morten Jorgensen
 * @author Erwin Bolwidt <ejb@klomp.org>
 *
 */

package org.apache.xalan.xsltc.compiler;

import java.util.Vector;

import org.apache.bcel.generic.BranchHandle;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.GOTO_W;
import org.apache.bcel.generic.IFEQ;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.xalan.xsltc.compiler.util.BooleanType;
import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
import org.apache.xalan.xsltc.compiler.util.MethodType;
import org.apache.xalan.xsltc.compiler.util.NodeSetType;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;

abstract class Expression extends SyntaxTreeNode {
    /**
     * The type of this expression. It is set after calling 
     * <code>typeCheck()</code>.
     */
    protected Type _type;

    /**
     * True if this expression is of node-set type and its corresponding
     * iterator has been started or reset.
     */
    protected boolean _startReset = false;

    /**
     * Instruction handles that comprise the true list.
     */
    protected FlowList _trueList = new FlowList();

    /**
     * Instruction handles that comprise the false list.
     */
    protected FlowList _falseList = new FlowList();

    public Type getType() {
	return _type;
    }

    public abstract String toString();

    public boolean hasPositionCall() {
	return false;		// default should be 'false' for StepPattern
    }

    public boolean hasLastCall() {
	return false;
    }
		
    /**
     * Returns an object representing the compile-time evaluation 
     * of an expression. We are only using this for function-available
     * and element-available at this time.
     */
    public Object evaluateAtCompileTime() {
	return null;
    }

    /**
     * Type check all the children of this node.
     */
    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
	return typeCheckContents(stable);
    }

    /**
     * Translate this node into JVM bytecodes.
     */
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
	ErrorMsg msg = new ErrorMsg(ErrorMsg.NOT_IMPLEMENTED_ERR,
				    getClass(), this);
	getParser().reportError(FATAL, msg);
    }
	
    /**
     * Translate this node into a fresh instruction list.
     * The original instruction list is saved and restored.
     */
    public final InstructionList compile(ClassGenerator classGen,
					 MethodGenerator methodGen) {
	final InstructionList result, save = methodGen.getInstructionList();
	methodGen.setInstructionList(result = new InstructionList());
	translate(classGen, methodGen);
	methodGen.setInstructionList(save);
	return result;
    }

    /**
     * Redefined by expressions of type boolean that use flow lists.
     */
    public void translateDesynthesized(ClassGenerator classGen,
				       MethodGenerator methodGen) {
	translate(classGen, methodGen);
	if (_type instanceof BooleanType) {
	    desynthesize(classGen, methodGen);
	}
    }

    /**
     * Expects an object on the stack and if this object can be proven
     * to be a node iterator then the iterator is reset or started
     * depending on the type of this expression.
     * If this expression is a var reference then the iterator 
     * is reset, otherwise it is started.
     */
    public void startResetIterator(ClassGenerator classGen,
				   MethodGenerator methodGen) {
	final ConstantPoolGen cpg = classGen.getConstantPool();
	final InstructionList il = methodGen.getInstructionList();

	if (_startReset) {
	    return;			// already started
	}
	_startReset = true;

	if (_type instanceof NodeSetType == false) {
	    return;		// nothing to do
	}

	Expression expr = this;
	if (expr instanceof CastExpr)
	    expr = ((CastExpr)expr).getExpr();
	if ( (expr instanceof VariableRefBase) == false ) {
	    il.append(methodGen.loadContextNode());
	    il.append(methodGen.setStartNode());
	}
    }

    /**
     * Synthesize a boolean expression, i.e., either push a 0 or 1 onto the 
     * operand stack for the next statement to succeed. Returns the handle
     * of the instruction to be backpatched.
     */
    public void synthesize(ClassGenerator classGen, MethodGenerator methodGen) {
	final ConstantPoolGen cpg = classGen.getConstantPool();
	final InstructionList il = methodGen.getInstructionList();
	_trueList.backPatch(il.append(ICONST_1));
	final BranchHandle truec = il.append(new GOTO_W(null));
	_falseList.backPatch(il.append(ICONST_0));
	truec.setTarget(il.append(NOP));
    }

    public void desynthesize(ClassGenerator classGen,
			     MethodGenerator methodGen) {
	final InstructionList il = methodGen.getInstructionList();
	_falseList.add(il.append(new IFEQ(null)));
    }

    public FlowList getFalseList() {
	return _falseList;
    }

    public FlowList getTrueList() {
	return _trueList;
    }

    public void backPatchFalseList(InstructionHandle ih) {
	_falseList.backPatch(ih);
    }

    public void backPatchTrueList(InstructionHandle ih) {
	_trueList.backPatch(ih);
    }

    /**
     * Search for a primop in the symbol table that matches the method type 
     * <code>ctype</code>. Two methods match if they have the same arity.
     * If a primop is overloaded then the "closest match" is returned. The
     * first entry in the vector of primops that has the right arity is 
     * considered to be the default one.
     */
    public MethodType lookupPrimop(SymbolTable stable, String op,
				   MethodType ctype) {
	MethodType result = null;
	final Vector primop = stable.lookupPrimop(op);
	if (primop != null) {
	    final int n = primop.size();
	    int minDistance = Integer.MAX_VALUE;
	    for (int i = 0; i < n; i++) {
		final MethodType ptype = (MethodType) primop.elementAt(i);
		// Skip if different arity
		if (ptype.argsCount() != ctype.argsCount()) {
		    continue;
		}
				
		// The first method with the right arity is the default
		if (result == null) {
		    result = ptype;		// default method
		}

		// Check if better than last one found
		final int distance = ctype.distanceTo(ptype);
		if (distance < minDistance) {
		    minDistance = distance;
		    result = ptype;
		}
	    }		
	}	
	return result;
    }	
}
