Open Source Repository

Home /beanshell/bsh-2.0b4 | Repository Home



bsh/BSHArrayInitializer.java
/*****************************************************************************
 *                                                                           *
 *  This file is part of the BeanShell Java Scripting distribution.          *
 *  Documentation and updates may be found at http://www.beanshell.org/      *
 *                                                                           *
 *  Sun Public License Notice:                                               *
 *                                                                           *
 *  The contents of this file are subject to the Sun Public License Version  *
 *  1.0 (the "License"); you may not use this file except in compliance with *
 *  the License. A copy of the License is available at http://www.sun.com    * 
 *                                                                           *
 *  The Original Code is BeanShell. The Initial Developer of the Original    *
 *  Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright     *
 *  (C) 2000.  All Rights Reserved.                                          *
 *                                                                           *
 *  GNU Public License Notice:                                               *
 *                                                                           *
 *  Alternatively, the contents of this file may be used under the terms of  *
 *  the GNU Lesser General Public License (the "LGPL"), in which case the    *
 *  provisions of LGPL are applicable instead of those above. If you wish to *
 *  allow use of your version of this file only under the  terms of the LGPL *
 *  and not to allow others to use your version of this file under the SPL,  *
 *  indicate your decision by deleting the provisions above and replace      *
 *  them with the notice and other provisions required by the LGPL.  If you  *
 *  do not delete the provisions above, a recipient may use your version of  *
 *  this file under either the SPL or the LGPL.                              *
 *                                                                           *
 *  Patrick Niemeyer ([email protected])                                           *
 *  Author of Learning Java, O'Reilly & Associates                           *
 *  http://www.pat.net/~pat/                                                 *
 *                                                                           *
 *****************************************************************************/


package bsh;

import java.lang.reflect.Array;

class BSHArrayInitializer extends SimpleNode
{
    BSHArrayInitializer(int id) { super(id)}

    public Object evalCallStack callstack, Interpreter interpreter )
    throws EvalError 
  {
    throw new EvalError"Array initializer has no base type."
      this, callstack );
  }

  /**
    Construct the array from the initializer syntax.

    @param baseType the base class type of the array (no dimensionality)
    @param dimensions the top number of dimensions of the array 
      e.g. 2 for a String [][];
  */
    public Object evalClass baseType, int dimensions, 
            CallStack callstack, Interpreter interpreter 
    throws EvalError
    {
        int numInitializers = jjtGetNumChildren();

    // allocate the array to store the initializers
    int [] dima = new int [dimensions]// description of the array
    // The other dimensions default to zero and are assigned when 
    // the values are set.
    dima[0= numInitializers;
        Object initializers =  Array.newInstancebaseType, dima );

    // Evaluate the initializers
        for (int i = 0; i < numInitializers; i++)
        {
      SimpleNode node = (SimpleNode)jjtGetChild(i);
            Object currentInitializer;
      if node instanceof BSHArrayInitializer ) {
        if dimensions < )
          throw new EvalError(
            "Invalid Location for Intializer, position: "+i, 
            this, callstack );
              currentInitializer = 
          ((BSHArrayInitializer)node).eval
            baseType, dimensions-1, callstack, interpreter);
      else
              currentInitializer = node.evalcallstack, interpreter);

      if currentInitializer == Primitive.VOID )
        throw new EvalError(
          "Void in array initializer, position"+i, this, callstack );

      // Determine if any conversion is necessary on the initializers.
      //
      // Quick test to see if conversions apply:
      // If the dimensionality of the array is 1 then the elements of
      // the initializer can be primitives or boxable types.  If it is
      // greater then the values must be array (object) types and there
      // are currently no conversions that we do on those.
      // If we have conversions on those in the future then we need to
      // get the real base type here instead of the dimensionless one.
      Object value = currentInitializer;
      if dimensions == )
      {
        // We do a bsh cast here.  strictJava should be able to affect
        // the cast there when we tighten control
        try {
          value = Types.castObject(
            currentInitializer, baseType, Types.CAST );
        catch UtilEvalError e ) {
          throw e.toEvalError(
            "Error in array initializer", this, callstack );
        }
        // unwrap any primitive, map voids to null, etc.
        value = Primitive.unwrapvalue );
      }

        // store the value in the array
            try {
        Array.set(initializers, i, value);
            catchIllegalArgumentException e ) {
        Interpreter.debug("illegal arg"+e);
        throwTypeErrorbaseType, currentInitializer, i, callstack );
            catchArrayStoreException e ) { // I think this can happen
        Interpreter.debug("arraystore"+e);
        throwTypeErrorbaseType, currentInitializer, i, callstack );
            }
        }

        return initializers;
    }

  private void throwTypeError
    Class baseType, Object initializer, int argNum, CallStack callstack 
    throws EvalError
  {
    String rhsType;
    if (initializer instanceof Primitive)
      rhsType = 
        ((Primitive)initializer).getType().getName();
    else
      rhsType = Reflect.normalizeClassName(
        initializer.getClass());

    throw new EvalError "Incompatible type: " + rhsType 
      +" in initializer of array type: "+ baseType
      +" at position: "+argNum, this, callstack );
  }

}