/* * 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.g; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import org.openquark.cal.compiler.QualifiedName; import org.openquark.cal.internal.machine.primitiveops.PrimOps; import org.openquark.cal.module.Cal.Core.CAL_Prelude; import org.openquark.cal.runtime.CALExecutorException; import org.openquark.cal.runtime.CalFunction; import org.openquark.cal.util.EquivalenceRelation; /** * This class contains information about the various primitive operations. * It also specifies the interface for an actual operation object. */ abstract class PrimOp { private PrimOps.PrimOpInfo info = null; /** * Since this is a static map which is mutated we need to synchronize it. */ private static Map<Integer, PrimOp> codeToOp = Collections.synchronizedMap (new HashMap<Integer, PrimOp> ()); /** QualifiedName -> PrimOp * Since this is a static map which is mutated we need to synchronize it. */ private static Map<QualifiedName, PrimOp> nameToOp = Collections.synchronizedMap (new HashMap<QualifiedName, PrimOp> ()); // static initialization block static { for (final PrimOps.PrimOpInfo primOp : PrimOps.primOps()) { addOp (primOp); } } private static void addOp (PrimOps.PrimOpInfo info) { PrimOp op; switch (info.getCode ()) { case PrimOps.PRIMOP_NOP: op = new PrimopNOP (info); break; case PrimOps.PRIMOP_OR: op = new PrimopOR (info); break; case PrimOps.PRIMOP_AND: op = new PrimopAND (info); break; case PrimOps.PRIMOP_EQUALS_INT: op = new PrimopEQUALS_INT (info); break; case PrimOps.PRIMOP_NOT_EQUALS_INT: op = new PrimopNOT_EQUALS_INT (info); break; case PrimOps.PRIMOP_GREATER_THAN_INT: op = new PrimopGREATER_THAN_INT (info); break; case PrimOps.PRIMOP_GREATER_THAN_EQUALS_INT: op = new PrimopGREATER_THAN_EQUALS_INT (info); break; case PrimOps.PRIMOP_LESS_THAN_INT: op = new PrimopLESS_THAN_INT (info); break; case PrimOps.PRIMOP_LESS_THAN_EQUALS_INT: op = new PrimopLESS_THAN_EQUALS_INT (info); break; case PrimOps.PRIMOP_ADD_INT: op = new PrimopADD_INT (info); break; case PrimOps.PRIMOP_SUBTRACT_INT: op = new PrimopSUBTRACT_INT (info); break; case PrimOps.PRIMOP_MULTIPLY_INT: op = new PrimopMULTIPLY_INT (info); break; case PrimOps.PRIMOP_DIVIDE_INT: op = new PrimopDIVIDE_INT (info); break; case PrimOps.PRIMOP_NEGATE_INT: op = new PrimopNEGATE_INT (info); break; case PrimOps.PRIMOP_REMAINDER_INT: op = new PrimopREMAINDER_INT (info); break; case PrimOps.PRIMOP_EQUALS_DOUBLE: op = new PrimopEQUALS_DOUBLE (info); break; case PrimOps.PRIMOP_NOT_EQUALS_DOUBLE: op = new PrimopNOT_EQUALS_DOUBLE (info); break; case PrimOps.PRIMOP_GREATER_THAN_DOUBLE: op = new PrimopGREATER_THAN_DOUBLE (info); break; case PrimOps.PRIMOP_GREATER_THAN_EQUALS_DOUBLE: op = new PrimopGREATER_THAN_EQUALS_DOUBLE (info); break; case PrimOps.PRIMOP_LESS_THAN_DOUBLE: op = new PrimopLESS_THAN_DOUBLE (info); break; case PrimOps.PRIMOP_LESS_THAN_EQUALS_DOUBLE: op = new PrimopLESS_THAN_EQUALS_DOUBLE (info); break; case PrimOps.PRIMOP_ADD_DOUBLE: op = new PrimopADD_DOUBLE (info); break; case PrimOps.PRIMOP_SUBTRACT_DOUBLE: op = new PrimopSUBTRACT_DOUBLE (info); break; case PrimOps.PRIMOP_MULTIPLY_DOUBLE: op = new PrimopMULTIPLY_DOUBLE (info); break; case PrimOps.PRIMOP_DIVIDE_DOUBLE: op = new PrimopDIVIDE_DOUBLE (info); break; case PrimOps.PRIMOP_NEGATE_DOUBLE: op = new PrimopNEGATE_DOUBLE (info); break; case PrimOps.PRIMOP_REMAINDER_DOUBLE: op = new PrimopREMAINDER_DOUBLE (info); break; case PrimOps.PRIMOP_EQUALS_LONG: op = new PrimopEQUALS_LONG (info); break; case PrimOps.PRIMOP_NOT_EQUALS_LONG: op = new PrimopNOT_EQUALS_LONG (info); break; case PrimOps.PRIMOP_GREATER_THAN_LONG: op = new PrimopGREATER_THAN_LONG (info); break; case PrimOps.PRIMOP_GREATER_THAN_EQUALS_LONG: op = new PrimopGREATER_THAN_EQUALS_LONG (info); break; case PrimOps.PRIMOP_LESS_THAN_LONG: op = new PrimopLESS_THAN_LONG (info); break; case PrimOps.PRIMOP_LESS_THAN_EQUALS_LONG: op = new PrimopLESS_THAN_EQUALS_LONG (info); break; case PrimOps.PRIMOP_ADD_LONG: op = new PrimopADD_LONG (info); break; case PrimOps.PRIMOP_SUBTRACT_LONG: op = new PrimopSUBTRACT_LONG (info); break; case PrimOps.PRIMOP_MULTIPLY_LONG: op = new PrimopMULTIPLY_LONG (info); break; case PrimOps.PRIMOP_DIVIDE_LONG: op = new PrimopDIVIDE_LONG (info); break; case PrimOps.PRIMOP_NEGATE_LONG: op = new PrimopNEGATE_LONG (info); break; case PrimOps.PRIMOP_REMAINDER_LONG: op = new PrimopREMAINDER_LONG (info); break; case PrimOps.PRIMOP_EQUALS_BYTE: op = new PrimopEQUALS_BYTE (info); break; case PrimOps.PRIMOP_NOT_EQUALS_BYTE: op = new PrimopNOT_EQUALS_BYTE (info); break; case PrimOps.PRIMOP_GREATER_THAN_BYTE: op = new PrimopGREATER_THAN_BYTE (info); break; case PrimOps.PRIMOP_GREATER_THAN_EQUALS_BYTE: op = new PrimopGREATER_THAN_EQUALS_BYTE (info); break; case PrimOps.PRIMOP_LESS_THAN_BYTE: op = new PrimopLESS_THAN_BYTE (info); break; case PrimOps.PRIMOP_LESS_THAN_EQUALS_BYTE: op = new PrimopLESS_THAN_EQUALS_BYTE (info); break; case PrimOps.PRIMOP_EQUALS_SHORT: op = new PrimopEQUALS_SHORT (info); break; case PrimOps.PRIMOP_NOT_EQUALS_SHORT: op = new PrimopNOT_EQUALS_SHORT (info); break; case PrimOps.PRIMOP_GREATER_THAN_SHORT: op = new PrimopGREATER_THAN_SHORT (info); break; case PrimOps.PRIMOP_GREATER_THAN_EQUALS_SHORT: op = new PrimopGREATER_THAN_EQUALS_SHORT (info); break; case PrimOps.PRIMOP_LESS_THAN_SHORT: op = new PrimopLESS_THAN_SHORT (info); break; case PrimOps.PRIMOP_LESS_THAN_EQUALS_SHORT: op = new PrimopLESS_THAN_EQUALS_SHORT (info); break; case PrimOps.PRIMOP_EQUALS_FLOAT: op = new PrimopEQUALS_FLOAT (info); break; case PrimOps.PRIMOP_NOT_EQUALS_FLOAT: op = new PrimopNOT_EQUALS_FLOAT (info); break; case PrimOps.PRIMOP_GREATER_THAN_FLOAT: op = new PrimopGREATER_THAN_FLOAT (info); break; case PrimOps.PRIMOP_GREATER_THAN_EQUALS_FLOAT: op = new PrimopGREATER_THAN_EQUALS_FLOAT (info); break; case PrimOps.PRIMOP_LESS_THAN_FLOAT: op = new PrimopLESS_THAN_FLOAT (info); break; case PrimOps.PRIMOP_LESS_THAN_EQUALS_FLOAT: op = new PrimopLESS_THAN_EQUALS_FLOAT (info); break; case PrimOps.PRIMOP_ADD_FLOAT: op = new PrimopADD_FLOAT (info); break; case PrimOps.PRIMOP_SUBTRACT_FLOAT: op = new PrimopSUBTRACT_FLOAT (info); break; case PrimOps.PRIMOP_MULTIPLY_FLOAT: op = new PrimopMULTIPLY_FLOAT (info); break; case PrimOps.PRIMOP_DIVIDE_FLOAT: op = new PrimopDIVIDE_FLOAT (info); break; case PrimOps.PRIMOP_NEGATE_FLOAT: op = new PrimopNEGATE_FLOAT (info); break; case PrimOps.PRIMOP_REMAINDER_FLOAT: op = new PrimopREMAINDER_FLOAT (info); break; case PrimOps.PRIMOP_EQUALS_CHAR: op = new PrimopEQUALS_CHAR (info); break; case PrimOps.PRIMOP_NOT_EQUALS_CHAR: op = new PrimopNOT_EQUALS_CHAR (info); break; case PrimOps.PRIMOP_GREATER_THAN_CHAR: op = new PrimopGREATER_THAN_CHAR (info); break; case PrimOps.PRIMOP_GREATER_THAN_EQUALS_CHAR: op = new PrimopGREATER_THAN_EQUALS_CHAR (info); break; case PrimOps.PRIMOP_LESS_THAN_CHAR: op = new PrimopLESS_THAN_CHAR (info); break; case PrimOps.PRIMOP_LESS_THAN_EQUALS_CHAR: op = new PrimopLESS_THAN_EQUALS_CHAR (info); break; case PrimOps.PRIMOP_FIELD_NAMES: { op = new PrimOpFIELD_NAMES(info); break; } case PrimOps.PRIMOP_FIELD_VALUES: { op = new PrimOpFIELD_VALUES(info); break; } case PrimOps.PRIMOP_HAS_FIELD: { op = new PrimOpHAS_FIELD(info); break; } case PrimOps.PRIMOP_RECORD_FIELD_INDEX: { op = new PrimOpRECORD_FIELD_INDEX(info); break; } case PrimOps.PRIMOP_OBJECT_TO_CAL_VALUE: { op = new PrimOpOBJECT_TO_CAL_VALUE(info); break; } case PrimOps.PRIMOP_CAL_VALUE_TO_OBJECT: { op = new PrimOpCAL_VALUE_TO_OBJECT(info); break; } case PrimOps.PRIMOP_MAKE_ITERATOR: { op = new PrimOpMAKE_ITERATOR(info); break; } case PrimOps.PRIMOP_MAKE_COMPARATOR: { op = new PrimOpMAKE_COMPARATOR(info); break; } case PrimOps.PRIMOP_MAKE_EQUIVALENCE_RELATION: { op = new PrimOpMAKE_EQUIVALENCE_RELATION(info); break; } case PrimOps.PRIMOP_MAKE_CAL_FUNCTION: { op = new PrimOpMAKE_CAL_FUNCTION(info); break; } case PrimOps.PRIMOP_BITWISE_AND_LONG: op = new PrimopBITWISE_AND_LONG (info); break; case PrimOps.PRIMOP_BITWISE_OR_LONG: op = new PrimopBITWISE_OR_LONG (info); break; case PrimOps.PRIMOP_BITWISE_XOR_LONG: op = new PrimopBITWISE_XOR_LONG (info); break; case PrimOps.PRIMOP_COMPLEMENT_LONG: op = new PrimopCOMPLEMENT_LONG (info); break; case PrimOps.PRIMOP_SHIFTL_LONG: op = new PrimopSHIFTL_LONG (info); break; case PrimOps.PRIMOP_SHIFTR_LONG: op = new PrimopSHIFTR_LONG (info); break; case PrimOps.PRIMOP_SHIFTR_UNSIGNED_LONG: op = new PrimopSHIFTR_UNSIGNED_LONG (info); break; case PrimOps.PRIMOP_BITWISE_AND_INT: op = new PrimopBITWISE_AND_INT (info); break; case PrimOps.PRIMOP_BITWISE_OR_INT: op = new PrimopBITWISE_OR_INT (info); break; case PrimOps.PRIMOP_BITWISE_XOR_INT: op = new PrimopBITWISE_XOR_INT (info); break; case PrimOps.PRIMOP_COMPLEMENT_INT: op = new PrimopCOMPLEMENT_INT (info); break; case PrimOps.PRIMOP_SHIFTL_INT: op = new PrimopSHIFTL_INT (info); break; case PrimOps.PRIMOP_SHIFTR_INT: op = new PrimopSHIFTR_INT (info); break; case PrimOps.PRIMOP_SHIFTR_UNSIGNED_INT: op = new PrimopSHIFTR_UNSIGNED_INT (info); break; case PrimOps.PRIMOP_EXECUTION_CONTEXT: { op = new PrimopEXECUTION_CONTEXT (info); break; } case PrimOps.PRIMOP_EAGER: // Eager gets ignored, we simply end up forcing evaluation of its argument. return; default: throw new IllegalArgumentException("Missing implementation of primitive op: " + info.getName()); } codeToOp.put (Integer.valueOf(info.getCode ()), op); nameToOp.put (info.getName (), op); } private PrimOp (PrimOps.PrimOpInfo info) { this.info = info; } public QualifiedName getName () { return info.getName(); } public int getCode () { return info.getCode (); } public int getArity () { return info.getArity (); } public String getDescription () { return info.getDescription (); } public abstract void perform (Executor e) throws CALExecutorException; public static PrimOp getPrimOpForCode (int code) { return codeToOp.get (Integer.valueOf(code)); } public static PrimOp getPrimOpForName (QualifiedName name) { return nameToOp.get (name); } ////////////////////////////////////////////////////////////////////////////////////////////////////// private static class PrimopNOP extends PrimOp { public PrimopNOP (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { } } private static class PrimopOR extends PrimOp { public PrimopOR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popBoolean() || stack.popBoolean()); } } private static class PrimopAND extends PrimOp { public PrimopAND (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popBoolean() && stack.popBoolean()); } } //Built-in functions for basic integer comparison and arithmetic private static class PrimopEQUALS_INT extends PrimOp { public PrimopEQUALS_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popInt() == stack.popInt()); } } private static class PrimopNOT_EQUALS_INT extends PrimOp { public PrimopNOT_EQUALS_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popInt() != stack.popInt()); } } private static class PrimopGREATER_THAN_INT extends PrimOp { public PrimopGREATER_THAN_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popInt() < stack.popInt()); } } private static class PrimopGREATER_THAN_EQUALS_INT extends PrimOp { public PrimopGREATER_THAN_EQUALS_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popInt() <= stack.popInt()); } } private static class PrimopLESS_THAN_INT extends PrimOp { public PrimopLESS_THAN_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popInt() > stack.popInt()); } } private static class PrimopLESS_THAN_EQUALS_INT extends PrimOp { public PrimopLESS_THAN_EQUALS_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popInt() >= stack.popInt()); } } private static class PrimopADD_INT extends PrimOp { public PrimopADD_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushInt (stack.popInt() + stack.popInt()); } } private static class PrimopSUBTRACT_INT extends PrimOp { public PrimopSUBTRACT_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int i = stack.popInt(); stack.pushInt (stack.popInt() - i); } } private static class PrimopMULTIPLY_INT extends PrimOp { public PrimopMULTIPLY_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushInt (stack.popInt() * stack.popInt()); } } private static class PrimopDIVIDE_INT extends PrimOp { public PrimopDIVIDE_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int i = stack.popInt(); stack.pushInt (stack.popInt() / i); } } private static class PrimopNEGATE_INT extends PrimOp { public PrimopNEGATE_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushInt (-stack.popInt()); } } private static class PrimopREMAINDER_INT extends PrimOp { public PrimopREMAINDER_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int i = stack.popInt(); stack.pushInt (stack.popInt() % i); } } //Built-in functions for basic double comparison and arithmetic private static class PrimopEQUALS_DOUBLE extends PrimOp { public PrimopEQUALS_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popDouble() == stack.popDouble()); } } private static class PrimopNOT_EQUALS_DOUBLE extends PrimOp { public PrimopNOT_EQUALS_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popDouble() != stack.popDouble()); } } private static class PrimopGREATER_THAN_DOUBLE extends PrimOp { public PrimopGREATER_THAN_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popDouble() < stack.popDouble()); } } private static class PrimopGREATER_THAN_EQUALS_DOUBLE extends PrimOp { public PrimopGREATER_THAN_EQUALS_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popDouble() <= stack.popDouble()); } } private static class PrimopLESS_THAN_DOUBLE extends PrimOp { public PrimopLESS_THAN_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popDouble() > stack.popDouble()); } } private static class PrimopLESS_THAN_EQUALS_DOUBLE extends PrimOp { public PrimopLESS_THAN_EQUALS_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popDouble() >= stack.popDouble()); } } private static class PrimopADD_DOUBLE extends PrimOp { public PrimopADD_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushDouble (stack.popDouble() + stack.popDouble()); } } private static class PrimopSUBTRACT_DOUBLE extends PrimOp { public PrimopSUBTRACT_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; double d = stack.popDouble(); stack.pushDouble (stack.popDouble() - d); } } private static class PrimopMULTIPLY_DOUBLE extends PrimOp { public PrimopMULTIPLY_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushDouble (stack.popDouble() * stack.popDouble()); } } private static class PrimopDIVIDE_DOUBLE extends PrimOp { public PrimopDIVIDE_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; double d = stack.popDouble(); stack.pushDouble (stack.popDouble() / d); } } private static class PrimopNEGATE_DOUBLE extends PrimOp { public PrimopNEGATE_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushDouble (- stack.popDouble()); } } private static class PrimopREMAINDER_DOUBLE extends PrimOp { public PrimopREMAINDER_DOUBLE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; double d = stack.popDouble(); stack.pushDouble (stack.popDouble() % d); } } // Built-in functions for basic long comparison and arithmetic private static class PrimopEQUALS_LONG extends PrimOp { public PrimopEQUALS_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popLong() == stack.popLong()); } } private static class PrimopNOT_EQUALS_LONG extends PrimOp { public PrimopNOT_EQUALS_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popLong() != stack.popLong()); } } private static class PrimopGREATER_THAN_LONG extends PrimOp { public PrimopGREATER_THAN_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popLong() < stack.popLong()); } } private static class PrimopGREATER_THAN_EQUALS_LONG extends PrimOp { public PrimopGREATER_THAN_EQUALS_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popLong() <= stack.popLong()); } } private static class PrimopLESS_THAN_LONG extends PrimOp { public PrimopLESS_THAN_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popLong() > stack.popLong()); } } private static class PrimopLESS_THAN_EQUALS_LONG extends PrimOp { public PrimopLESS_THAN_EQUALS_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popLong() >= stack.popLong()); } } private static class PrimopADD_LONG extends PrimOp { public PrimopADD_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushLong (stack.popLong() + stack.popLong()); } } private static class PrimopSUBTRACT_LONG extends PrimOp { public PrimopSUBTRACT_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long l = stack.popLong(); stack.pushLong (stack.popLong() - l); } } private static class PrimopMULTIPLY_LONG extends PrimOp { public PrimopMULTIPLY_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushLong (stack.popLong() * stack.popLong()); } } private static class PrimopDIVIDE_LONG extends PrimOp { public PrimopDIVIDE_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long l = stack.popLong(); stack.pushLong (stack.popLong() / l); } } private static class PrimopNEGATE_LONG extends PrimOp { public PrimopNEGATE_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushLong (- stack.popLong()); } } private static class PrimopREMAINDER_LONG extends PrimOp { public PrimopREMAINDER_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long l = stack.popLong(); stack.pushLong (stack.popLong() % l); } } // Built-in functions for basic short comparison private static class PrimopEQUALS_SHORT extends PrimOp { public PrimopEQUALS_SHORT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popShort() == stack.popShort()); } } private static class PrimopNOT_EQUALS_SHORT extends PrimOp { public PrimopNOT_EQUALS_SHORT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popShort() != stack.popShort()); } } private static class PrimopGREATER_THAN_SHORT extends PrimOp { public PrimopGREATER_THAN_SHORT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popShort() < stack.popShort()); } } private static class PrimopGREATER_THAN_EQUALS_SHORT extends PrimOp { public PrimopGREATER_THAN_EQUALS_SHORT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popShort() <= stack.popShort()); } } private static class PrimopLESS_THAN_SHORT extends PrimOp { public PrimopLESS_THAN_SHORT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popShort() > stack.popShort()); } } private static class PrimopLESS_THAN_EQUALS_SHORT extends PrimOp { public PrimopLESS_THAN_EQUALS_SHORT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popShort() >= stack.popShort()); } } // Built-in functions for basic byte comparison private static class PrimopEQUALS_BYTE extends PrimOp { public PrimopEQUALS_BYTE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popByte() == stack.popByte()); } } private static class PrimopNOT_EQUALS_BYTE extends PrimOp { public PrimopNOT_EQUALS_BYTE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popByte() != stack.popByte()); } } private static class PrimopGREATER_THAN_BYTE extends PrimOp { public PrimopGREATER_THAN_BYTE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popByte() < stack.popByte()); } } private static class PrimopGREATER_THAN_EQUALS_BYTE extends PrimOp { public PrimopGREATER_THAN_EQUALS_BYTE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popByte() <= stack.popByte()); } } private static class PrimopLESS_THAN_BYTE extends PrimOp { public PrimopLESS_THAN_BYTE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popByte() > stack.popByte()); } } private static class PrimopLESS_THAN_EQUALS_BYTE extends PrimOp { public PrimopLESS_THAN_EQUALS_BYTE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popByte() >= stack.popByte()); } } // Built-in functions for basic float comparison and arithmetic private static class PrimopEQUALS_FLOAT extends PrimOp { public PrimopEQUALS_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popFloat() == stack.popFloat()); } } private static class PrimopNOT_EQUALS_FLOAT extends PrimOp { public PrimopNOT_EQUALS_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popFloat() != stack.popFloat()); } } private static class PrimopGREATER_THAN_FLOAT extends PrimOp { public PrimopGREATER_THAN_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean (stack.popFloat() < stack.popFloat()); } } private static class PrimopGREATER_THAN_EQUALS_FLOAT extends PrimOp { public PrimopGREATER_THAN_EQUALS_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popFloat() <= stack.popFloat()); } } private static class PrimopLESS_THAN_FLOAT extends PrimOp { public PrimopLESS_THAN_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popFloat() > stack.popFloat()); } } private static class PrimopLESS_THAN_EQUALS_FLOAT extends PrimOp { public PrimopLESS_THAN_EQUALS_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popFloat() >= stack.popFloat()); } } private static class PrimopADD_FLOAT extends PrimOp { public PrimopADD_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushFloat (stack.popFloat() + stack.popFloat()); } } private static class PrimopSUBTRACT_FLOAT extends PrimOp { public PrimopSUBTRACT_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; float f = stack.popFloat(); stack.pushFloat (stack.popFloat() - f); } } private static class PrimopMULTIPLY_FLOAT extends PrimOp { public PrimopMULTIPLY_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushFloat (stack.popFloat() * stack.popFloat()); } } private static class PrimopDIVIDE_FLOAT extends PrimOp { public PrimopDIVIDE_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; float f = stack.popFloat(); stack.pushFloat (stack.popFloat() / f); } } private static class PrimopNEGATE_FLOAT extends PrimOp { public PrimopNEGATE_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushFloat (- stack.popFloat()); } } private static class PrimopREMAINDER_FLOAT extends PrimOp { public PrimopREMAINDER_FLOAT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; float f = stack.popFloat(); stack.pushFloat (stack.popFloat() % f); } } //Built-in functions for basic character comparison private static class PrimopEQUALS_CHAR extends PrimOp { public PrimopEQUALS_CHAR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popChar() == stack.popChar()); } } private static class PrimopNOT_EQUALS_CHAR extends PrimOp { public PrimopNOT_EQUALS_CHAR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popChar() != stack.popChar()); } } private static class PrimopGREATER_THAN_CHAR extends PrimOp { public PrimopGREATER_THAN_CHAR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popChar() < stack.popChar()); } } private static class PrimopGREATER_THAN_EQUALS_CHAR extends PrimOp { public PrimopGREATER_THAN_EQUALS_CHAR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popChar() <= stack.popChar()); } } private static class PrimopLESS_THAN_CHAR extends PrimOp { public PrimopLESS_THAN_CHAR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popChar() > stack.popChar()); } } private static class PrimopLESS_THAN_EQUALS_CHAR extends PrimOp { public PrimopLESS_THAN_EQUALS_CHAR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pushBoolean(stack.popChar() >= stack.popChar()); } } private static class PrimOpFIELD_NAMES extends PrimOp { public PrimOpFIELD_NAMES (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { NRecordValue recordValue = (NRecordValue)e.stack.pop(); e.stack.push (new NValObject(recordValue.fieldNames())); } } private static class PrimOpFIELD_VALUES extends PrimOp { public PrimOpFIELD_VALUES (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { NRecordValue recordValue = (NRecordValue)e.stack.pop(); e.stack.push (new NValObject(recordValue.fieldValues())); } } private static class PrimOpHAS_FIELD extends PrimOp { public PrimOpHAS_FIELD (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { String fieldName = e.stack.popString (); NRecordValue recordValue = (NRecordValue)e.stack.pop (); e.stack.pushBoolean(recordValue.hasField(fieldName)); } } private static class PrimOpRECORD_FIELD_INDEX extends PrimOp { public PrimOpRECORD_FIELD_INDEX (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { String fieldName = e.stack.popString (); NRecordValue recordValue = (NRecordValue)e.stack.pop (); e.stack.pushInt(recordValue.indexOfField(fieldName)); } } private static class PrimOpOBJECT_TO_CAL_VALUE extends PrimOp { public PrimOpOBJECT_TO_CAL_VALUE (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Node n = e.stack.pop (); e.stack.push ((Node)(((NValObject)n).getValue())); } } private static class PrimOpCAL_VALUE_TO_OBJECT extends PrimOp { public PrimOpCAL_VALUE_TO_OBJECT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { e.stack.push (new NValObject (e.stack.pop())); } } /** * Implements the primitive function declared in the List module * makeIterator :: [a] -> (a -> JObject) -> JIterator * * @author Bo Ilic */ private static final class PrimOpMAKE_ITERATOR extends PrimOp { private static final class CalListIterator implements Iterator<Object> { private Node calListValue; private final NInd elementMarshalingFunction; private final Executor executor; private CalListIterator(Node calListValue, Node elementMarshalingFunction, Executor oldExecutor) { if (calListValue == null || elementMarshalingFunction == null || oldExecutor == null) { throw new NullPointerException(); } this.calListValue = calListValue; this.elementMarshalingFunction = (NInd)elementMarshalingFunction; this.executor = new Executor (oldExecutor.program, oldExecutor.resourceAccess, oldExecutor.getExecutionContext()); } /** {@inheritDoc} */ public boolean hasNext() { //evaluate calListValue to WHNF and see if it is a Cons. This means there is a next value try { this.executor.reset (); this.executor.stack.push (calListValue); this.executor.exec (new Code(Instruction.I_Eval)); calListValue = this.executor.stack.pop(); //0 == Prelude.Nil //1 == Prelude.Cons return calListValue.getOrdinalValue() == 1; } catch (CALExecutorException cee) { //wrap the exception up in a non-checked exception and rethrow. throw new RuntimeException (cee); } } /** {@inheritDoc} */ public Object next() { try { this.executor.reset (); this.executor.stack.push (calListValue); this.executor.exec (new Code(Instruction.I_Eval)); calListValue = this.executor.stack.pop(); switch (calListValue.getOrdinalValue()) { case 0: { //Prelude.Nil throw new NoSuchElementException(); } case 1: { //Prelude.Cons NConstr2 listCons = (NConstr2)calListValue; Node headValue = listCons.getN0(); calListValue = listCons.getN1(); executor.stack.push(elementMarshalingFunction.apply(headValue)); this.executor.exec (new Code(Instruction.I_Eval)); return executor.stack.pop().getValue(); } default: { throw new IndexOutOfBoundsException(); } } } catch (CALExecutorException executorException) { //wrap the exception up in a non-checked exception and rethrow. throw new RuntimeException(executorException); } } /** {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } } public PrimOpMAKE_ITERATOR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Node elementMarshalingFunction = e.stack.pop(); Node calListValue = e.stack.pop(); e.stack.push(new NValObject(new CalListIterator(calListValue, elementMarshalingFunction, e))); } } /** * Implements the primitive function declared in the Prelude module * makeEquivalenceRelation :: (a -> a -> Ordering) -> Comparator * * @author Bo Ilic */ private static final class PrimOpMAKE_COMPARATOR extends PrimOp { private static final class GComparator implements java.util.Comparator<Node> { private final NInd comparisonFunction; private final Executor executor; private GComparator(Node comparisonFunction, Executor oldExecutor) { if (comparisonFunction == null || oldExecutor == null) { throw new NullPointerException(); } this.comparisonFunction = (NInd)comparisonFunction; this.executor = new Executor (oldExecutor.program, oldExecutor.resourceAccess, oldExecutor.getExecutionContext()); } /** {@inheritDoc} */ public int compare(Node object1, Node object2) { this.executor.reset (); this.executor.stack.push (new NAp(new NAp (comparisonFunction, object1), object2)); try { this.executor.exec (new Code(Instruction.I_Eval)); } catch (CALExecutorException cee) { //wrap the exception up in a non-checked exception and rethrow. throw new RuntimeException (cee); } int result = this.executor.stack.pop().getOrdinalValue(); switch (result) { case 0: { // Prelude.LT return -1; } case 1: { // Prelude.EQ return 0; } case 2: { // Prelude.GT return 1; } default: { throw new RuntimeException("Unrecognized " + CAL_Prelude.TypeConstructors.Ordering.getQualifiedName() + " data constructor."); } } } /** {@inheritDoc} */ @Override public String toString() { return comparisonFunction.toString(); } } public PrimOpMAKE_COMPARATOR (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Node comparisonFunction = e.stack.pop(); e.stack.push(new NValObject(new GComparator(comparisonFunction, e))); } } /** * Implements the primitive function declared in the Prelude module * makeEquivalenceRelation :: (a -> a -> Boolean) -> EquivalenceRelation * * @author Bo Ilic */ private static final class PrimOpMAKE_EQUIVALENCE_RELATION extends PrimOp { private static final class GEquivalenceRelation implements EquivalenceRelation<Node> { private final NInd equivalenceFunction; private final Executor executor; private GEquivalenceRelation(Node equivalenceFunction, Executor oldExecutor) { if (equivalenceFunction == null || oldExecutor == null) { throw new NullPointerException(); } this.equivalenceFunction = (NInd)equivalenceFunction; this.executor = new Executor (oldExecutor.program, oldExecutor.resourceAccess, oldExecutor.getExecutionContext()); } /** {@inheritDoc} */ public boolean equivalent(Node object1, Node object2) { //evaluate the result of the equivalence function applied to the two objects in question. this.executor.reset (); this.executor.stack.push (new NAp (new NAp (equivalenceFunction, object1), object2)); try { this.executor.exec (new Code (Instruction.I_Eval)); } catch (CALExecutorException cee) { //wrap the exception up in a non-checked exception and rethrow. throw new RuntimeException (cee); } boolean result = ((NValBoolean)this.executor.stack.pop()).getBooleanValue(); return result; } /** {@inheritDoc} */ @Override public String toString() { return equivalenceFunction.toString(); } } public PrimOpMAKE_EQUIVALENCE_RELATION (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Node eqFunction = e.stack.pop(); e.stack.push(new NValObject(new GEquivalenceRelation(eqFunction, e))); } } /** * Implements the primitive function declared in the Prelude module * makeCalFunction :: (JObject -> JObject) -> CalFunction * * @author Bo Ilic */ private static final class PrimOpMAKE_CAL_FUNCTION extends PrimOp { private static final class GCalFunction implements CalFunction { private final NInd calFunction; private final Executor executor; private GCalFunction(Node calFunction, Executor oldExecutor) { if (calFunction == null || oldExecutor == null) { throw new NullPointerException(); } this.calFunction = (NInd)calFunction; this.executor = new Executor (oldExecutor.program, oldExecutor.resourceAccess, oldExecutor.getExecutionContext()); } /** {@inheritDoc} */ public Object evaluate(Object object) { this.executor.reset (); this.executor.stack.push (new NAp(calFunction, new NValObject(object))); try { this.executor.exec (new Code(Instruction.I_Eval)); } catch (CALExecutorException cee) { //wrap the exception up in a non-checked exception and rethrow. throw new RuntimeException (cee); } return this.executor.stack.pop().getValue(); } /** {@inheritDoc} */ @Override public String toString() { return calFunction.toString(); } } public PrimOpMAKE_CAL_FUNCTION (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Node calFunction = e.stack.pop(); e.stack.push(new NValObject(new GCalFunction(calFunction, e))); } } private static class PrimopBITWISE_AND_INT extends PrimOp { public PrimopBITWISE_AND_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int y = stack.popInt(); int x = stack.popInt(); stack.pushInt (x & y); } } private static class PrimopBITWISE_OR_INT extends PrimOp { public PrimopBITWISE_OR_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int i = stack.popInt(); stack.pushInt (stack.popInt() | i); } } private static class PrimopBITWISE_XOR_INT extends PrimOp { public PrimopBITWISE_XOR_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int i = stack.popInt(); stack.pushInt (stack.popInt() ^ i); } } private static class PrimopCOMPLEMENT_INT extends PrimOp { public PrimopCOMPLEMENT_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int i = stack.popInt(); stack.pushInt (~i); } } private static class PrimopSHIFTL_INT extends PrimOp { public PrimopSHIFTL_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int y = stack.popInt(); int x = stack.popInt(); stack.pushInt (x << y); } } private static class PrimopSHIFTR_INT extends PrimOp { public PrimopSHIFTR_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int y = stack.popInt(); int x = stack.popInt(); stack.pushInt (x >> y); } } private static class PrimopSHIFTR_UNSIGNED_INT extends PrimOp { public PrimopSHIFTR_UNSIGNED_INT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; int y = stack.popInt(); int x = stack.popInt(); stack.pushInt (x >>> y); } } private static class PrimopBITWISE_AND_LONG extends PrimOp { public PrimopBITWISE_AND_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long y = stack.popLong(); long x = stack.popLong(); stack.pushLong (x & y); } } private static class PrimopBITWISE_OR_LONG extends PrimOp { public PrimopBITWISE_OR_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long i = stack.popLong(); stack.pushLong (stack.popLong() | i); } } private static class PrimopBITWISE_XOR_LONG extends PrimOp { public PrimopBITWISE_XOR_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long i = stack.popLong(); stack.pushLong (stack.popLong() ^ i); } } private static class PrimopCOMPLEMENT_LONG extends PrimOp { public PrimopCOMPLEMENT_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long i = stack.popLong(); stack.pushLong (~i); } } private static class PrimopSHIFTL_LONG extends PrimOp { public PrimopSHIFTL_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long y = stack.popLong(); long x = stack.popLong(); stack.pushLong (x << y); } } private static class PrimopSHIFTR_LONG extends PrimOp { public PrimopSHIFTR_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long y = stack.popLong(); long x = stack.popLong(); stack.pushLong (x >> y); } } private static class PrimopSHIFTR_UNSIGNED_LONG extends PrimOp { public PrimopSHIFTR_UNSIGNED_LONG (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; long y = stack.popLong(); long x = stack.popLong(); stack.pushLong (x >>> y); } } private static class PrimopEXECUTION_CONTEXT extends PrimOp { public PrimopEXECUTION_CONTEXT (PrimOps.PrimOpInfo info) { super (info); } @Override public void perform (Executor e) throws CALExecutorException { e.stack.push(new NValObject(e.getContext())); } } }