/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. */ /* * RTCons.java * Created: May 14, 2003 2:51:53 PM * By: RCypher */ package org.openquark.cal.internal.runtime.lecc; import org.openquark.cal.runtime.CALExecutorException; import org.openquark.cal.runtime.CalValue; import org.openquark.cal.runtime.ErrorInfo; /** * This is the RTCons class/interface. * This serves as the base class for non-primitive types. * <p> * lecc automatically generates classes for data types that are subclasses of RTCons. * For example, for the Prelude.List type, a TYPE_List class deriving from RTCons will be generated. * TYPE_List will have 2 derived classes as static inner classes CAL_Nil and CAL_Cons. * CAL_Nil and CAL_Cons both have $instance static final fields for the use of Prelude.Nil and Prelude.Cons * as functions. In this sense they are truly RTSupercombinator derived classes. However, they also are able * to constructor values e.g. Cons applied to 2 RTValue arguments. In this sense they do not obey the RTSupercombinator * contract, and so some special treatment is needed. * * Created: May 14, 2003 2:51:53 PM * @author RCypher */ public abstract class RTCons extends RTSupercombinator { /** * Set a string which shows the sequence of call calls that * led to the creation of this object. * This class will be overridden by generated derived classes. */ public void setCreationCallChain() { } /** * Check that this instance represents the expected data constructor. * If it doesn't throws and error. * @param dcOrdinal - ordinal of the expected data constructor * @param errorInfo * @throws CALExecutorException */ protected final void checkDCOrdinalForFieldSelection (int dcOrdinal, ErrorInfo errorInfo) throws CALExecutorException { if (dcOrdinal != getOrdinalValue()) { String message = "Wrong data constructor in data constructor field selection or local pattern match declaration. Expecting: " + getModuleName() + "." + getDCNameByOrdinal(dcOrdinal) + ", found: " + getQualifiedName() + "."; throw new CALExecutorException.ExternalException.PatternMatchFailure(errorInfo, message, null); } } public RTValue getFieldByIndex (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); return badValue(errorInfo, "Attempt to call getFieldByIndex() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); } public Object getFieldByIndex_As_Object (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); return badValue(errorInfo, "Attempt to call getFieldByIndex_As_Object() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); } public boolean getFieldByIndex_As_Boolean (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Boolean() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return false; } public byte getFieldByIndex_As_Byte (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Byte() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return (byte)0; } public short getFieldByIndex_As_Short (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Short() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return 0; } public char getFieldByIndex_As_Character (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Character() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return ' '; } public int getFieldByIndex_As_Int (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Int() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return 0; } public long getFieldByIndex_As_Long (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Long() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return 0; } public double getFieldByIndex_As_Double (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Double() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return 0; } public float getFieldByIndex_As_Float (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_Float() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return 0; } public String getFieldByIndex_As_java_lang_String (int dcOrdinal, int fieldIndex, ErrorInfo errorInfo) throws CALExecutorException { checkDCOrdinalForFieldSelection(dcOrdinal, errorInfo); badFieldIndexInGetFieldByIndex(fieldIndex); badValue(errorInfo, "Attempt to call getFieldByIndex_As_java_lang_String() on " + getClass().getName() + " with field index " + fieldIndex + " on " + getClass().getName()); return ""; } protected String getDCNameByOrdinal (int dcOrdinal) { badValue(null, "Attempt to call getDCNameByOrdinal() on " + getClass().getName() + "."); return ""; } /** * See the class comment as to why RTCons instances do not obey the contract of RTSupercombinator. If this function returns * true, then this particular instance of the given data constructor class type is the one that *does* actually obey the * RTSupercombinator contract. * * In particular, it returns true for all 0 arity data constructors, as well as the functional singleton for positive * arity data constructors (corresponding to the $instance field in the generated code for the data constructor). * * @return true if this is the special singleton instance of the given data constructor representing the use of the * data constructor as a function. For example, there is a Cons singleton instance, which is used for partially applied * applications of Cons. When the function is actually evaluated, and we have a Cons application to 2 arguments, this * creates a Cons node which is not a singleton, but more like a subclass of RTData. */ public boolean isFunctionSingleton() { //in general, 0-arity data constructors are always represented by a singleton. For positive arity functions, //this must be overridden in the generated data constructor class. return true; } /** * {@inheritDoc} */ @Override public final int debug_getNChildren() { if (isFunctionSingleton()) { return 0; } return getArity(); } /** * {@inheritDoc} */ @Override public CalValue debug_getChild(int childN) { if (isFunctionSingleton()) { throw new IndexOutOfBoundsException(); } throw new IllegalStateException("debug_getChild must be overridden for non function singletons."); } /** * {@inheritDoc} */ @Override public final String debug_getNodeStartText() { if (isFunctionSingleton()) { return getQualifiedName(); } return "(" + getQualifiedName(); } /** * {@inheritDoc} */ @Override public final String debug_getNodeEndText() { if (isFunctionSingleton()) { return ""; } return ")"; } /** * {@inheritDoc} */ @Override public final String debug_getChildPrefixText(int childN) { if (isFunctionSingleton()) { throw new IndexOutOfBoundsException(); } if (childN >= 0 && childN < getArity()) { return " "; } throw new IndexOutOfBoundsException(); } /** * Method called when a field accessor (i.e. get_fieldName()) is * called for a field that doesn't exist in this instance of RTCons. * @param fieldName * @return Won't really return anything since it will always throw an exception. */ protected final RTValue badFieldAccessor (String fieldName) { return RTValue.badValue("Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final boolean badFieldAccessor_Boolean (String fieldName) { return RTValue.badValue_boolean(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final byte badFieldAccessor_Byte (String fieldName) { return RTValue.badValue_byte(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final char badFieldAccessor_Character (String fieldName) { return RTValue.badValue_char(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final double badFieldAccessor_Double (String fieldName) { return RTValue.badValue_double(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final float badFieldAccessor_Float (String fieldName) { return RTValue.badValue_float(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final int badFieldAccessor_Int (String fieldName) { return RTValue.badValue_int(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final long badFieldAccessor_Long (String fieldName) { return RTValue.badValue_long(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final Object badFieldAccessor_Object (String fieldName) { return RTValue.badValue_Object(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } protected final short badFieldAccessor_Short (String fieldName) { return RTValue.badValue_short(null, "Unable to retrieve field " + fieldName + " from " + getQualifiedName() + "."); } /** * Helper function called by generated code if an invalid field index is encountered in * a generated instance of getFieldByIndex. * @param index */ protected void badFieldIndexInGetFieldByIndex (int index) { RTValue.badValue("Unable to retrieve field for index " + index + " in data constructor " + getQualifiedName() + "."); } }