/*
 * $Id: Evaluator.java,v 1.5 1998/10/28 23:10:37 metlov Exp $
 *
 * This file is part of the Java Expressions Library (JEL).
 *   For more information about JEL visit :
 *    http://galaxy.fzu.cz/JEL/
 *
 * (c) 1998 by Konstantin Metlov(metlov@fzu.cz);
 *
 * JEL is Distributed under the terms of GNU General Public License.
 *    This code comes with ABSOLUTELY NO WARRANTY.
 *  For license details see COPYING file in this directory.
 */

package gnu.jel; 

import gnu.jel.generated.EC;
import gnu.jel.generated.ParseException;
import gnu.jel.generated.TokenMgrError;
import gnu.jel.debug.Debug;

/**
 * This is the main front end to JEL.
 * <P>It is intended for compilation of algebraic expressions, involving 
 * functions.
 * <P> Syntax supports variables, which are, in fact, functions with no 
 * arguments. If You define such function in the static library -- it is a
 * constant (and will be substituted into expression at compile time).
 * If you define the method , such as "<TT>double x() {}</TT>;" 
 * in the dynamic
 * library class the expression "<TT>sin(x)</TT>" will call the method 
 * "<TT>x()</TT>" ( and 
 * function <TT>Math.sin()</TT> ) each time it is evaluated.
 * <P>It is possible to have any type of intermediate object
 * throughout the calculation as long as types of the function return values 
 * and parameters stay compatible.
 * <P>The variant of the "compile" function with three arguments allows
 * to fix the type of the expression result. For example :
 * <PRE>
 * CompiledExpression expression=compile("2*6+6",lib,Double.TYPE);
 * </PRE>
 * will produce compiled expression, whose return type is always 
 * <TT>double</TT>. For additional information on how to use this feature to
 * eliminate object allocation overhead see <TT>gnu.jel.CompiledExpression</TT>
 * documentation.
 * 
 * <P> Care should be taken during the assembly of static and dynamic libraries
 * to avoid conflicts and unsupported return types.
 *
 * <P>(c) 1998, by Konstantin Metlov<BR>
 * Prague, CZ
 * @see gnu.jel.CompiledExpression
 */
public class Evaluator {
  
  /**
   * Compiles expression, resolving the function names in the library.
   * @param expression is the expression to compile. i.e. "sin(666)" .
   * @param lib Library of functions exported for use in expression.
   * @param resultType identifies the type result should be converted to. Can
   *        be null, in this case the result type is not fixed.
   * @return Instance of the CompiledExpression subclass, implementing
   *   the specified expression evaluation.
   * @exception gnu.jel.CompilationException if the expression is not
   *  syntactically or semantically correct.
   * @see gnu.jel.CompiledExpression#evaluate
   */
  public static CompiledExpression compile(String expression, Library lib,
					   Class resultType) 
       throws CompilationException {
    return compileBits(expression,lib,resultType).getExpression();
  };

  /**
   * Compiles expression, resolving the function names in the library.
   * <P>This variant of compile allows to store expressions in a 
   * <TT>java.io.OutputStream</TT> using Java serialization mechanism.
   * @param expression is the expression to compile. i.e. "sin(666)" .
   * @param lib Library of functions exported for use in expression.
   * @param resultType identifies the type result should be converted to. Can
   *        be null, in this case the result type is not fixed.
   * @return Instance of the ExpressionBits class, allowing to store and/or
   * instantiate compiled expression.
   * @exception gnu.jel.CompilationException if the expression is not
   *  syntactically or semantically correct.
   * @see gnu.jel.CompiledExpression#evaluate
   */
  public static ExpressionBits compileBits(String expression, Library lib,
					   Class resultType) 
       throws CompilationException {
    Optimizer o=fillOptimizer(expression, lib,resultType);
    o.optimize(1);
    return o.compileBits();
  };

  /**
   * Compiles expression, resolving the function names in the library.
   * @param expression is the expression to compile. i.e. "sin(666)" .
   * @param lib Library of functions exported for use in expression.
   * @return Instance of the CompiledExpression subclass, implementing
   *   the specified expression evaluation.
   * @exception gnu.jel.CompilationException if the expression is not
   *  syntactically or semantically correct.
   * @see gnu.jel.CompiledExpression#evaluate
   */
  public static CompiledExpression compile(String expression, Library lib)
       throws CompilationException {
    return compile(expression, lib, null);
  };

  /**
   * Compiles expression, resolving the function names in the library.
   * <P>This variant of compile allows to store expressions in a 
   * <TT>java.io.OutputStream</TT> using Java serialization mechanism.
   * @param expression is the expression to compile. i.e. "sin(666)" .
   * @param lib Library of functions exported for use in expression.
   * @return Instance of the ExpressionBits class, allowing to store and/or
   * instantiate compiled expression.
   * @exception gnu.jel.CompilationException if the expression is not
   *  syntactically or semantically correct.
   * @see gnu.jel.CompiledExpression#evaluate
   */
  public static ExpressionBits compileBits(String expression, Library lib)
       throws CompilationException {
    return compileBits(expression, lib, null);
  };
  

  // This is for convenient use in the internal optimizer tests
  static Optimizer fillOptimizer(String expression, Library lib, 
				 Class resultType) 
       throws CompilationException {
    EC ec=new EC(new java.io.StringReader(expression));
    Optimizer o=new Optimizer(lib);
    try {
      ec.expression(o,resultType);
    } catch (ParseException pe) {
      throw new CompilationException(pe);
    } catch (TokenMgrError tme) {
      throw new CompilationException(tme);
    };
    return o;
  };

};











