/*
* 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.
*/
/*
* PrimOp.java
* Creation date: Dec 19, 2002
* By: rcypher
*/
package org.openquark.cal.internal.machine.primitiveops;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.internal.module.Cal.Collections.CAL_List_internal;
import org.openquark.cal.internal.module.Cal.Core.CAL_Bits_internal;
import org.openquark.cal.internal.module.Cal.Core.CAL_Dynamic_internal;
import org.openquark.cal.internal.module.Cal.Core.CAL_Prelude_internal;
import org.openquark.cal.internal.module.Cal.Core.CAL_Record_internal;
import org.openquark.cal.module.Cal.Core.CAL_Prelude;
/**
* This class contains information about the various primitive operations.
* It also specifies the interface for an actual operation object.
* @author Luke Evans, Bo Ilic, Raymond Cypher
*/
public class PrimOps extends Object {
/**
* Since this map is only mutated by code in the static initialization block
* it isn't synchronized. If, however, the map is ever mutated by code outside
* the static initialization block it will need to be synchronized.
*/
private static final Map<QualifiedName, PrimOpInfo> nameToInfo = new HashMap<QualifiedName, PrimOpInfo> ();
/**
* Since this map is only mutated by code in the static initialization block
* it isn't synchronized. If, however, the map is ever mutated by code outside
* the static initialization block it will need to be synchronized.
*/
private static final Map<Integer, PrimOpInfo> codeToInfo = new HashMap<Integer, PrimOpInfo> ();
// Operator sub-code for primitive intrinsic operations
public static final int PRIMOP_NOP = -1; // No operation
public static final int PRIMOP_OR = 1; // Logical OR
public static final int PRIMOP_AND = 2; // Logical AND
//Built-in functions for basic integer comparison and arithmetic
public static final int PRIMOP_EQUALS_INT = 3;
public static final int PRIMOP_NOT_EQUALS_INT = 4;
public static final int PRIMOP_GREATER_THAN_INT = 5;
public static final int PRIMOP_GREATER_THAN_EQUALS_INT = 6;
public static final int PRIMOP_LESS_THAN_INT = 7;
public static final int PRIMOP_LESS_THAN_EQUALS_INT = 8;
public static final int PRIMOP_ADD_INT = 9;
public static final int PRIMOP_SUBTRACT_INT = 10;
public static final int PRIMOP_MULTIPLY_INT = 11;
public static final int PRIMOP_DIVIDE_INT = 12;
public static final int PRIMOP_NEGATE_INT = 13;
public static final int PRIMOP_REMAINDER_INT = 14;
//Built-in functions for basic double comparison and arithmetic
public static final int PRIMOP_EQUALS_DOUBLE = 15;
public static final int PRIMOP_NOT_EQUALS_DOUBLE = 16;
public static final int PRIMOP_GREATER_THAN_DOUBLE = 17;
public static final int PRIMOP_GREATER_THAN_EQUALS_DOUBLE = 18;
public static final int PRIMOP_LESS_THAN_DOUBLE = 19;
public static final int PRIMOP_LESS_THAN_EQUALS_DOUBLE = 20;
public static final int PRIMOP_ADD_DOUBLE = 21;
public static final int PRIMOP_SUBTRACT_DOUBLE = 22;
public static final int PRIMOP_MULTIPLY_DOUBLE = 23;
public static final int PRIMOP_DIVIDE_DOUBLE = 24;
public static final int PRIMOP_NEGATE_DOUBLE = 25;
public static final int PRIMOP_REMAINDER_DOUBLE = 26;
//Built-in functions for basic character comparison
public static final int PRIMOP_EQUALS_CHAR = 27;
public static final int PRIMOP_NOT_EQUALS_CHAR = 28;
public static final int PRIMOP_GREATER_THAN_CHAR = 29;
public static final int PRIMOP_GREATER_THAN_EQUALS_CHAR = 30;
public static final int PRIMOP_LESS_THAN_CHAR = 31;
public static final int PRIMOP_LESS_THAN_EQUALS_CHAR = 32;
// Built-in functions for basic long comparison and arithmetic
public static final int PRIMOP_EQUALS_LONG = 33;
public static final int PRIMOP_NOT_EQUALS_LONG = 34;
public static final int PRIMOP_GREATER_THAN_LONG = 35;
public static final int PRIMOP_GREATER_THAN_EQUALS_LONG = 36;
public static final int PRIMOP_LESS_THAN_LONG = 37;
public static final int PRIMOP_LESS_THAN_EQUALS_LONG = 38;
public static final int PRIMOP_ADD_LONG = 39;
public static final int PRIMOP_SUBTRACT_LONG = 40;
public static final int PRIMOP_MULTIPLY_LONG = 41;
public static final int PRIMOP_DIVIDE_LONG = 42;
public static final int PRIMOP_NEGATE_LONG = 43;
public static final int PRIMOP_REMAINDER_LONG = 44;
// Built-in functions for basic short comparison
public static final int PRIMOP_EQUALS_SHORT = 45;
public static final int PRIMOP_NOT_EQUALS_SHORT = 46;
public static final int PRIMOP_GREATER_THAN_SHORT = 47;
public static final int PRIMOP_GREATER_THAN_EQUALS_SHORT = 48;
public static final int PRIMOP_LESS_THAN_SHORT = 49;
public static final int PRIMOP_LESS_THAN_EQUALS_SHORT = 50;
// Built-in functions for basic byte comparison
public static final int PRIMOP_EQUALS_BYTE = 51;
public static final int PRIMOP_NOT_EQUALS_BYTE = 52;
public static final int PRIMOP_GREATER_THAN_BYTE = 53;
public static final int PRIMOP_GREATER_THAN_EQUALS_BYTE = 54;
public static final int PRIMOP_LESS_THAN_BYTE = 55;
public static final int PRIMOP_LESS_THAN_EQUALS_BYTE = 56;
// Built-in functions for basic float comparison and arithmetic
public static final int PRIMOP_EQUALS_FLOAT = 57;
public static final int PRIMOP_NOT_EQUALS_FLOAT = 58;
public static final int PRIMOP_GREATER_THAN_FLOAT = 59;
public static final int PRIMOP_GREATER_THAN_EQUALS_FLOAT = 60;
public static final int PRIMOP_LESS_THAN_FLOAT = 61;
public static final int PRIMOP_LESS_THAN_EQUALS_FLOAT = 62;
public static final int PRIMOP_ADD_FLOAT = 63;
public static final int PRIMOP_SUBTRACT_FLOAT = 64;
public static final int PRIMOP_MULTIPLY_FLOAT = 65;
public static final int PRIMOP_DIVIDE_FLOAT = 66;
public static final int PRIMOP_NEGATE_FLOAT = 67;
public static final int PRIMOP_REMAINDER_FLOAT = 68;
// bitwise operations in Int
public static final int PRIMOP_BITWISE_AND_INT = 69;
public static final int PRIMOP_BITWISE_OR_INT = 70;
public static final int PRIMOP_BITWISE_XOR_INT = 71;
public static final int PRIMOP_COMPLEMENT_INT = 72;
public static final int PRIMOP_HIGHEST_MASK_INT = 73;
public static final int PRIMOP_SHIFTL_INT = 74;
public static final int PRIMOP_SHIFTR_INT = 75;
public static final int PRIMOP_SHIFTR_UNSIGNED_INT = 76;
// bitwise operations on Long
public static final int PRIMOP_BITWISE_AND_LONG = 77;
public static final int PRIMOP_BITWISE_OR_LONG = 78;
public static final int PRIMOP_BITWISE_XOR_LONG = 79;
public static final int PRIMOP_COMPLEMENT_LONG = 80;
public static final int PRIMOP_HIGHEST_MASK_LONG = 81;
public static final int PRIMOP_SHIFTL_LONG = 82;
public static final int PRIMOP_SHIFTR_LONG = 83;
public static final int PRIMOP_SHIFTR_UNSIGNED_LONG = 84;
public static final int PRIMOP_CAL_VALUE_TO_OBJECT = 85;
public static final int PRIMOP_OBJECT_TO_CAL_VALUE = 86;
public static final int PRIMOP_MAKE_COMPARATOR = 87;
public static final int PRIMOP_MAKE_EQUIVALENCE_RELATION = 88;
public static final int PRIMOP_MAKE_CAL_FUNCTION = 89;
//record related functions
public static final int PRIMOP_FIELD_NAMES = 90;
public static final int PRIMOP_FIELD_VALUES = 91;
public static final int PRIMOP_HAS_FIELD = 92;
public static final int PRIMOP_RECORD_FIELD_INDEX = 93;
// primitive for forcing eager evaluation
public static final int PRIMOP_EAGER = 94;
//for the System.executionContext function
public static final int PRIMOP_EXECUTION_CONTEXT = 95;
//for List.makeIterator :: [a] -> (a -> JObject) -> JIterator;
public static final int PRIMOP_MAKE_ITERATOR = 96;
public static final int PRIMOP_FOREIGN_FUNCTION = 97;
//leave PRIMOP_FOREIGN_FUNCTION last!
/////////////////////////////////////////////////////////////////////////////////
// Initialization block to set up the info for the primitive ops.
static {
// addPreludeOp ("||", PRIMOP_OR, 2, "||");
// addPreludeOp ("&&", PRIMOP_AND, 2, "&&");
addOp (CAL_Prelude_internal.Functions.equalsInt, PRIMOP_EQUALS_INT, 2);
addOp (CAL_Prelude_internal.Functions.notEqualsInt, PRIMOP_NOT_EQUALS_INT, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanInt, PRIMOP_GREATER_THAN_INT, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanEqualsInt, PRIMOP_GREATER_THAN_EQUALS_INT, 2);
addOp (CAL_Prelude_internal.Functions.lessThanInt, PRIMOP_LESS_THAN_INT, 2);
addOp (CAL_Prelude_internal.Functions.lessThanEqualsInt, PRIMOP_LESS_THAN_EQUALS_INT, 2);
addOp (CAL_Prelude_internal.Functions.addInt, PRIMOP_ADD_INT, 2);
addOp (CAL_Prelude_internal.Functions.subtractInt, PRIMOP_SUBTRACT_INT, 2);
addOp (CAL_Prelude_internal.Functions.multiplyInt, PRIMOP_MULTIPLY_INT, 2);
addOp (CAL_Prelude_internal.Functions.divideInt, PRIMOP_DIVIDE_INT, 2);
addOp (CAL_Prelude_internal.Functions.negateInt, PRIMOP_NEGATE_INT, 1);
addOp (CAL_Prelude_internal.Functions.remainderInt, PRIMOP_REMAINDER_INT, 2);
addOp (CAL_Prelude_internal.Functions.equalsDouble, PRIMOP_EQUALS_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.notEqualsDouble, PRIMOP_NOT_EQUALS_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanDouble, PRIMOP_GREATER_THAN_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanEqualsDouble, PRIMOP_GREATER_THAN_EQUALS_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.lessThanDouble, PRIMOP_LESS_THAN_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.lessThanEqualsDouble, PRIMOP_LESS_THAN_EQUALS_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.addDouble, PRIMOP_ADD_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.subtractDouble, PRIMOP_SUBTRACT_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.multiplyDouble, PRIMOP_MULTIPLY_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.divideDouble, PRIMOP_DIVIDE_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.negateDouble, PRIMOP_NEGATE_DOUBLE, 1);
addOp (CAL_Prelude_internal.Functions.remainderDouble, PRIMOP_REMAINDER_DOUBLE, 2);
addOp (CAL_Prelude_internal.Functions.equalsChar, PRIMOP_EQUALS_CHAR, 2);
addOp (CAL_Prelude_internal.Functions.notEqualsChar, PRIMOP_NOT_EQUALS_CHAR, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanChar, PRIMOP_GREATER_THAN_CHAR, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanEqualsChar, PRIMOP_GREATER_THAN_EQUALS_CHAR, 2);
addOp (CAL_Prelude_internal.Functions.lessThanChar, PRIMOP_LESS_THAN_CHAR, 2);
addOp (CAL_Prelude_internal.Functions.lessThanEqualsChar, PRIMOP_LESS_THAN_EQUALS_CHAR, 2);
addOp (CAL_Prelude_internal.Functions.equalsLong, PRIMOP_EQUALS_LONG, 2);
addOp (CAL_Prelude_internal.Functions.notEqualsLong, PRIMOP_NOT_EQUALS_LONG, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanLong, PRIMOP_GREATER_THAN_LONG, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanEqualsLong, PRIMOP_GREATER_THAN_EQUALS_LONG, 2);
addOp (CAL_Prelude_internal.Functions.lessThanLong, PRIMOP_LESS_THAN_LONG, 2);
addOp (CAL_Prelude_internal.Functions.lessThanEqualsLong, PRIMOP_LESS_THAN_EQUALS_LONG, 2);
addOp (CAL_Prelude_internal.Functions.addLong, PRIMOP_ADD_LONG, 2);
addOp (CAL_Prelude_internal.Functions.subtractLong, PRIMOP_SUBTRACT_LONG, 2);
addOp (CAL_Prelude_internal.Functions.multiplyLong, PRIMOP_MULTIPLY_LONG, 2);
addOp (CAL_Prelude_internal.Functions.divideLong, PRIMOP_DIVIDE_LONG, 2);
addOp (CAL_Prelude_internal.Functions.negateLong, PRIMOP_NEGATE_LONG, 1);
addOp (CAL_Prelude_internal.Functions.remainderLong, PRIMOP_REMAINDER_LONG, 2);
addOp (CAL_Prelude_internal.Functions.equalsShort, PRIMOP_EQUALS_SHORT, 2);
addOp (CAL_Prelude_internal.Functions.notEqualsShort, PRIMOP_NOT_EQUALS_SHORT, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanShort, PRIMOP_GREATER_THAN_SHORT, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanEqualsShort, PRIMOP_GREATER_THAN_EQUALS_SHORT, 2);
addOp (CAL_Prelude_internal.Functions.lessThanShort, PRIMOP_LESS_THAN_SHORT, 2);
addOp (CAL_Prelude_internal.Functions.lessThanEqualsShort, PRIMOP_LESS_THAN_EQUALS_SHORT, 2);
addOp (CAL_Prelude_internal.Functions.equalsByte, PRIMOP_EQUALS_BYTE, 2);
addOp (CAL_Prelude_internal.Functions.notEqualsByte, PRIMOP_NOT_EQUALS_BYTE, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanByte, PRIMOP_GREATER_THAN_BYTE, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanEqualsByte, PRIMOP_GREATER_THAN_EQUALS_BYTE, 2);
addOp (CAL_Prelude_internal.Functions.lessThanByte, PRIMOP_LESS_THAN_BYTE, 2);
addOp (CAL_Prelude_internal.Functions.lessThanEqualsByte, PRIMOP_LESS_THAN_EQUALS_BYTE, 2);
addOp (CAL_Prelude_internal.Functions.equalsFloat, PRIMOP_EQUALS_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.notEqualsFloat, PRIMOP_NOT_EQUALS_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanFloat, PRIMOP_GREATER_THAN_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.greaterThanEqualsFloat, PRIMOP_GREATER_THAN_EQUALS_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.lessThanFloat, PRIMOP_LESS_THAN_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.lessThanEqualsFloat, PRIMOP_LESS_THAN_EQUALS_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.addFloat, PRIMOP_ADD_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.subtractFloat, PRIMOP_SUBTRACT_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.multiplyFloat, PRIMOP_MULTIPLY_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.divideFloat, PRIMOP_DIVIDE_FLOAT, 2);
addOp (CAL_Prelude_internal.Functions.negateFloat, PRIMOP_NEGATE_FLOAT, 1);
addOp (CAL_Prelude_internal.Functions.remainderFloat, PRIMOP_REMAINDER_FLOAT, 2);
addOp (CAL_Bits_internal.Functions.bitwiseAndInt, PRIMOP_BITWISE_AND_INT, 2);
addOp (CAL_Bits_internal.Functions.bitwiseOrInt, PRIMOP_BITWISE_OR_INT, 2);
addOp (CAL_Bits_internal.Functions.bitwiseXorInt, PRIMOP_BITWISE_XOR_INT, 2);
addOp (CAL_Bits_internal.Functions.complementInt, PRIMOP_COMPLEMENT_INT, 1);
addOp (CAL_Bits_internal.Functions.shiftLInt, PRIMOP_SHIFTL_INT, 2);
addOp (CAL_Bits_internal.Functions.shiftRInt, PRIMOP_SHIFTR_INT, 2);
addOp (CAL_Bits_internal.Functions.shiftRUnsignedInt, PRIMOP_SHIFTR_UNSIGNED_INT, 2);
addOp (CAL_Bits_internal.Functions.bitwiseAndLong, PRIMOP_BITWISE_AND_LONG, 2);
addOp (CAL_Bits_internal.Functions.bitwiseOrLong, PRIMOP_BITWISE_OR_LONG, 2);
addOp (CAL_Bits_internal.Functions.bitwiseXorLong, PRIMOP_BITWISE_XOR_LONG, 2);
addOp (CAL_Bits_internal.Functions.complementLong, PRIMOP_COMPLEMENT_LONG, 1);
addOp (CAL_Bits_internal.Functions.shiftLLong, PRIMOP_SHIFTL_LONG, 2);
addOp (CAL_Bits_internal.Functions.shiftRLong, PRIMOP_SHIFTR_LONG, 2);
addOp (CAL_Bits_internal.Functions.shiftRUnsignedLong, PRIMOP_SHIFTR_UNSIGNED_LONG, 2);
addOp (CAL_Prelude_internal.Functions.calValueToObject, PRIMOP_CAL_VALUE_TO_OBJECT, 1);
addOp (CAL_Prelude_internal.Functions.objectToCalValue, PRIMOP_OBJECT_TO_CAL_VALUE, 1);
addOp (CAL_Prelude_internal.Functions.makeComparator, PRIMOP_MAKE_COMPARATOR, 1);
addOp (CAL_Prelude_internal.Functions.makeEquivalenceRelation, PRIMOP_MAKE_EQUIVALENCE_RELATION, 1);
addOp (CAL_Prelude.Functions.makeCalFunction, PRIMOP_MAKE_CAL_FUNCTION, 1);
addOp (CAL_Record_internal.Functions.fieldNamesPrimitive, PRIMOP_FIELD_NAMES, 1);
addOp (CAL_Record_internal.Functions.hasFieldPrimitive, PRIMOP_HAS_FIELD, 2);
addOp (CAL_Dynamic_internal.Functions.fieldValuesPrimitive, PRIMOP_FIELD_VALUES, 1);
addOp (CAL_Dynamic_internal.Functions.recordFieldIndex, PRIMOP_RECORD_FIELD_INDEX, 2);
addOp (CAL_Prelude.Functions.eager, PRIMOP_EAGER, 1);
addOp (CAL_Prelude_internal.Functions.executionContext, PRIMOP_EXECUTION_CONTEXT, 0);
addOp (CAL_List_internal.Functions.makeIterator, PRIMOP_MAKE_ITERATOR, 2);
}
private static void addOp (QualifiedName name, int code, int arity) {
addOp (name, code, arity, name.getUnqualifiedName());
}
// Add information about a named op, including description, to the maps.
private static void addOp (QualifiedName name, int code, int arity, String description) {
//System.out.println ("addOp " + name);
PrimOpInfo pof = new PrimOpInfo (name, code, arity, description);
nameToInfo.put (name, pof);
codeToInfo.put (Integer.valueOf(code), pof);
}
// Fetch info by qualified name.
public static PrimOps.PrimOpInfo fetchInfo (QualifiedName name) {
return nameToInfo.get(name);
}
// Fetch info by code.
public static PrimOps.PrimOpInfo fetchInfo (int code) {
return codeToInfo.get (Integer.valueOf(code));
}
public static Collection<PrimOpInfo> primOps () {
return codeToInfo.values();
}
public static final class PrimOpInfo {
private final QualifiedName name;
private final int arity;
private final int code;
private final String description;
private PrimOpInfo (QualifiedName name, int code, int arity, String description) {
this.name = name;
this.code = code;
this.arity = arity;
this.description = description;
}
public QualifiedName getName () {
return name;
}
public int getArity () {
return arity;
}
public int getCode () {
return code;
}
public String getDescription () {
return description;
}
@Override
public String toString () {
return name + ": arity = " + arity + ", code = " + code + " " + description;
}
}
}