Package org.openquark.cal.compiler

Examples of org.openquark.cal.compiler.Expression


     * @return null if this is not an SC application, array of Expression otherwise.
     */
    static private Expression[] appChain (Expression root) {
        if (root.asAppl() != null) {
            // Walk down the left branch.
            Expression c = root;
            int nArgs = 0;
            while (c instanceof Expression.Appl) {
                nArgs++;
                c = ((Expression.Appl)c).getE1();
            }
View Full Code Here


        // Has to match: EAp(EAp(EVar <op>) e1) e2, for a binary op
        // Has to match: EAp(EVar <op>) e1, for a unary op
        // Where e<n> are the argument expressions

        // Check for an application node spine, and count the number of arguments         
        Expression spineNode = e;    
        int nArguments = 0;            
        for (Expression.Appl applNode = e.asAppl (); applNode != null; applNode = spineNode.asAppl ())
        {
            if (applNode.getE2 () == null) {
                throw new IllegalArgumentException("Programming error. The argument 'e' is not a valid application node.");             
            }
           
            ++nArguments;
            spineNode = applNode.getE1 ();                   
        }      
               
        Expression.Var var = spineNode.asVar();
        if (var == null) {
            return null;
        }
          
        DataConstructor dc = var.getDataConstructor ();
       
        if (dc == null) {
            return null;
        }

        // Check that the full number of arguments are supplied.
        int nExpectedArguments = dc.getArity();
           
        if (nExpectedArguments != nArguments) {
            return null;
        }           
       
        if (testOnly) {
            return ConstructorOpTuple.emptyConstructorOpTuple;
        }
       
 
        Expression[] argumentExpressions = new Expression [nArguments];
        spineNode = e;
        for (int argN = nArguments - 1; argN >= 0; --argN)
        {
            Expression.Appl applNode = spineNode.asAppl();
            argumentExpressions[argN] = applNode.getE2 ();          
            spineNode = applNode.getE1 ();
        }
       
        return new ConstructorOpTuple (var, argumentExpressions);
View Full Code Here

     * @return null if this is not an SC application, array of Expression otherwise.
     */
    static private Expression[] appChain (Expression root) {
        if (root.asAppl() != null) {
            // Walk down the left branch.
            Expression c = root;
            int nArgs = 0;
            while (c instanceof Expression.Appl) {
                nArgs++;
                c = ((Expression.Appl)c).getE1();
            }
View Full Code Here

        // Save the supercombinator away in the object to save stack if we recurse
        this.currentMachineFunction = gmf;
        InstructionList gp = null;

        Expression e = gmf.getExpressionForm();

        // If this is a DataConstructor for an enumeration data type
        // we want to simply return as these are treates as int.
        Expression.PackCons packCons = e.asPackCons();
        if (packCons != null) {
            DataConstructor dc = packCons.getDataConstructor();
            if (TypeExpr.isEnumType(dc.getTypeConstructor())) {
                gmf.setCodeGenerated(true);
                return;
View Full Code Here

        // e is a record case
        Expression.RecordCase recordCase = e.asRecordCase();
        if (recordCase != null) {
            // Strictly compile the condition expression
            Expression conditionExpr = recordCase.getConditionExpr();
            gp.code (schemeE (conditionExpr, p, d));

            Map<QualifiedName, Integer> newEnv = argOffset (0, p);
            QualifiedName recordName = QualifiedName.make(currentMachineFunction.getQualifiedName().getModuleName(), "$recordCase");
            newEnv.put (recordName, Integer.valueOf(++d));

            //FieldName -> String
            SortedMap<FieldName, String> fieldBindingVarMap = recordCase.getFieldBindingVarMap();

            int recordPos = 0;

            // This creates, if necessary, a record equivalent to the original record minus the bound fields.         
            String baseRecordPatternVarName = recordCase.getBaseRecordPatternVarName();       
            if (baseRecordPatternVarName != null &&
                    !baseRecordPatternVarName.equals(Expression.RecordCase.WILDCARD_VAR)) {
                recordPos++;

                // Create a new record that is the original record minus the bound fields.
                QualifiedName qn = QualifiedName.make(currentMachineFunction.getQualifiedName().getModuleName(), baseRecordPatternVarName);
                newEnv.put (qn, Integer.valueOf(++d));

                // push the original record
                gp.code (new Instruction.I_Push(0));

                // consume the record on top of the stack and replace with an extended version
                gp.code (new Instruction.I_ExtendRecord());

                // Now remove fields from the record as appropriate.
                for (final FieldName fieldName : fieldBindingVarMap.keySet()) {
                  
                    gp.code (new Instruction.I_RemoveRecordField(fieldName.getCalSourceForm()));
                }

            }

            // Now push the values for the bound fields onto the stack.
            for (final Map.Entry<FieldName, String> entry : fieldBindingVarMap.entrySet()) {

                FieldName fieldName = entry.getKey();
                String bindingVarName = entry.getValue();

                //ignore anonymous pattern variables. These are guaranteed not to be used
                //by the result expression, and so don't need to be extracted from the condition record.
                if (!bindingVarName.equals(Expression.RecordCase.WILDCARD_VAR)) {

                    QualifiedName qn = QualifiedName.make(currentMachineFunction.getQualifiedName().getModuleName(), bindingVarName);
                    newEnv.put(qn, Integer.valueOf(++d));

                    gp.code (new Instruction.I_Push (recordPos));
                    gp.code (new Instruction.I_RecordSelection (fieldName.getCalSourceForm()));
                    recordPos++;
                }
            }

            //encode the result expression in the context of the extended variable scope.
            Expression resultExpr = recordCase.getResultExpr();
            gp.code (schemeR (resultExpr, newEnv, d));
            appendUpdateCode(gp, d);
            return gp;
        }
View Full Code Here

                MACHINE_LOGGER.log(Level.FINE, "    Application:");
            }

            // e is an application
            // Get e1 (LHS) and e2 (RHS) expressions
            Expression e1 = appl.getE1();
            Expression e2 = appl.getE2();

            InstructionList gpe2 = schemeC (e2, p, d);
            InstructionList gpe1 = schemeRS (e1, p, d + 1, n + 1);
            if (gpe1 == null) {
                // The RHS could not be handled by schemeRC.  Return null and let the calling code
View Full Code Here

        if (recordUpdateExpr  != null) {
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    Record extension:");
            }

            Expression baseRecordExpr = recordUpdateExpr .getBaseRecordExpr();

            //FieldName -> Expression
            Map<FieldName, Expression> updateFieldValuesMap = recordUpdateExpr .getUpdateFieldValuesMap();

            // Strictly evaluate the base record.
            gp.code(schemeE (baseRecordExpr, p, d));

            // Create a new record that is a copy of the base record.
            gp.code(new Instruction.I_ExtendRecord());          

            // Put the field values into the new record instance.
            for (final Map.Entry<FieldName, Expression> entry : updateFieldValuesMap.entrySet()) {              
                FieldName fieldName = entry.getKey();
                Expression valueExpr = entry.getValue();
                gp.code (schemeC (valueExpr, p, d+1));
                gp.code (new Instruction.I_PutRecordField(fieldName.getCalSourceForm()));
            }

            return gp;
        }         

        // Is e a record extension
        Expression.RecordExtension recordExtensionExpr = e.asRecordExtension();
        if (recordExtensionExpr != null) {
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    Record extension:");
            }

            Expression baseRecordExpr = recordExtensionExpr.getBaseRecordExpr();

            //FieldName -> Expression
            Map<FieldName, Expression> extensionFieldsMap = recordExtensionExpr.getExtensionFieldsMap();

            if (baseRecordExpr == null) {
                // No base record so create a new one.
                gp.code(new Instruction.I_CreateRecord(extensionFieldsMap.size()));      
            } else {
                // Strictly evaluate the base record.
                gp.code(schemeE (baseRecordExpr, p, d));

                // Create a new record that is a copy of the base record.
                gp.code(new Instruction.I_ExtendRecord());
            }

            // Put the field values into the new record instance.
            for (final Map.Entry<FieldName, Expression> entry : extensionFieldsMap.entrySet()) {             
                FieldName fieldName = entry.getKey();
                Expression valueExpr = entry.getValue();
                gp.code (schemeC (valueExpr, p, d+1));
                gp.code (new Instruction.I_PutRecordField(fieldName.getCalSourceForm()));
            }

            return gp;
       

        // e is a record selection
        Expression.RecordSelection recordSelection = e.asRecordSelection();
        if (recordSelection != null) {
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    Record selection:");
            }

            Expression recordExpr = recordSelection.getRecordExpr();
            String fieldName = recordSelection.getFieldName().getCalSourceForm();

            // Evaluate the record to WHNF.           
            gp.code(schemeE(recordExpr, p, d));
View Full Code Here

                MACHINE_LOGGER.log(Level.FINE, "    Application:");
            }

            // e is an application
            // Get e1 (LHS) and e2 (RHS) expressions
            Expression e1 = appl.getE1();
            Expression e2 = appl.getE2();

            InstructionList gpe2 = schemeC (e2, p, d);
            InstructionList gpe1 = schemeES (e1, p, d + 1, n + 1);
            if (gpe1 == null) {
                // The RHS could not be compiled by the RS scheme.  Return null and let
View Full Code Here

                MACHINE_LOGGER.log(Level.FINE, "    Application:");
            }

            // e is an application
            // Get e1 (LHS) and e2 (RHS) expressions
            Expression e1 = appl.getE1();
            Expression e2 = appl.getE2();

            InstructionList gpe2 = schemeC (e2, p, d);
            InstructionList gpe1 = schemeC (e1, p, d + 1);

            gp.code (gpe2);
            gp.code (gpe1);
            gp.code  (new Instruction.I_MkapN ());

            return gp;
        }  

        // Is e a let expression?
        Expression.Let let = e.asLet();
        if (let != null) {
            // Currently the compiler doesn't differentialte between let and letrec scenarios.
            // As such we have to treat all lets as letrecs.

            Expression.Let.LetDefn[] defs = let.getDefns();

            EnvAndDepth ead = schemeXr (defs, p, d);           

            InstructionList gprecs = schemeCLetrec (defs, ead.env, ead.depth);

            gp.code (gprecs);

            gp.code (schemeC (let.getBody (), ead.env, ead.depth));

            if (ead.depth - d > 0) {
                gp.code (new Instruction.I_Slide (ead.depth - d));
            }

            return gp; 
        }

        Expression.RecordUpdate recordUpdateExpr = e.asRecordUpdate();
        if (recordUpdateExpr != null) {
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    Record update:");
            }

            Expression baseRecordExpr = recordUpdateExpr.getBaseRecordExpr();

            //FieldName -> Expression
            Map<FieldName, Expression> updateFieldValuesMap = recordUpdateExpr.getUpdateFieldValuesMap();

            // Lazy evaluation of the base record.
            gp.code(schemeC (baseRecordExpr, p, d));

            // Create an application of the virtual update function to the base record.
            gp.code(new Instruction.I_LazyRecordUpdate());

            // Add field values.  In the case of extending an existing record these are
            // added to the record extension node as if they were further arguments in
            // the application chain for the virtual function.
            for (final Map.Entry<FieldName, Expression> entry : updateFieldValuesMap.entrySet()) {            
                FieldName fieldName = entry.getKey();
                Expression valueExpr = entry.getValue();
                gp.code (schemeC (valueExpr, p, d+1));
                gp.code (new Instruction.I_PutRecordField(fieldName.getCalSourceForm()));
            }

            return gp;           
        }

        // Is e a record extension
        // e is a record extension
        Expression.RecordExtension recordExtensionExpr = e.asRecordExtension();
        if (recordExtensionExpr != null) {
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    Record extension:");
            }

            Expression baseRecordExpr = recordExtensionExpr.getBaseRecordExpr();

            //FieldName -> Expression
            Map<FieldName, Expression> extensionFieldsMap = recordExtensionExpr.getExtensionFieldsMap();

            if (baseRecordExpr == null) {
                // No base record so we create a new one.
                gp.code(new Instruction.I_CreateRecord(extensionFieldsMap.size()));      
            } else {
                // Lazy evaluation of the base record.
                gp.code(schemeC (baseRecordExpr, p, d));

                // Create an application of the virtual extension function to the base record.
                gp.code(new Instruction.I_LazyRecordExtension());
            }

            // Add field values.  In the case of extending an existing record these are
            // added to the record extension node as if they were further arguments in
            // the application chain for the virtual function.
            for (final Map.Entry<FieldName, Expression> entry : extensionFieldsMap.entrySet()) {                
                FieldName fieldName = entry.getKey();
                Expression valueExpr = entry.getValue();
                gp.code (schemeC (valueExpr, p, d+1));
                gp.code (new Instruction.I_PutRecordField(fieldName.getCalSourceForm()));
            }

            return gp;
       

        // e is a record selection
        Expression.RecordSelection recordSelection = e.asRecordSelection();
        if (recordSelection != null) {
            if (CODEGEN_DIAG) {
                MACHINE_LOGGER.log(Level.FINE, "    Record selection:");
            }

            Expression recordExpr = recordSelection.getRecordExpr();
            String fieldName = recordSelection.getFieldName().getCalSourceForm();

            // If we can ignore laziness for the base record (i.e. it can be safely
            // forced to WHNF) then we can just select the field value, but don't force
            // the field value to WHNF
View Full Code Here

            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
        // expression and the field is strict.
        if (e.asDataConsSelection() != null) {
            Expression.DataConsSelection dcs = (Expression.DataConsSelection)e;
            if (dcs.getDataConstructor().isArgStrict(dcs.getFieldIndex()) && canIgnoreLaziness(dcs.getDCValueExpr(), env)) {
                return true;
            }
        }

        // 'if a then b else c' where laziness can be ignore for a, b, and c.
        CondTuple conditionExpressions = CondTuple.isCondOp(e);
        if (conditionExpressions != null) {
            Expression condExpr = conditionExpressions.getConditionExpression();
            Expression thenExpr = conditionExpressions.getThenExpression();
            Expression elseExpr = conditionExpressions.getElseExpression();
            if (canIgnoreLaziness(condExpr, env) &&
                    canIgnoreLaziness(thenExpr, env) &&
                    canIgnoreLaziness(elseExpr, env)) {
                return true;
            }
View Full Code Here

TOP

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

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.