Search in sources :

Example 1 with Assignment

use of org.lflang.lf.Assignment in project lingua-franca by lf-lang.

the class CParameterGenerator method getInitializer.

/**
 * Return a C expression that can be used to initialize the specified
 * parameter instance. If the parameter initializer refers to other
 * parameters, then those parameter references are replaced with
 * accesses to the self struct of the parents of those parameters.
 */
public static String getInitializer(ParameterInstance p) {
    // Handle the bank_index parameter.
    if (p.getName().equals("bank_index")) {
        return CUtil.bankIndex(p.getParent());
    }
    // Handle overrides in the intantiation.
    // In case there is more than one assignment to this parameter, we need to
    // find the last one.
    Assignment lastAssignment = null;
    for (Assignment assignment : p.getParent().getDefinition().getParameters()) {
        if (assignment.getLhs() == p.getDefinition()) {
            lastAssignment = assignment;
        }
    }
    List<String> list = new LinkedList<>();
    if (lastAssignment != null) {
        // Right hand side can be a list. Collect the entries.
        for (Value value : lastAssignment.getRhs()) {
            if (value.getParameter() != null) {
                // The parameter is being assigned a parameter value.
                // Assume that parameter belongs to the parent's parent.
                // This should have been checked by the validator.
                list.add(CUtil.reactorRef(p.getParent().getParent()) + "->" + value.getParameter().getName());
            } else {
                list.add(GeneratorBase.getTargetTime(value));
            }
        }
    } else {
        // parameter's initial value.
        for (Value i : p.getParent().initialParameterValue(p.getDefinition())) {
            if (ASTUtils.isOfTimeType(p.getDefinition())) {
                list.add(GeneratorBase.getTargetTime(i));
            } else {
                list.add(GeneratorBase.getTargetTime(i));
            }
        }
    }
    if (list.size() == 1) {
        return list.get(0);
    } else {
        return "{" + String.join(", ", list) + "}";
    }
}
Also used : Assignment(org.lflang.lf.Assignment) Value(org.lflang.lf.Value) LinkedList(java.util.LinkedList)

Example 2 with Assignment

use of org.lflang.lf.Assignment in project lingua-franca by lf-lang.

the class ASTUtils method getDelayInstance.

/**
 * Create a new instance delay instances using the given reactor class.
 * The supplied time value is used to override the default interval (which
 * is zero).
 * If the target supports parametric polymorphism, then a single class may
 * be used for each instantiation, in which case a non-empty string must
 * be supplied to parameterize the instance.
 * A default name ("delay") is assigned to the instantiation, but this
 * name must be overridden at the call site, where checks can be done to
 * avoid name collisions in the container in which the instantiation is
 * to be placed. Such checks (or modifications of the AST) are not
 * performed in this method in order to avoid causing concurrent
 * modification exceptions.
 * @param delayClass The class to create an instantiation for
 * @param connection The connection to create a delay instantiation foe
 * @param generic A string that denotes the appropriate type parameter,
 *  which should be null or empty if the target does not support generics.
 * @param defineWidthFromConnection If this is true and if the connection
 *  is a wide connection, then instantiate a bank of delays where the width
 *  is given by ports involved in the connection. Otherwise, the width will
 *  be  unspecified indicating a variable length.
 */
private static Instantiation getDelayInstance(Reactor delayClass, Connection connection, String generic, Boolean defineWidthFromConnection) {
    Delay delay = connection.getDelay();
    Instantiation delayInstance = factory.createInstantiation();
    delayInstance.setReactorClass(delayClass);
    if (!StringExtensions.isNullOrEmpty(generic)) {
        TypeParm typeParm = factory.createTypeParm();
        typeParm.setLiteral(generic);
        delayInstance.getTypeParms().add(typeParm);
    }
    if (hasMultipleConnections(connection)) {
        WidthSpec widthSpec = factory.createWidthSpec();
        if (defineWidthFromConnection) {
            // to delay the ports first, and then broadcast the output of the delays.
            for (VarRef port : connection.getLeftPorts()) {
                WidthTerm term = factory.createWidthTerm();
                term.setPort(EcoreUtil.copy(port));
                widthSpec.getTerms().add(term);
            }
        } else {
            widthSpec.setOfVariableLength(true);
        }
        delayInstance.setWidthSpec(widthSpec);
    }
    Assignment assignment = factory.createAssignment();
    assignment.setLhs(delayClass.getParameters().get(0));
    Value value = factory.createValue();
    if (delay.getParameter() != null) {
        value.setParameter(delay.getParameter());
    } else {
        value.setTime(delay.getTime());
    }
    assignment.getRhs().add(value);
    delayInstance.getParameters().add(assignment);
    // This has to be overridden.
    delayInstance.setName("delay");
    return delayInstance;
}
Also used : VarRef(org.lflang.lf.VarRef) Assignment(org.lflang.lf.Assignment) Value(org.lflang.lf.Value) Instantiation(org.lflang.lf.Instantiation) WidthTerm(org.lflang.lf.WidthTerm) Delay(org.lflang.lf.Delay) TypeParm(org.lflang.lf.TypeParm) WidthSpec(org.lflang.lf.WidthSpec)

Example 3 with Assignment

use of org.lflang.lf.Assignment in project lingua-franca by lf-lang.

the class ASTUtils method initialValue.

/**
 * Given a parameter, return its initial value.
 * The initial value is a list of instances of Value, where each
 * Value is either an instance of Time, Literal, or Code.
 *
 * If the instantiations argument is null or an empty list, then the
 * value returned is simply the default value given when the parameter
 * is defined.
 *
 * If a list of instantiations is given, then the first instantiation
 * is required to be an instantiation of the reactor class that is
 * parameterized by the parameter. I.e.,
 * ```
 *     parameter.eContainer == instantiations.get(0).reactorClass
 * ```
 * If a second instantiation is given, then it is required to be an instantiation of a
 * reactor class that contains the first instantiation.  That is,
 * ```
 *     instantiations.get(0).eContainer == instantiations.get(1).reactorClass
 * ```
 * More generally, for all 0 <= i < instantiations.size - 1,
 * ```
 *     instantiations.get(i).eContainer == instantiations.get(i + 1).reactorClass
 * ```
 * If any of these conditions is not satisfied, then an IllegalArgumentException
 * will be thrown.
 *
 * Note that this chain of reactions cannot be inferred from the parameter because
 * in each of the predicates above, there may be more than one instantiation that
 * can appear on the right hand side of the predicate.
 *
 * For example, consider the following program:
 * ```
 *     reactor A(x:int(1)) {}
 *     reactor B(y:int(2)) {
 *         a1 = new A(x = y);
 *         a2 = new A(x = -1);
 *     }
 *     reactor C(z:int(3)) {
 *         b1 = new B(y = z);
 *         b2 = new B(y = -2);
 *     }
 * ```
 * Notice that there are a total of four instances of reactor class A.
 * Then
 * ```
 *     initialValue(x, null) returns 1
 *     initialValue(x, [a1]) returns 2
 *     initialValue(x, [a2]) returns -1
 *     initialValue(x, [a1, b1]) returns 3
 *     initialValue(x, [a2, b1]) returns -1
 *     initialValue(x, [a1, b2]) returns -2
 *     initialValue(x, [a2, b2]) returns -1
 * ```
 * (Actually, in each of the above cases, the returned value is a list with
 * one entry, a Literal, e.g. ["1"]).
 *
 * There are two instances of reactor class B.
 * ```
 *     initialValue(y, null) returns 2
 *     initialValue(y, [a1]) throws an IllegalArgumentException
 *     initialValue(y, [b1]) returns 3
 *     initialValue(y, [b2]) returns -2
 * ```
 *
 * @param parameter The parameter.
 * @param instantiations The (optional) list of instantiations.
 *
 * @return The value of the parameter.
 *
 * @throws IllegalArgumentException If an instantiation provided is not an
 *  instantiation of the reactor class that is parameterized by the
 *  respective parameter or if the chain of instantiations is not nested.
 */
public static List<Value> initialValue(Parameter parameter, List<Instantiation> instantiations) {
    // the first of those instantiations.
    if (instantiations != null && instantiations.size() > 0) {
        // Check to be sure that the instantiation is in fact an instantiation
        // of the reactor class for which this is a parameter.
        Instantiation instantiation = instantiations.get(0);
        if (!belongsTo(parameter, instantiation)) {
            throw new IllegalArgumentException("Parameter " + parameter.getName() + " is not a parameter of reactor instance " + instantiation.getName() + ".");
        }
        // In case there is more than one assignment to this parameter, we need to
        // find the last one.
        Assignment lastAssignment = (Assignment) null;
        for (Assignment assignment : instantiation.getParameters()) {
            if (assignment.getLhs().equals(parameter)) {
                lastAssignment = assignment;
            }
        }
        if (lastAssignment != null) {
            // Right hand side can be a list. Collect the entries.
            List<Value> result = new ArrayList<>();
            for (Value value : lastAssignment.getRhs()) {
                if (value.getParameter() != null) {
                    if (instantiations.size() > 1 && instantiation.eContainer() != instantiations.get(1).getReactorClass()) {
                        throw new IllegalArgumentException("Reactor instance " + instantiation.getName() + " is not contained by instance " + instantiations.get(1).getName() + ".");
                    }
                    result.addAll(initialValue(value.getParameter(), instantiations.subList(1, instantiations.size())));
                } else {
                    result.add(value);
                }
            }
            return result;
        }
    }
    // parameter's initial value.
    return parameter.getInit();
}
Also used : Assignment(org.lflang.lf.Assignment) Value(org.lflang.lf.Value) ArrayList(java.util.ArrayList) Instantiation(org.lflang.lf.Instantiation)

Example 4 with Assignment

use of org.lflang.lf.Assignment in project lingua-franca by lf-lang.

the class PythonParameterGenerator method generatePythonInitializer.

/**
 * Return a Python expression that can be used to initialize the specified
 * parameter instance. If the parameter initializer refers to other
 * parameters, then those parameter references are replaced with
 * accesses to the Python reactor instance class of the parents of
 * those parameters.
 *
 * @param p The parameter instance to create initializer for
 * @return Initialization code
 */
public static String generatePythonInitializer(ParameterInstance p) {
    // Handle overrides in the instantiation.
    // In case there is more than one assignment to this parameter, we need to
    // find the last one.
    Assignment lastAssignment = getLastAssignment(p);
    List<String> list = new LinkedList<>();
    if (lastAssignment != null) {
        // Right hand side can be a list. Collect the entries.
        for (Value value : lastAssignment.getRhs()) {
            if (value.getParameter() != null) {
                // The parameter is being assigned a parameter value.
                // Assume that parameter belongs to the parent's parent.
                // This should have been checked by the validator.
                list.add(PyUtil.reactorRef(p.getParent().getParent()) + "." + value.getParameter().getName());
            } else {
                list.add(GeneratorBase.getTargetTime(value));
            }
        }
    } else {
        for (Value i : p.getParent().initialParameterValue(p.getDefinition())) {
            list.add(PyUtil.getPythonTargetValue(i));
        }
    }
    return list.size() > 1 ? "(" + String.join(", ", list) + ")" : list.get(0);
}
Also used : Assignment(org.lflang.lf.Assignment) Value(org.lflang.lf.Value) LinkedList(java.util.LinkedList)

Example 5 with Assignment

use of org.lflang.lf.Assignment in project lingua-franca by lf-lang.

the class ValueGenerator method getInitializerList.

/**
 * Create a list of parameter initializers in target code in the context
 * of an reactor instantiation.
 *
 * This respects the parameter assignments given in the reactor
 * instantiation and falls back to the reactors default initializers
 * if no value is assigned to it.
 *
 * @param param The parameter to create initializers for
 * @return A list of initializers in target code
 */
public List<String> getInitializerList(Parameter param, Instantiation i) {
    List<Assignment> assignments = i.getParameters().stream().filter(it -> it.getLhs() == param).collect(Collectors.toList());
    if (// Case 0: The parameter was not overwritten in the instantiation
    assignments.isEmpty())
        return getInitializerList(param);
    // Case 1: The parameter was overwritten in the instantiation
    List<String> list = new ArrayList<>();
    if (assignments.get(0) == null)
        return list;
    for (Value init : assignments.get(0).getRhs()) list.add(getTargetValue(init, ASTUtils.isOfTimeType(param)));
    return list;
}
Also used : Assignment(org.lflang.lf.Assignment) Delay(org.lflang.lf.Delay) Time(org.lflang.lf.Time) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) StateVar(org.lflang.lf.StateVar) Parameter(org.lflang.lf.Parameter) List(java.util.List) Value(org.lflang.lf.Value) Assignment(org.lflang.lf.Assignment) Instantiation(org.lflang.lf.Instantiation) TimeValue(org.lflang.TimeValue) TimeUnit(org.lflang.TimeUnit) ASTUtils(org.lflang.ASTUtils) ArrayList(java.util.ArrayList) Value(org.lflang.lf.Value) TimeValue(org.lflang.TimeValue)

Aggregations

Assignment (org.lflang.lf.Assignment)5 Value (org.lflang.lf.Value)5 Instantiation (org.lflang.lf.Instantiation)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 Delay (org.lflang.lf.Delay)2 List (java.util.List)1 Collectors (java.util.stream.Collectors)1 ASTUtils (org.lflang.ASTUtils)1 TimeUnit (org.lflang.TimeUnit)1 TimeValue (org.lflang.TimeValue)1 Parameter (org.lflang.lf.Parameter)1 StateVar (org.lflang.lf.StateVar)1 Time (org.lflang.lf.Time)1 TypeParm (org.lflang.lf.TypeParm)1 VarRef (org.lflang.lf.VarRef)1 WidthSpec (org.lflang.lf.WidthSpec)1 WidthTerm (org.lflang.lf.WidthTerm)1