/*
 * $Id: Evaluator.java,v 1.1.1.1 1998/05/11 18:43:02 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.debug.Debug;

/**
 * This class is intended for evaluation of the algebraic expressions.
 * <P> There is not much sense to use this class when expression has to be
 *  evaluated only once. The overhead of compilation makes usage of 
 *  interpreter much more suitable in this case. If, however, there is a 
 *  need to evaluate some function repeatedly (functions plotting, 
 *  numerical methods,...), this class should be very  well suitable.
 * <P> The expression language apart of usage of the arifmetic expressions 
 * allows to call functions. Functions are divided then into two groups. 
 * "Stateless" functions, whose result depends on their argument only 
 * (no state)
 *  and "virtual" functions, whose result explicitly depends on some externally
 * given state (Object pointer). Functions should be defined prior to the
 *  expression and passed in the gnu.jel.Library object.
 * <P>For example, if You a library based on <TT>java.lang.Math</TT> as
 * the static lirary the following expressions will be supported : 
 * "<TT>sin(0.1)</TT>", "<TT>sin(0.1)*cos(0.01)+abs(-1)</TT>".
 * <P> If class is nominated as static library all its public static methods
 * are exported for use in expressions. If it is nominated as dynamic library
 * all of it's virtual methods are exported. The basic difference is that the
 * dynamic libraries require class instance variable of corresponding class to
 * be supplied to the compiled code, the static methods do not. 
 * <P> Syntax supports variables, which are, in fact, functions with no 
 * argiments. If You define such function in the static library -- it is a
 * constant. If you define the method , such as "<TT>double x() {}</TT>;" 
 * in 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> All constants in the expressions are assumed to be either <TT>long</TT>
 * and <TT>double</TT> java types.
 * 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>Result is always returned as an object, even if it was calculated as a
 *  primitive type. Precisely if the result of the expression is primitive
 * integral type ( <TT>byte</TT>, <TT>char</TT>, <TT>short</TT>, <TT>int</TT>,
 *  <TT>boolean</TT>) it's converted to <TT>long</TT> and the new 
 * <TT>java.lang.Long</TT> object is returned. Floating point types (
 * <TT>float</TT>, <TT>double</TT>) are returned as <TT>java.lang.Double</TT>.
 * 
 * <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
 */
public class Evaluator {
  
  /**
   * Compiles expression, resolving the function names in the library.
   * @param expression is the expression to compile. i.e. "sin(666)" .
   * @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 {
    Optimizer o=fillOptimizer(expression, lib);
    if (Debug.enabled)
      Debug.println(o.toString());
    o.optimize(1);
    return o.compile();
  };
  
  // This is for convenient use in the internal optimizer tests
  static Optimizer fillOptimizer(String expression, Library lib) 
       throws CompilationException {
    EC ec=new EC(new java.io.StringReader(expression));
    Optimizer o=new Optimizer(lib);
    try {
      ec.expression(o);
    } catch (ParseException pe) {
      throw new CompilationException(pe);
    };
    return o;
  };

};











