Package org.openquark.cal.compiler

Examples of org.openquark.cal.compiler.DataConstructor


     *   0-length array if the alt's tag is not a data constructor.
     */
    private String[] getVars(Expression.Switch.SwitchAlt alt, Object altTag) {

        if (altTag instanceof DataConstructor) {
            DataConstructor dataCons = (DataConstructor)altTag;
            String[] vars = new String[dataCons.getArity()];
            Arrays.fill(vars, Expression.Switch.SwitchAlt.WILDCARD_VAR);

            if (alt instanceof Expression.Switch.SwitchAlt.Positional) {
                Map<Integer, String> positionToVarNameMap = ((Expression.Switch.SwitchAlt.Positional)alt).getPositionToVarNameMap();
                for (final Map.Entry<Integer, String> entry : positionToVarNameMap.entrySet()) {
                  
                    Integer positionInteger = entry.getKey();
                    String varName = entry.getValue();

                    int fieldIndex = positionInteger.intValue();
                    vars[fieldIndex] = varName;
                }
            } else {
                // Must be matching.
                Map<FieldName, String> fieldNameToVarNameMap = ((Expression.Switch.SwitchAlt.Matching)alt).getFieldNameToVarNameMap();
                for (final Map.Entry<FieldName, String> entry : fieldNameToVarNameMap.entrySet()) {                  
                    FieldName fieldName = entry.getKey();
                    String varName = entry.getValue();

                    int fieldIndex = dataCons.getFieldIndex(fieldName);
                    vars[fieldIndex] = varName;
                }
            }

            return vars;
View Full Code Here


        }

        // Is e an application of a saturated constructor?
        ConstructorOpTuple constructorOpTuple = ConstructorOpTuple.isConstructorOp(e, false);
        if (constructorOpTuple != null) {
            DataConstructor dc = constructorOpTuple.getDataConstructor ();

            boolean[] fieldStrictness = new boolean [dc.getArity()];
            boolean dcHasStrictFields = false;
            for (int i = 0; i < dc.getArity(); ++i) {
                fieldStrictness[i] = dc.isArgStrict(i);
                if (fieldStrictness[i]) {
                    dcHasStrictFields = true;
                }
            }

            // If there are no strict arguments we can simply create an instance of the DC class.
            // The simplest way to do this is to treat this DC application as if it were in a strict context.
            if (!dcHasStrictFields) {
                return true;
            } else {
                // If all strict arguments are already evaluated, or we consider them safe to evaluate (i.e. cheap and
                // with no side effects) we can treat this as strict.
                boolean allOK = true;
                for (int i = 0; i < dc.getArity(); ++i) {
                    if (dc.getArgStrictness()[i] && !canIgnoreLaziness(constructorOpTuple.getArgument(i), env)) {
                        allOK = false;
                        break;
                    }
                }

                if (allOK) {
                    return true;
                }
            }       
        }

        // 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) {
                return true;
            }
        }

        // If e is a fully saturated application of a function tagged for optimization and
        // all the arguments are in WHNF or can have laziness ignored we can
        // ignore laziness for the application.
        if (e.asAppl() != null) {
            Expression[] chain = appChain(e.asAppl());
            if (chain[0].asVar() != null) {
                // Get the supercombinator on the left end of the chain.
                Expression.Var scVar = chain[0].asVar();
                if (scVar != null) {
                    // Check if this supercombinator is one we should try to optimize.
                    MachineFunction mf = currentModule.getFunction(scVar.getName());
                    if (mf != null && mf.canFunctionBeEagerlyEvaluated()) {

                        // Now determine the arity of the SC.
                        int calledArity = mf.getArity();

                        // Check to see if we can ignore laziness for all the arguments.
                        if (chain.length - 1 == calledArity) {
                            int nWHNFArgs = 0;
                            for (int i = 0; i < calledArity; ++i) {
                                if (canIgnoreLaziness(chain[i+1], env)) {
                                    nWHNFArgs++;
                                }
                            }

                            if (nWHNFArgs == calledArity) {
                                return true;
                            }
                        }
                    }
                }
            }
        }

        // Is e an application of a zero arity constructor.
        if (ConstructorOpTuple.isConstructorOp(e, true) != null) {
            ConstructorOpTuple  constructorOpExpressions = ConstructorOpTuple.isConstructorOp(e, false);

            DataConstructor dc = constructorOpExpressions.getDataConstructor ();

            if (dc.getArity() == 0){
                return true;
            }
        }

        // Is e a DataConsFieldSelection where the laziness can be ignored for the data constructor
View Full Code Here

            break;
           
            case Instruction.T_PackCons:
                int arity = inst.getArity();
                int ord = inst.getOrd();
                DataConstructor tag = (DataConstructor)inst.getInfo();
               
                if (CALL_COUNTS) {
                    i_instrument (new Executor.CallCountInfo((tag).getName(), "DataConstructor instance counts"));
                }
               
View Full Code Here

        // Is e an application of a zero arity constructor.
        if (ConstructorOpTuple.isConstructorOp(e, true) != null) {
            ConstructorOpTuple  constructorOpExpressions = ConstructorOpTuple.isConstructorOp(e, false);

            DataConstructor dc = constructorOpExpressions.getDataConstructor ();

            if (dc.getArity() == 0){
                return true;
            }
        }

        // Is e a DataConsFieldSelection where the data constructor expression can be shortcutted and
View Full Code Here

        }

        for (final ReferencedDCInfo rfi : sharedValues.getReferencedDCs()) {

            if (rfi.getGeneratedClassTypeName().equals(type)) {
                DataConstructor odc = rfi.getDC();
                if (dc == odc) {
                    return rfi.getJField();
                    //don't need to copy, JavaField is immutable!
                    //return new JavaField (field);
                }
View Full Code Here

     * @return the ExpressionContextPair describing the java equivalent of the literal list.
     * @throws CodeGenerationException
     */
    private ExpressionContextPair compileLiteralList (ConstructorOpTuple constructorOpExpressions, Scheme scheme, VariableContext variableContext) throws CodeGenerationException {
        // Because of the recursive nature of the List data structur we handle literal lists as a special case.
        DataConstructor dc = constructorOpExpressions.getDataConstructor ();
        QualifiedName qn = dc.getName();
        if (!qn.equals(CAL_Prelude.DataConstructors.Cons)) {
            return null;
        }

        JavaTypeName dcTypeName = CALToJavaNames.createTypeNameFromDC(dc, module);

        int nArgs = 2;
        boolean addEC = LECCMachineConfiguration.passExecContextToDataConstructors();
        if (addEC) {
            nArgs++;
        }

        JavaExpression constructorArgs[] = null;
        JavaExpression lastConstructorArgs[] = null;
        JavaTypeName constructorArgTypes[] = new JavaTypeName[nArgs];
        Arrays.fill(constructorArgTypes, JavaTypeNames.RTVALUE);
        if (addEC) {
            constructorArgTypes[dc.getArity()] = JavaTypeNames.RTEXECUTION_CONTEXT;
        }

        JavaExpression listCreation = null;
        Block contextBlock = null;
        boolean moreListElements = true;
        do {
            moreListElements = false;
            ExpressionContextPair leftArg = genS_C(constructorOpExpressions.getArgument(0), variableContext);
            if (contextBlock == null) {
                contextBlock = leftArg.getContextBlock();
            } else {
                contextBlock.addStatement(leftArg.getContextBlock());
            }

            constructorArgs = new JavaExpression [nArgs];
            if (addEC) {
                constructorArgs[dc.getArity()] = EXECUTION_CONTEXT_VAR;
            }

            constructorArgs[0] = leftArg.getJavaExpression();

            ClassInstanceCreationExpression cc =
View Full Code Here

        ExpressionContextPair list = compileLiteralList(constructorOpExpressions, scheme, variableContext);
        if (list != null) {
            return list;
        }

        DataConstructor dc = constructorOpExpressions.getDataConstructor ();

        // If we are dealing with a data constructor for the CAL type boolean we want to optimize
        // by substituting and instance of the literal RTKernel.CAL_Boolean.
        if (isTrueOrFalseDataCons(dc)) {
            LiteralWrapper boolWrapper = LiteralWrapper.make(Boolean.valueOf(isTrueDataCons(dc)));

            return new ExpressionContextPair(createMakeKernelBooleanInvocation(boolWrapper));
        }

        if (LECCMachineConfiguration.TREAT_ENUMS_AS_INTS) {
            if (isEnumDataType(dc)) {
                // We should never see a DataConstructor instance for an enumeration type.
                throw new CodeGenerationException("Encountered enumeration data constructor: " + dc.getName().getQualifiedName());
            }
        }

        int arity = dc.getArity();

        JavaTypeName dcTypeName = CALToJavaNames.createTypeNameFromDC(dc, module);
        Block argContext = new Block();

        boolean[] fieldStrictness = new boolean [dc.getArity()];
        boolean dcHasStrictFields = false;
        if (LECCMachineConfiguration.IGNORE_STRICTNESS_ANNOTATIONS) {
            Arrays.fill(fieldStrictness, false);
        } else {
            for (int i = 0; i < dc.getArity(); ++i) {
                fieldStrictness[i] = dc.isArgStrict(i);
                if (fieldStrictness[i]) {
                    dcHasStrictFields = true;
                }
            }
        }

        // If there are no strict arguments we can simply create an instance of the DC class.
        // The simplest way to do this is to treat this DC application as if it were in a strict context.
        if (!dcHasStrictFields) {
            scheme = Scheme.E_SCHEME;
        } else {
            // If all strict arguments are already evaluated, or we consider them safe to evaluate (i.e. cheap and
            // with no side effects) we can treat this as strict.
            boolean allOK = true;
            for (int i = 0; i < dc.getArity(); ++i) {
                if (dc.getArgStrictness()[i] && !canIgnoreLaziness(constructorOpExpressions.getArgument(i), variableContext)) {
                    allOK = false;
                    break;
                }
            }

            if (allOK) {
                scheme = Scheme.E_SCHEME;
            }
        }

        if (arity < 0) {
            throw new CodeGenerationException("Invalid constructor operator arity: " + arity);
        } else
        if (arity == 0) {
            JavaExpression dcInstance;
            JavaTypeName typeName = CALToJavaNames.createTypeNameFromDC(dc, module);
            if (LECCMachineConfiguration.generateStatistics()) {
                // If this is a TagDC we want to pass the ordinal as an argument
                if (isTagDC(dc, getModule())) {
                    dcInstance = new ClassInstanceCreationExpression(typeName, JavaExpression.LiteralWrapper.make(Integer.valueOf(dc.getOrdinal())), JavaTypeName.INT);
                } else {
                    dcInstance = new ClassInstanceCreationExpression(typeName, SCJavaDefn.EXECUTION_CONTEXT_VAR, JavaTypeNames.RTEXECUTION_CONTEXT);
                }
            } else {
                dcInstance = getReferencedDC(typeName, dc);
            }
            return new ExpressionContextPair(dcInstance, argContext);
        } else{
            if (scheme == Scheme.C_SCHEME) {
                // This is a fully saturated DC application in a lazy context.
                // If there are no strict fields in the data constructor we can
                // simply create an instance of it.  Otherwise create an
                // appropriate application node.

                // First generate the java expressions for the CAL expressions.
                ExpressionContextPair[] ecp = new ExpressionContextPair[dc.getArity()];

                for (int i = 0; i < dc.getArity(); ++i) {
                    ecp[i] = genS_C(constructorOpExpressions.getArgument(i), variableContext);
                }

                Block newContext = ecp[0].getContextBlock();
                for (int i = 1; i < dc.getArity(); ++i) {
                    newContext.addStatement(ecp[i].getContextBlock());
                }

                JavaExpression dcExpr = expressionVarToJavaDef(constructorOpExpressions.getDataConstructorExpression(), scheme, variableContext);

                if (dc.getArity() <= LECCMachineConfiguration.OPTIMIZED_APP_CHAIN_LENGTH) {
                    JavaExpression nodeArgs[] = new JavaExpression[dc.getArity() + 1];
                    JavaTypeName nodeArgTypes[] = new JavaTypeName[dc.getArity() + 1];
                    nodeArgs[0] = dcExpr;
                    nodeArgTypes[0] = JavaTypeNames.RTSUPERCOMBINATOR;
                    for (int i = 0; i < dc.getArity(); ++i) {
                        nodeArgs[i+1] = ecp[i].getJavaExpression();
                        nodeArgTypes[i+1] = JavaTypeNames.RTVALUE;
                    }

                    JavaTypeName appNodeType = getTypeNameForApplicationNode(dc.getArity(), false);

                    return new ExpressionContextPair(new JavaExpression.ClassInstanceCreationExpression(appNodeType, nodeArgs, nodeArgTypes), newContext);
                } else {
                    JavaExpression target = dcExpr;
                    for (int i = 0; i < dc.getArity(); ++i) {
                        target = createInvocation(target, APPLY, ecp[i].getJavaExpression());
                    }
                    return new ExpressionContextPair (target, newContext);
                }
            } else {
                // This is a fully saturated DC application in a strict context.  Create a
                // new DC class instance.

                // First generate the java expressions for the members.
                ExpressionContextPair[] ecp = new ExpressionContextPair[dc.getArity()];
                TypeExpr[] fieldTypes = SCJavaDefn.getFieldTypesForDC(dc);

                for (int i = 0; i < dc.getArity(); ++i) {
                    if (fieldStrictness[i]) {
                        if (SCJavaDefn.canTypeBeUnboxed(fieldTypes[i])) {
                            ecp[i] = generateUnboxedArgument(typeExprToTypeName(fieldTypes[i]), constructorOpExpressions.getArgument(i), variableContext);
                        } else {
                            ecp[i] = genS_E(constructorOpExpressions.getArgument(i), variableContext);
                        }
                    } else {
                        ecp[i] = genS_C(constructorOpExpressions.getArgument(i), variableContext);
                    }
                }

                Block newContext = ecp[0].getContextBlock();
                for (int i = 1; i < dc.getArity(); ++i) {
                    newContext.addStatement(ecp[i].getContextBlock());
                }

                int nArgs = dc.getArity();
                boolean addEC = LECCMachineConfiguration.passExecContextToDataConstructors();
                if (addEC) {
                    nArgs++;
                }

                JavaExpression[] constructorArgs = new JavaExpression [nArgs];
                JavaTypeName[] constructorArgTypes = new JavaTypeName [nArgs];
                for (int i = 0; i < dc.getArity(); ++i) {
                    constructorArgs[i] = ecp[i].getJavaExpression();
                    constructorArgTypes[i] = JavaTypeNames.RTVALUE;
                    if (fieldStrictness[i] && SCJavaDefn.canTypeBeUnboxed(fieldTypes[i])) {
                        constructorArgTypes[i] = SCJavaDefn.typeExprToTypeName(fieldTypes[i]);
                    }
                }

                if (addEC) {
                    constructorArgs[dc.getArity()] = EXECUTION_CONTEXT_VAR;
                    constructorArgTypes[dc.getArity()] = JavaTypeNames.RTEXECUTION_CONTEXT;
                }

                ClassInstanceCreationExpression cc = new ClassInstanceCreationExpression (dcTypeName, constructorArgs, constructorArgTypes);
                return new ExpressionContextPair (cc, newContext);
            }
View Full Code Here

            // Is e an application of a saturated constructor?
            if (ConstructorOpTuple.isConstructorOp(e, true) != null) {
                ConstructorOpTuple  constructorOpExpressions = ConstructorOpTuple.isConstructorOp(e, false);

                DataConstructor dc = constructorOpExpressions.getDataConstructor ();

                // If we are dealing with a data constructor for the CAL type boolean we want to optimize
                // by substituting the literal boolean values.
                if (isTrueOrFalseDataCons(dc)) {
                    verifyUnboxType(unboxType, JavaTypeName.BOOLEAN);
                    LiteralWrapper boolWrapper = LiteralWrapper.make(Boolean.valueOf(isTrueDataCons(dc)));
                    return new ExpressionContextPair(boolWrapper);
                }

                if (LECCMachineConfiguration.TREAT_ENUMS_AS_INTS) {
                    if (SCJavaDefn.isEnumDataType(dc)) {
                        verifyUnboxType(unboxType, JavaTypeName.INT);
                           return new ExpressionContextPair (LiteralWrapper.make (Integer.valueOf(dc.getOrdinal())));
                    }
                }
            }

            // Is e a dc field selection?
View Full Code Here

            // Is e an application of a saturated constructor?
            if (ConstructorOpTuple.isConstructorOp(e, true) != null) {
                ConstructorOpTuple  constructorOpExpressions = ConstructorOpTuple.isConstructorOp(e, false);

                DataConstructor dc = constructorOpExpressions.getDataConstructor ();

                // If we are dealing with a data constructor for the CAL type boolean we want to optimize
                // by substituting and instance of the literal RTKernel.CAL_Boolean.
                if (isTrueOrFalseDataCons(dc)) {
                    verifyUnboxType(unboxType, JavaTypeName.BOOLEAN);
                    LiteralWrapper boolWrapper = LiteralWrapper.make(Boolean.valueOf(isTrueDataCons(dc)));
                    return new ExpressionContextPair(boolWrapper);
                }

                if (LECCMachineConfiguration.TREAT_ENUMS_AS_INTS) {
                    if (SCJavaDefn.isEnumDataType(dc)) {
                        verifyUnboxType(unboxType, JavaTypeName.INT);
                        return new ExpressionContextPair (LiteralWrapper.make (Integer.valueOf(dc.getOrdinal())));
                    }
                }

            }
View Full Code Here

        // If the field is a strict primitive we can use
        // the version of getFieldByIndex() which returns an unboxed
        // value.
        // Assuming of course that the expected unboxed type is compatible with
        // the type of the field.
        DataConstructor dc = dcs.getDataConstructor();
        TypeExpr[] fieldTypes = SCJavaDefn.getFieldTypesForDC(dc);
        TypeExpr fieldType = fieldTypes[dcs.getFieldIndex()];

        if (unboxedType == null) {
            // The type of the unboxed value is irrelevent so set it to be the same type as the field.
            if (dc.isArgStrict(dcs.getFieldIndex())) {
                unboxedType = SCJavaDefn.typeExprToTypeName(fieldType);
            } else {
                unboxedType = JavaTypeNames.RTVALUE;
            }
        }

        // Check that the field is strict and can be unboxed.
        boolean directlyRetrieveUnboxed = dc.isArgStrict(dcs.getFieldIndex()) &&
                                          SCJavaDefn.canTypeBeUnboxed(fieldType);

        // Now check compatability of the expected type and the field type.
        if (directlyRetrieveUnboxed) {
            verifyUnboxType(unboxedType, SCJavaDefn.typeExprToTypeName(fieldType));
View Full Code Here

TOP

Related Classes of org.openquark.cal.compiler.DataConstructor

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.