Package org.openquark.cal.internal.machine

Examples of org.openquark.cal.internal.machine.BasicOpTuple


            appendUpdateCode(gp, d);

            return gp;
        }

        BasicOpTuple  basicOpExpressions = BasicOpTuple.isBasicOp(e);
        if (GENERATE_DEBUG_CODE) {
            //When we have function tracing enabled, we want to force all primitive operations to be
            //done as function calls. This will have the effect of ensuring that they get traced when called. 
            if (basicOpExpressions != null && !basicOpExpressions.getName().equals(currentMachineFunction.getQualifiedName())) {
                basicOpExpressions = null;
            }
        }

        // Is e a basic operation (arithmetic, comparative etc.)?  Test only - don't get tuple
        if (basicOpExpressions != null) {
            // Unpack the basic op into subexpressions
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    basic:");
            }



            // Code a basic operation
            int op = basicOpExpressions.getPrimitiveOp ();

            Instruction instruction = null;
            if (op == PrimOps.PRIMOP_EAGER) {
                return schemeR (basicOpExpressions.getArgument(0), p, d);
            } else
                if (op == PrimOps.PRIMOP_FOREIGN_FUNCTION) {
                    instruction = new Instruction.I_ForeignFunctionCall (basicOpExpressions.getForeignFunctionInfo());
                } else {
                    instruction = new Instruction.I_PrimOp(op);
                }

            int nArgs = basicOpExpressions.getNArguments ();

            if (nArgs < 0) {
                throw new CodeGenerationException ("Internal Coding Error: Invalid basic operator arity");  
            }

            if (op == PrimOps.PRIMOP_CAL_VALUE_TO_OBJECT) {
                //Prelude.calValueToObject is non-strict in its first argument.       
                gp.code (schemeC (basicOpExpressions.getArgument(0), p, d));
                gp.code (instruction);
            } else
            {
                for (int i = 0; i < nArgs; ++i) {
                    gp.code (schemeE (basicOpExpressions.getArgument(i), p, d + i));
                }
                gp.code (instruction);
            }

            appendUpdateCode(gp, d);
View Full Code Here


                gp.code(Instruction.I_PushVVal.makePushVVal(literal.getLiteral()));
            }
            return gp;
        }

        BasicOpTuple  basicOpExpressions = BasicOpTuple.isBasicOp(e);
        if (GENERATE_DEBUG_CODE) {
            //When we have function tracing enabled, we want to force all primitive operations to be
            //done as function calls. This will have the effect of ensuring that they get traced when called. 
            if (basicOpExpressions != null && !basicOpExpressions.getName().equals(currentMachineFunction.getQualifiedName())) {
                basicOpExpressions = null;
            }
        }

        // Is e a basic operation (arithmetic, comparative etc.)?  Test only - don't get tuple
        if (basicOpExpressions != null) {
            // Unpack the basic op into subexpressions
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    basic:");
            }

            // Code a basic operation
            int op = basicOpExpressions.getPrimitiveOp ();        

            Instruction instruction = null;

            if (op == PrimOps.PRIMOP_EAGER) {
                return schemeE (basicOpExpressions.getArgument(0), p, d);
            } else
                if (op == PrimOps.PRIMOP_FOREIGN_FUNCTION) {
                    instruction = new Instruction.I_ForeignFunctionCall (basicOpExpressions.getForeignFunctionInfo());
                } else {
                    instruction = new Instruction.I_PrimOp(op);
                }

            int nArgs = basicOpExpressions.getNArguments ();

            if (nArgs < 0) {
                throw new CodeGenerationException("Internal Coding Error: Invalid basic operator arity");  
            }

            if (op == PrimOps.PRIMOP_CAL_VALUE_TO_OBJECT) {
                //Prelude.calValueToObject is non-strict in its first argument.
               
                gp.code (schemeC (basicOpExpressions.getArgument(0), p, d));
                gp.code (instruction);
            } else
            {
                for (int i = 0; i < nArgs; ++i) {
                    gp.code (schemeE (basicOpExpressions.getArgument(i), p, d + i));
                }
                gp.code (instruction);
            }

            return gp;
View Full Code Here

        }

        // Is e a basic operation?
        // There is one basic operation, Prelude.eager, which is treated specially in the C scheme.
        if (BasicOpTuple.isBasicOp(e) != null) {
            BasicOpTuple basicOpExpressions = BasicOpTuple.isBasicOp(e);

            // Code a basic operation
            int op = basicOpExpressions.getPrimitiveOp ();        

            if (op == PrimOps.PRIMOP_EAGER) {
                return schemeE (basicOpExpressions.getArgument(0), p, d);
            }
        }


        // Is e a variable?
View Full Code Here

        }

        // We can shortcut a basic op if it is marked as allowed to
        // be eagerly evaluated and all arguments can all be shortcut.
        // Also if the op is Prelude.eager we can shortcut.
        BasicOpTuple basicOpExpressions = BasicOpTuple.isBasicOp(e);
        if (basicOpExpressions != null) {
            if (basicOpExpressions.getPrimitiveOp() == PrimOps.PRIMOP_EAGER) {
                return true;
            }

            QualifiedName opName = basicOpExpressions.getName();
            MachineFunction mf = currentModule.getFunction(opName);
            if (mf == null) {
                return false;
            }

            if (mf.canFunctionBeEagerlyEvaluated()) {
                int nArgs = basicOpExpressions.getNArguments();
                int nWHNFArgs = 0;
                for (int i = 0; i < nArgs; ++i) {
                    Expression eArg = basicOpExpressions.getArgument(i);
                    if (canIgnoreLaziness(eArg, env)) {
                        nWHNFArgs++;
                    }
                }
                if (nArgs == nWHNFArgs) {
                    // All the args are in WHNF so ideally we can ignore laziness for
                    // this primitive operation.  However, there are some primitive
                    // ops where an additional condition, that the second argument is
                    // known to not be zero, is required.
                    String unqualifiedOpName = opName.getUnqualifiedName();
                    if (opName.getModuleName().equals(CAL_Prelude.MODULE_NAME) &&
                            (unqualifiedOpName.equals("divideLong") ||
                                    unqualifiedOpName.equals("remainderLong") ||
                                    unqualifiedOpName.equals("divideInt") ||
                                    unqualifiedOpName.equals("remainderInt") ||
                                    unqualifiedOpName.equals("divideShort") ||
                                    unqualifiedOpName.equals("remainderShort") ||
                                    unqualifiedOpName.equals("divideByte") ||
                                    unqualifiedOpName.equals("remainderByte"))) {

                        // Check that the second argument is a non zero literal.

                        Expression arg = basicOpExpressions.getArgument(1);
                        if (arg.asLiteral() != null) {

                            if (unqualifiedOpName.equals("divideLong") || unqualifiedOpName.equals("remainderLong")) {

                                Long l = (Long)arg.asLiteral().getLiteral();
                                return l.longValue() != 0;

                            } else if (unqualifiedOpName.equals("divideInt") || unqualifiedOpName.equals("remainderInt")) {

                                Integer i = (Integer)arg.asLiteral().getLiteral();
                                return i.intValue() != 0;

                            } else if (unqualifiedOpName.equals("divideShort") || unqualifiedOpName.equals("remainderShort")) {

                                Short shortValue = (Short)arg.asLiteral().getLiteral();
                                return shortValue.shortValue() != 0;

                            } else if (unqualifiedOpName.equals("divideByte") || unqualifiedOpName.equals("remainderByte")) {

                                Byte byteValue = (Byte)arg.asLiteral().getLiteral();
                                return byteValue.byteValue() != 0;

                            } else {
                                throw new IllegalStateException();
                            }
                        } else {
                            return false;
                        }
                    } else {
                        return true;
                    }
                } else {
                    return false;
                }
            }
        }

        basicOpExpressions = BasicOpTuple.isAndOr (e);
        if (basicOpExpressions != null) {

            // Code a basic operation
            int nArgs = basicOpExpressions.getNArguments ();
            int nWHNFArgs = 0;
            for (int i = 0; i < nArgs; ++i) {
                Expression eArg = basicOpExpressions.getArgument(i);
                if (canIgnoreLaziness(eArg, env)) {
                    nWHNFArgs++;
                }
            }
            if (nArgs == nWHNFArgs) {
View Full Code Here

        }

        // We can shortcut a basic op if it is marked as eager
        // arguments can all be shortcut.
        // Also if the op is Prelude.eager we can shortcut.
        BasicOpTuple basicOpExpressions = BasicOpTuple.isBasicOp(e);
        if (basicOpExpressions != null) {
            if (basicOpExpressions.getPrimitiveOp() == PrimOps.PRIMOP_EAGER) {
                return true;
            }

            QualifiedName opName = basicOpExpressions.getName();
            MachineFunction mf = module.getFunction(opName);
            if (mf != null && mf.canFunctionBeEagerlyEvaluated()) {
                int nArgs = basicOpExpressions.getNArguments();
                int nWHNFArgs = 0;
                for (int i = 0; i < nArgs; ++i) {
                    Expression eArg = basicOpExpressions.getArgument(i);
                    if (canIgnoreLaziness(eArg, variableContext)) {
                        nWHNFArgs++;
                    }
                }
                if (nArgs == nWHNFArgs) {

                    String unqualifiedOpName = opName.getUnqualifiedName();
                    if (opName.getModuleName().equals(CAL_Prelude.MODULE_NAME) &&
                        (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideLong.getUnqualifiedName()) ||
                         unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderLong.getUnqualifiedName()) ||
                         unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideInt.getUnqualifiedName()) ||
                         unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderInt.getUnqualifiedName()) ||
                         unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideShort.getUnqualifiedName()) ||
                         unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderShort.getUnqualifiedName()) ||
                         unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideByte.getUnqualifiedName()) ||
                         unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderByte.getUnqualifiedName()))) {

                        // Check that the second argument is a non zero literal.

                        Expression arg = basicOpExpressions.getArgument(1);
                        if (arg.asLiteral() != null) {

                            if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideLong.getUnqualifiedName()) ||
                                unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderLong.getUnqualifiedName())) {

                                Long l = (Long)arg.asLiteral().getLiteral();
                                return l.longValue() != 0;

                            } else if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideInt.getUnqualifiedName()) ||
                                unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderInt.getUnqualifiedName())) {

                                Integer i = (Integer)arg.asLiteral().getLiteral();
                                return i.intValue() != 0;

                            } else if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideShort.getUnqualifiedName()) ||
                                unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderShort.getUnqualifiedName())) {

                                Short shortValue = (Short)arg.asLiteral().getLiteral();
                                return shortValue.shortValue() != 0;

                            } else if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideByte.getUnqualifiedName()) ||
                                unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderByte.getUnqualifiedName())) {

                                Byte byteValue = (Byte)arg.asLiteral().getLiteral();
                                return byteValue.byteValue() != 0;

                            } else {
                                throw new IllegalStateException();
                            }
                        } else {
                            return false;
                        }
                    } else {
                        return true;
                    }
                } else {
                    return false;
                }
            }
        }

        basicOpExpressions = BasicOpTuple.isAndOr (e);
        if (basicOpExpressions != null) {

            // Code a basic operation
            int nArgs = basicOpExpressions.getNArguments ();
            int nWHNFArgs = 0;
            for (int i = 0; i < nArgs; ++i) {
                Expression eArg = basicOpExpressions.getArgument(i);
                if (canIgnoreLaziness(eArg, variableContext)) {
                    nWHNFArgs++;
                }
            }
            if (nArgs == nWHNFArgs) {
View Full Code Here

            return letVarECP;
        }

        // There is one primitive operation that gets special treatment in the lazy compilation context.
        // This is Prelude.eager.  Even in a lazy context eager is evaluated immediately.
        BasicOpTuple bop = BasicOpTuple.isBasicOp(e);
        if (bop != null) {
            if (codeGenerationStats != null) {
                codeGenerationStats.incrementLazyPrimOps (bop.getName());
            }
            if (bop.getPrimitiveOp() == PrimOps.PRIMOP_EAGER) {
                if (LECCMachineConfiguration.generateDirectPrimOpCalls()) {
                    return generatePrimitiveOp(e, true, Scheme.C_SCHEME, variableContext);
                } else {
                     //we don't directly call primitive operators when doing function tracing.
                    //This will have the effect of ensuring that they get traced when called.
View Full Code Here

            return letVarECP;
        }

        // Is e a primitive operation (arithmetic, comparative etc.)?
        {
            BasicOpTuple bop = BasicOpTuple.isBasicOp(e);
            if (!LECCMachineConfiguration.generateDirectPrimOpCalls()) {
                // When we are generating call chains we want to force all primitive operations
                // to be done as a function call to the generated function.

                //When we have function tracing enabled, we want to force all primitive operations to be
                //done as function calls. This will have the effect of ensuring that they get traced when called.

                if (bop != null && !bop.getName().equals(getQualifiedName())) {
                    bop = null;
                }
            }

            if (bop != null) {
View Full Code Here

     * of eager and return the argument.
     * @param e
     * @return the argument to Prelude.eager
     */
    private Expression stripEager (Expression e) throws CodeGenerationException {
        BasicOpTuple bot = BasicOpTuple.isBasicOp(e);
        while (bot != null && bot.getPrimitiveOp() == PrimOps.PRIMOP_EAGER) {
            e = bot.getArgument(0);
            bot = BasicOpTuple.isBasicOp(e);
        }

        return e;
    }
View Full Code Here

            return generateReturn(letVarECP, variableContext);
        }

        // Is e a primitive operation (arithmetic, comparative etc.)?
        {
            BasicOpTuple bop = BasicOpTuple.isBasicOp(e);
            if (!LECCMachineConfiguration.generateDirectPrimOpCalls()) {

                // When we are generating call chains we want to force all primitive operations
                // to be done as a function call to the generated function.

                //When we have function tracing enabled, we want to force all primitive operations to be
                //done as function calls. This will have the effect of ensuring that they get traced when called.

                if (bop != null && !bop.getName().equals(getQualifiedName())) {
                    bop = null;
                }
            }

            if (bop != null) {
View Full Code Here

        if (codeGenerationStats != null) {
            codeGenerationStats.incrementDirectForeignCalls();
        }

        // Unpack the basic op into subexpressions
        final BasicOpTuple basicOpExpressions = BasicOpTuple.isBasicOp(e);

        final ForeignFunctionInfo foreignFunctionInfo = basicOpExpressions.getForeignFunctionInfo();
        final ForeignFunctionInfo.JavaKind kind = foreignFunctionInfo.getJavaKind();

        JavaExpression returnExpression = null;
        Block returnContext = new Block();

        if (kind.isMethod()) {

            final ForeignFunctionInfo.Invocation invocationInfo = (ForeignFunctionInfo.Invocation)foreignFunctionInfo;

            final Method method = (Method)SCJavaDefn.getJavaProxy(invocationInfo);
            if (method.getReturnType() == void.class && (scheme != Scheme.R_SCHEME)) {
                ExpressionContextPair ecp = genS_C (e, variableContext);
                JavaExpression expr = ecp.getJavaExpression();
                JavaStatement block = ecp.getContextBlock();
                JavaExpression.MethodInvocation eval = createInvocation(expr, EVALUATE, EXECUTION_CONTEXT_VAR);
                return new ExpressionContextPair(eval, block);
            }

            int nJavaArgs = SCJavaDefn.getNArguments(foreignFunctionInfo);
            final Class<?> invocationClass = SCJavaDefn.getInvocationClass(invocationInfo);
            final JavaTypeName invocationClassName = JavaTypeName.make(invocationClass);
            String methodName = method.getName();
            int startArg = 0;

            Class<?>[] exceptions = method.getExceptionTypes();
            for (int i = 0; i < exceptions.length; ++i) {
                if (!exceptionHandled(exceptions [i])) {
                    addExceptionHandler(exceptions[i]);
                }
            }

            if (!LECCMachineConfiguration.generateDirectPrimOpCalls()) {
                if (!exceptionHandled(Throwable.class)) {
                    addExceptionHandler(Throwable.class);
                }
            }

            JavaExpression target;
            InvocationType invocationType;      // static, virtual, or interface.  Can't be special (ie. private method).
            if (kind.isStatic()){
                target = null;
                invocationType = InvocationType.STATIC;
            } else {
                ExpressionContextPair pair = generateUnboxedForeignFunctionArgument(invocationClassName, basicOpExpressions.getArgument(0), variableContext);
                target = pair.getJavaExpression();
                invocationType = invocationClass.isInterface() ? InvocationType.INTERFACE : InvocationType.VIRTUAL;
                returnContext.addStatement(pair.getContextBlock());
                startArg = 1;
            }

            Class<?>[] argTypes = method.getParameterTypes();
            JavaExpression[] args = new JavaExpression[argTypes.length];
            JavaTypeName[] argTypeNames = new JavaTypeName[argTypes.length];

            for (int i = startArg, j = 0; i < nJavaArgs; ++i, ++j) {
                int index = i - startArg;
                final JavaTypeName argTypeName = JavaTypeName.make(argTypes[index]);
                ExpressionContextPair pair = generateUnboxedForeignFunctionArgument(argTypeName, basicOpExpressions.getArgument(i), variableContext);
                args[index] = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());

                argTypeNames[index] = argTypeName;
            }

            JavaTypeName returnType = JavaTypeName.make(method.getReturnType());

            if (kind.isStatic()) {
                returnExpression = new MethodInvocation.Static(invocationClassName, methodName, args, argTypeNames, returnType);
            } else {
                returnExpression = new MethodInvocation.Instance(target, methodName, invocationClassName, args, argTypeNames, returnType, invocationType);
            }

            if (boxResult) {
                ExpressionContextPair pair = returnTypeToCal(method.getReturnType(), returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind.isField()) {

            final ForeignFunctionInfo.Invocation invocationInfo = (ForeignFunctionInfo.Invocation)foreignFunctionInfo;

            final Field field = (Field)SCJavaDefn.getJavaProxy(invocationInfo);

            JavaTypeName fieldType = JavaTypeName.make(field.getType());
            String fieldName = field.getName();

            final JavaTypeName invocationClassName = JavaTypeName.make(SCJavaDefn.getInvocationClass(invocationInfo));
            if (kind.isStatic()) {
                returnExpression = new JavaField.Static(invocationClassName, fieldName, fieldType);
            } else {
                ExpressionContextPair pair = generateUnboxedForeignFunctionArgument(invocationClassName, basicOpExpressions.getArgument(0), variableContext);
                JavaExpression instance = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
                returnExpression = new JavaField.Instance(instance, fieldName, fieldType);
            }

            if (boxResult) {
                ExpressionContextPair pair = returnTypeToCal (field.getType(), returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind.isConstructor()) {

            final ForeignFunctionInfo.Invocation invocationInfo = (ForeignFunctionInfo.Invocation)foreignFunctionInfo;

            Constructor<?> constructor = (Constructor<?>)SCJavaDefn.getJavaProxy(invocationInfo);
            int nJavaArgs = SCJavaDefn.getNArguments(foreignFunctionInfo);
            Class<?> clazz = constructor.getDeclaringClass();
            Class<?>[] argTypes = constructor.getParameterTypes();

            Class<?>[] exceptions = constructor.getExceptionTypes();
            for (int i = 0; i < exceptions.length; ++i) {
                if (!exceptionHandled(exceptions [i])) {
                    addExceptionHandler(exceptions[i]);
                }
            }

            JavaExpression[] args = new JavaExpression[argTypes.length];
            JavaTypeName[] argTypeNames = new JavaTypeName[argTypes.length];
            for (int i = 0; i < nJavaArgs; i++) {
                final JavaTypeName argTypeName = JavaTypeName.make(argTypes[i]);
                ExpressionContextPair pair = generateUnboxedForeignFunctionArgument(argTypeName, basicOpExpressions.getArgument(i), variableContext);
                args[i] = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
                argTypeNames[i] = argTypeName;
            }

            returnExpression = new ClassInstanceCreationExpression(JavaTypeName.make(clazz), args, argTypeNames);

            if (boxResult) {
                ExpressionContextPair pair = returnTypeToCal(constructor.getDeclaringClass(), returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind.isCast()) {

            final Class<?> argType = SCJavaDefn.getJavaArgumentType(foreignFunctionInfo, 0);
            final Class<?> resultType = SCJavaDefn.getJavaReturnType(foreignFunctionInfo);

            final ExpressionContextPair argExprPair = generateUnboxedForeignFunctionArgument(JavaTypeName.make(argType), basicOpExpressions.getArgument(0), variableContext);
            final JavaExpression argExpr = argExprPair.getJavaExpression();
            returnContext.addStatement(argExprPair.getContextBlock());

            if (kind == ForeignFunctionInfo.JavaKind.IDENTITY_CAST ||
                kind == ForeignFunctionInfo.JavaKind.WIDENING_REFERENCE_CAST) {

                //it is important to do nothing for a widening reference cast (except for evaluating)
                //this is because at the JavaTypeName level, where the inheritance hierarchy is not available, it is not possible for
                //the bytecode generator to determine if this is truly a widening reference cast i.e. a no-op. Hence we must make
                //this optimization at this point.
                returnExpression = argExpr;

            } else if (kind == ForeignFunctionInfo.JavaKind.NARROWING_PRIMITIVE_CAST ||
                       kind == ForeignFunctionInfo.JavaKind.WIDENING_PRIMITIVE_CAST ||
                       kind == ForeignFunctionInfo.JavaKind.NARROWING_REFERENCE_CAST) {

                returnExpression = new JavaExpression.CastExpression(JavaTypeName.make(resultType), argExpr);

            } else {
                throw new CodeGenerationException("Unrecognized foreign function cast kind: " + kind);
            }

            if (boxResult) {
                ExpressionContextPair pair = returnTypeToCal(resultType, returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind.isInstanceOf()) {

            final Class<?> argType = SCJavaDefn.getJavaArgumentType(foreignFunctionInfo, 0);
            final ForeignFunctionInfo.InstanceOf instanceOfInfo = (ForeignFunctionInfo.InstanceOf)foreignFunctionInfo;
            final Class<?> instanceOfType = SCJavaDefn.getInstanceOfType(instanceOfInfo);

            final ExpressionContextPair argExprPair = generateUnboxedForeignFunctionArgument(JavaTypeName.make(argType), basicOpExpressions.getArgument(0), variableContext);
            final JavaExpression argExpr = argExprPair.getJavaExpression();
            returnContext.addStatement(argExprPair.getContextBlock());

            returnExpression = new JavaExpression.InstanceOf(argExpr, JavaTypeName.make(instanceOfType));

            if (boxResult) {
                ExpressionContextPair pair = returnTypeToCal(boolean.class, returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind.isClassLiteral()) {

            final ForeignFunctionInfo.ClassLiteral classLiteralInfo = (ForeignFunctionInfo.ClassLiteral)foreignFunctionInfo;
            final Class<?> referentType = SCJavaDefn.getReferentType(classLiteralInfo);

            returnExpression = new JavaExpression.ClassLiteral(JavaTypeName.make(referentType));

            if (boxResult) {
                ExpressionContextPair pair = returnTypeToCal(Class.class, returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind.isNullLiteral()) {

            returnExpression = JavaExpression.LiteralWrapper.NULL;
            if (boxResult) {
                final ExpressionContextPair pair = returnTypeToCal(SCJavaDefn.getJavaReturnType(foreignFunctionInfo), returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind.isNullCheck()) {

            final ForeignFunctionInfo.NullCheck nullCheckInfo = (ForeignFunctionInfo.NullCheck)foreignFunctionInfo;

            final Class<?> argType = SCJavaDefn.getJavaArgumentType(foreignFunctionInfo, 0);

            final ExpressionContextPair argExprPair = generateUnboxedForeignFunctionArgument(JavaTypeName.make(argType), basicOpExpressions.getArgument(0), variableContext);
            final JavaExpression argExpr = argExprPair.getJavaExpression();
            returnContext.addStatement(argExprPair.getContextBlock());

            final JavaOperator javaOp = nullCheckInfo.checkIsNull() ? JavaOperator.EQUALS_OBJECT : JavaOperator.NOT_EQUALS_OBJECT;

            returnExpression = new JavaExpression.OperatorExpression.Binary(javaOp, argExpr, LiteralWrapper.NULL);

            if (boxResult) {
                final ExpressionContextPair pair = returnTypeToCal(boolean.class, returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind == ForeignFunctionInfo.JavaKind.NEW_ARRAY) {

            //e.g. newString3Array :: Int -> Int -> JString3Array; (for new String[d1][d2][])

            //note, this may be less than the dimension of the array e.g. for new String[10][7][] this is 2.
            final int nJavaArgs = SCJavaDefn.getNArguments(foreignFunctionInfo);
            final Class<?> newArrayType = SCJavaDefn.getJavaReturnType(foreignFunctionInfo);

            final JavaExpression[] args = new JavaExpression[nJavaArgs];
            final JavaTypeName[] argTypeNames = new JavaTypeName[nJavaArgs];
            for (int i = 0; i < nJavaArgs; i++) {
                final ExpressionContextPair pair = generateUnboxedForeignFunctionArgument(JavaTypeName.INT, basicOpExpressions.getArgument(i), variableContext);
                args[i] = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
                argTypeNames[i] = JavaTypeName.INT;
            }

            returnExpression = new ClassInstanceCreationExpression(JavaTypeName.make(newArrayType), args, argTypeNames);

            if (boxResult) {
                final ExpressionContextPair pair = returnTypeToCal(newArrayType, returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind == ForeignFunctionInfo.JavaKind.LENGTH_ARRAY) {

            final Class<?> argType = SCJavaDefn.getJavaArgumentType(foreignFunctionInfo, 0);

            final ExpressionContextPair argExprPair = generateUnboxedForeignFunctionArgument(JavaTypeName.make(argType), basicOpExpressions.getArgument(0), variableContext);
            final JavaExpression argExpr = argExprPair.getJavaExpression();
            returnContext.addStatement(argExprPair.getContextBlock());

            returnExpression = new JavaExpression.ArrayLength(argExpr);

            if (boxResult) {
                final ExpressionContextPair pair = returnTypeToCal(int.class, returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);


        } else if (kind == ForeignFunctionInfo.JavaKind.SUBSCRIPT_ARRAY) {

            //e.g. subscriptString3Array :: String3Array -> Int -> Int -> StringArray;
            //for subscripting using 2 indices a 3-dimensional String array to get a 1-dimensional String array

            //note, this may be less than the dimension of the array e.g. for new String[10][7][] this is 2.
            final int nJavaArgs = SCJavaDefn.getNArguments(foreignFunctionInfo);
            final Class<?> subscriptedArrayType = SCJavaDefn.getJavaReturnType(foreignFunctionInfo);

            for (int i = 0; i < nJavaArgs; i++) {

                final JavaTypeName argTypeName = JavaTypeName.make(SCJavaDefn.getJavaArgumentType(foreignFunctionInfo, i));
                final ExpressionContextPair pair =
                    generateUnboxedForeignFunctionArgument(argTypeName, basicOpExpressions.getArgument(i), variableContext);
                returnContext.addStatement(pair.getContextBlock());

                if (i == 0) {
                    //the initial array expression
                    returnExpression = pair.getJavaExpression();
                } else {
                    //subscript by the next index
                    returnExpression = new JavaExpression.ArrayAccess(returnExpression, pair.getJavaExpression());
                }
            }

            if (boxResult) {
                final ExpressionContextPair pair = returnTypeToCal(subscriptedArrayType, returnExpression);
                returnExpression = pair.getJavaExpression();
                returnContext.addStatement(pair.getContextBlock());
            }

            return new ExpressionContextPair(returnExpression, returnContext);

        } else if (kind == ForeignFunctionInfo.JavaKind.UPDATE_ARRAY) {

            //e.g. updateString3Array :: String3Array -> Int -> Int -> StringArray -> StringArray;
            //for updating using 2 indices a 3-dimensional String array with a 1-dimensional String array

            //note, this may be less than the dimension of the array to update
            final int nJavaArgs = SCJavaDefn.getNArguments(foreignFunctionInfo);
            final Class<?> updatedElementType = SCJavaDefn.getJavaReturnType(foreignFunctionInfo);

            for (int i = 0; i < nJavaArgs; i++) {

                final JavaTypeName argTypeName = JavaTypeName.make(SCJavaDefn.getJavaArgumentType(foreignFunctionInfo, i));
                final ExpressionContextPair pair =
                    generateUnboxedForeignFunctionArgument(argTypeName, basicOpExpressions.getArgument(i), variableContext);
                returnContext.addStatement(pair.getContextBlock());

                if (i == 0) {

                    //the initial array expression
View Full Code Here

TOP

Related Classes of org.openquark.cal.internal.machine.BasicOpTuple

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.