Search in sources :

Example 16 with VarRef

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

the class FederateInstance method containsAllVarRefs.

/**
 * Return true if all members of 'varRefs' belong to this federate.
 *
 * As a convenience measure, if some members of 'varRefs' are from
 * different federates, also report an error.
 *
 * @param varRefs A collection of VarRefs
 */
private boolean containsAllVarRefs(Iterable<VarRef> varRefs) {
    var referencesFederate = false;
    var inFederate = true;
    for (VarRef varRef : varRefs) {
        if (varRef.getContainer() == this.instantiation) {
            referencesFederate = true;
        } else {
            if (referencesFederate) {
                errorReporter.reportError(varRef, "Mixed triggers and effects from" + " different federates. This is not permitted");
            }
            inFederate = false;
        }
    }
    return inFederate;
}
Also used : VarRef(org.lflang.lf.VarRef)

Example 17 with VarRef

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

the class CGeneratorExtension method initializeTriggerForControlReactions.

/**
 * Generate C code that initializes three critical structures that support
 * network control reactions:
 *  - triggers_for_network_input_control_reactions: These are triggers that are
 *  used at runtime to insert network input control reactions into the
 *  reaction queue. There could be multiple network input control reactions
 *  for one network input at multiple levels in the hierarchy.
 *  - trigger_for_network_output_control_reactions: Triggers for
 *  network output control reactions, which are unique per each output port.
 *  There could be multiple network output control reactions for each network
 *  output port if it is connected to multiple downstream federates.
 *
 * @param instance  The reactor instance that is at any level of the
 *                  hierarchy within the federate.
 * @param federate  The top-level federate
 * @param generator The instance of the CGenerator passed to keep this
 *                  extension function static.
 * @return A string that initializes the aforementioned three structures.
 */
public static StringBuilder initializeTriggerForControlReactions(ReactorInstance instance, FederateInstance federate, CGenerator generator) {
    StringBuilder builder = new StringBuilder();
    // reactor
    if (instance != generator.main) {
        return builder;
    }
    ReactorDecl reactorClass = instance.getDefinition().getReactorClass();
    Reactor reactor = ASTUtils.toDefinition(reactorClass);
    String nameOfSelfStruct = CUtil.reactorRef(instance);
    // Initialize triggers for network input control reactions
    for (Action trigger : federate.networkInputControlReactionsTriggers) {
        // Check if the trigger belongs to this reactor instance
        if (ASTUtils.allReactions(reactor).stream().anyMatch(r -> {
            return r.getTriggers().stream().anyMatch(t -> {
                if (t instanceof VarRef) {
                    return ((VarRef) t).getVariable().equals(trigger);
                } else {
                    return false;
                }
            });
        })) {
            // Initialize the triggers_for_network_input_control_reactions for the input
            builder.append("// Add trigger " + nameOfSelfStruct + "->_lf__" + trigger.getName() + " to the global list of network input ports.\n" + "_fed.triggers_for_network_input_control_reactions[" + federate.networkInputControlReactionsTriggers.indexOf(trigger) + "]= &" + nameOfSelfStruct + "" + "->_lf__" + trigger.getName() + ";\n");
        }
    }
    nameOfSelfStruct = CUtil.reactorRef(instance);
    // Initialize the trigger for network output control reactions if it doesn't exist.
    if (federate.networkOutputControlReactionsTrigger != null) {
        builder.append("_fed.trigger_for_network_output_control_reactions=&" + nameOfSelfStruct + "->_lf__outputControlReactionTrigger;\n");
    }
    return builder;
}
Also used : VarRef(org.lflang.lf.VarRef) Action(org.lflang.lf.Action) ReactorDecl(org.lflang.lf.ReactorDecl) Reactor(org.lflang.lf.Reactor)

Example 18 with VarRef

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

the class LFValidator method checkConnection.

@Check(CheckType.FAST)
public void checkConnection(Connection connection) {
    // Report if connection is part of a cycle.
    Set<NamedInstance<?>> cycles = this.info.topologyCycles();
    for (VarRef lp : connection.getLeftPorts()) {
        for (VarRef rp : connection.getRightPorts()) {
            boolean leftInCycle = false;
            for (NamedInstance<?> it : cycles) {
                if ((lp.getContainer() == null && it.getDefinition().equals(lp.getVariable())) || (it.getDefinition().equals(lp.getVariable()) && it.getParent().equals(lp.getContainer()))) {
                    leftInCycle = true;
                    break;
                }
            }
            for (NamedInstance<?> it : cycles) {
                if ((rp.getContainer() == null && it.getDefinition().equals(rp.getVariable())) || (it.getDefinition().equals(rp.getVariable()) && it.getParent().equals(rp.getContainer()))) {
                    if (leftInCycle) {
                        Reactor reactor = ASTUtils.getEnclosingReactor(connection);
                        String reactorName = reactor.getName();
                        error(String.format("Connection in reactor %s creates", reactorName) + String.format("a cyclic dependency between %s and %s.", toText(lp), toText(rp)), Literals.CONNECTION__DELAY);
                    }
                }
            }
        }
    }
    // we leave type compatibility that language's compiler or interpreter.
    if (isCBasedTarget()) {
        Type type = (Type) null;
        for (VarRef port : connection.getLeftPorts()) {
            // error. Avoid a class cast exception.
            if (port.getVariable() instanceof Port) {
                if (type == null) {
                    type = ((Port) port.getVariable()).getType();
                } else {
                    // method for AST types, so we have to manually check the types.
                    if (!sameType(type, ((Port) port.getVariable()).getType())) {
                        error("Types do not match.", Literals.CONNECTION__LEFT_PORTS);
                    }
                }
            }
        }
        for (VarRef port : connection.getRightPorts()) {
            // error. Avoid a class cast exception.
            if (port.getVariable() instanceof Port) {
                if (type == null) {
                    type = ((Port) port.getVariable()).getType();
                } else {
                    if (!sameType(type, type = ((Port) port.getVariable()).getType())) {
                        error("Types do not match.", Literals.CONNECTION__RIGHT_PORTS);
                    }
                }
            }
        }
    }
    // Check whether the total width of the left side of the connection
    // matches the total width of the right side. This cannot be determined
    // here if the width is not given as a constant. In that case, it is up
    // to the code generator to check it.
    int leftWidth = 0;
    for (VarRef port : connection.getLeftPorts()) {
        // null args imply incomplete check.
        int width = inferPortWidth(port, null, null);
        if (width < 0 || leftWidth < 0) {
            // Cannot determine the width of the left ports.
            leftWidth = -1;
        } else {
            leftWidth += width;
        }
    }
    int rightWidth = 0;
    for (VarRef port : connection.getRightPorts()) {
        // null args imply incomplete check.
        int width = inferPortWidth(port, null, null);
        if (width < 0 || rightWidth < 0) {
            // Cannot determine the width of the left ports.
            rightWidth = -1;
        } else {
            rightWidth += width;
        }
    }
    if (leftWidth != -1 && rightWidth != -1 && leftWidth != rightWidth) {
        if (connection.isIterated()) {
            if (leftWidth == 0 || rightWidth % leftWidth != 0) {
                // FIXME: The second argument should be Literals.CONNECTION, but
                // stupidly, xtext will not accept that. There seems to be no way to
                // report an error for the whole connection statement.
                warning(String.format("Left width %s does not divide right width %s", leftWidth, rightWidth), Literals.CONNECTION__LEFT_PORTS);
            }
        } else {
            // FIXME: The second argument should be Literals.CONNECTION, but
            // stupidly, xtext will not accept that. There seems to be no way to
            // report an error for the whole connection statement.
            warning(String.format("Left width %s does not match right width %s", leftWidth, rightWidth), Literals.CONNECTION__LEFT_PORTS);
        }
    }
    Reactor reactor = ASTUtils.getEnclosingReactor(connection);
    // Make sure the right port is not already an effect of a reaction.
    for (Reaction reaction : ASTUtils.allReactions(reactor)) {
        for (VarRef effect : reaction.getEffects()) {
            for (VarRef rightPort : connection.getRightPorts()) {
                if (// Refers to the same variable
                rightPort.getVariable().equals(effect.getVariable()) && // Refers to the same instance
                rightPort.getContainer() == effect.getContainer() && (// Either is not part of a mode
                reaction.eContainer() instanceof Reactor || connection.eContainer() instanceof Reactor || // Or they are in the same mode
                connection.eContainer() == reaction.eContainer())) {
                    error("Cannot connect: Port named '" + effect.getVariable().getName() + "' is already effect of a reaction.", Literals.CONNECTION__RIGHT_PORTS);
                }
            }
        }
    }
    // upstream connection.
    for (Connection c : reactor.getConnections()) {
        if (c != connection) {
            for (VarRef thisRightPort : connection.getRightPorts()) {
                for (VarRef thatRightPort : c.getRightPorts()) {
                    if (// Refers to the same variable
                    thisRightPort.getVariable().equals(thatRightPort.getVariable()) && // Refers to the same instance
                    thisRightPort.getContainer() == thatRightPort.getContainer() && (// Or either of the connections in not part of a mode
                    connection.eContainer() instanceof Reactor || c.eContainer() instanceof Reactor || // Or they are in the same mode
                    connection.eContainer() == c.eContainer())) {
                        error("Cannot connect: Port named '" + thisRightPort.getVariable().getName() + "' may only appear once on the right side of a connection.", Literals.CONNECTION__RIGHT_PORTS);
                    }
                }
            }
        }
    }
}
Also used : VarRef(org.lflang.lf.VarRef) ASTUtils.isOfTimeType(org.lflang.ASTUtils.isOfTimeType) CheckType(org.eclipse.xtext.validation.CheckType) ModeTransitionType(org.lflang.generator.ModeInstance.ModeTransitionType) Type(org.lflang.lf.Type) Port(org.lflang.lf.Port) Connection(org.lflang.lf.Connection) ImportedReactor(org.lflang.lf.ImportedReactor) Reactor(org.lflang.lf.Reactor) Reaction(org.lflang.lf.Reaction) NamedInstance(org.lflang.generator.NamedInstance) Check(org.eclipse.xtext.validation.Check)

Example 19 with VarRef

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

the class LFValidator method checkReaction.

@Check(CheckType.FAST)
public void checkReaction(Reaction reaction) {
    if (reaction.getTriggers() == null || reaction.getTriggers().size() == 0) {
        warning("Reaction has no trigger.", Literals.REACTION__TRIGGERS);
    }
    HashSet<Variable> triggers = new HashSet<>();
    // Make sure input triggers have no container and output sources do.
    for (TriggerRef trigger : reaction.getTriggers()) {
        if (trigger instanceof VarRef) {
            VarRef triggerVarRef = (VarRef) trigger;
            triggers.add(triggerVarRef.getVariable());
            if (triggerVarRef instanceof Input) {
                if (triggerVarRef.getContainer() != null) {
                    error(String.format("Cannot have an input of a contained reactor as a trigger: %s.%s", triggerVarRef.getContainer().getName(), triggerVarRef.getVariable().getName()), Literals.REACTION__TRIGGERS);
                }
            } else if (triggerVarRef.getVariable() instanceof Output) {
                if (triggerVarRef.getContainer() == null) {
                    error(String.format("Cannot have an output of this reactor as a trigger: %s", triggerVarRef.getVariable().getName()), Literals.REACTION__TRIGGERS);
                }
            }
        }
    }
    // Also check that a source is not already listed as a trigger.
    for (VarRef source : reaction.getSources()) {
        if (triggers.contains(source.getVariable())) {
            error(String.format("Source is already listed as a trigger: %s", source.getVariable().getName()), Literals.REACTION__SOURCES);
        }
        if (source.getVariable() instanceof Input) {
            if (source.getContainer() != null) {
                error(String.format("Cannot have an input of a contained reactor as a source: %s.%s", source.getContainer().getName(), source.getVariable().getName()), Literals.REACTION__SOURCES);
            }
        } else if (source.getVariable() instanceof Output) {
            if (source.getContainer() == null) {
                error(String.format("Cannot have an output of this reactor as a source: %s", source.getVariable().getName()), Literals.REACTION__SOURCES);
            }
        }
    }
    // Make sure output effects have no container and input effects do.
    for (VarRef effect : reaction.getEffects()) {
        if (effect.getVariable() instanceof Input) {
            if (effect.getContainer() == null) {
                error(String.format("Cannot have an input of this reactor as an effect: %s", effect.getVariable().getName()), Literals.REACTION__EFFECTS);
            }
        } else if (effect.getVariable() instanceof Output) {
            if (effect.getContainer() != null) {
                error(String.format("Cannot have an output of a contained reactor as an effect: %s.%s", effect.getContainer().getName(), effect.getVariable().getName()), Literals.REACTION__EFFECTS);
            }
        }
    }
    // // Report error if this reaction is part of a cycle.
    Set<NamedInstance<?>> cycles = this.info.topologyCycles();
    Reactor reactor = ASTUtils.getEnclosingReactor(reaction);
    boolean reactionInCycle = false;
    for (NamedInstance<?> it : cycles) {
        if (it.getDefinition().equals(reaction)) {
            reactionInCycle = true;
        }
    }
    if (reactionInCycle) {
        // Report involved triggers.
        List<CharSequence> trigs = new ArrayList<>();
        for (TriggerRef t : reaction.getTriggers()) {
            if (!(t instanceof VarRef)) {
                continue;
            }
            VarRef tVarRef = (VarRef) t;
            boolean triggerExistsInCycle = false;
            for (NamedInstance<?> c : cycles) {
                if (c.getDefinition().equals(tVarRef.getVariable())) {
                    triggerExistsInCycle = true;
                    break;
                }
            }
            if (triggerExistsInCycle) {
                trigs.add(toText(tVarRef));
            }
        }
        if (trigs.size() > 0) {
            error(String.format("Reaction triggers involved in cyclic dependency in reactor %s: %s.", reactor.getName(), String.join(", ", trigs)), Literals.REACTION__TRIGGERS);
        }
        // Report involved sources.
        List<CharSequence> sources = new ArrayList<>();
        for (VarRef t : reaction.getSources()) {
            boolean sourceExistInCycle = false;
            for (NamedInstance<?> c : cycles) {
                if (c.getDefinition().equals(t.getVariable())) {
                    sourceExistInCycle = true;
                    break;
                }
            }
            if (sourceExistInCycle) {
                sources.add(toText(t));
            }
        }
        if (sources.size() > 0) {
            error(String.format("Reaction sources involved in cyclic dependency in reactor %s: %s.", reactor.getName(), String.join(", ", sources)), Literals.REACTION__SOURCES);
        }
        // Report involved effects.
        List<CharSequence> effects = new ArrayList<>();
        for (VarRef t : reaction.getEffects()) {
            boolean effectExistInCycle = false;
            for (NamedInstance<?> c : cycles) {
                if (c.getDefinition().equals(t.getVariable())) {
                    effectExistInCycle = true;
                    break;
                }
            }
            if (effectExistInCycle) {
                effects.add(toText(t));
            }
        }
        if (effects.size() > 0) {
            error(String.format("Reaction effects involved in cyclic dependency in reactor %s: %s.", reactor.getName(), String.join(", ", effects)), Literals.REACTION__EFFECTS);
        }
        if (trigs.size() + sources.size() == 0) {
            error(String.format("Cyclic dependency due to preceding reaction. Consider reordering reactions within reactor %s to avoid causality loop.", reactor.getName()), reaction.eContainer(), Literals.REACTOR__REACTIONS, reactor.getReactions().indexOf(reaction));
        } else if (effects.size() == 0) {
            error(String.format("Cyclic dependency due to succeeding reaction. Consider reordering reactions within reactor %s to avoid causality loop.", reactor.getName()), reaction.eContainer(), Literals.REACTOR__REACTIONS, reactor.getReactions().indexOf(reaction));
        }
    // Not reporting reactions that are part of cycle _only_ due to reaction ordering.
    // Moving them won't help solve the problem.
    }
// FIXME: improve error message.
}
Also used : VarRef(org.lflang.lf.VarRef) TypedVariable(org.lflang.lf.TypedVariable) Variable(org.lflang.lf.Variable) ArrayList(java.util.ArrayList) TriggerRef(org.lflang.lf.TriggerRef) NamedInstance(org.lflang.generator.NamedInstance) Input(org.lflang.lf.Input) Output(org.lflang.lf.Output) ImportedReactor(org.lflang.lf.ImportedReactor) Reactor(org.lflang.lf.Reactor) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Check(org.eclipse.xtext.validation.Check)

Example 20 with VarRef

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

the class CReactionGenerator method generateIntendedTagInheritence.

/**
 * Generate code that passes existing intended tag to all output ports
 * and actions. This intended tag is the minimum intended tag of the
 * triggering inputs of the reaction.
 *
 * @param body The body of the reaction. Used to check for the DISABLE_REACTION_INITIALIZATION_MARKER.
 * @param reaction The initialization code will be generated for this specific reaction
 * @param decl The reactor that has the reaction
 * @param reactionIndex The index of the reaction relative to other reactions in the reactor, starting from 0
 */
public static String generateIntendedTagInheritence(String body, Reaction reaction, ReactorDecl decl, int reactionIndex, CTypes types, boolean isFederatedAndDecentralized) {
    // Construct the intended_tag inheritance code to go into
    // the body of the function.
    CodeBuilder intendedTagInheritenceCode = new CodeBuilder();
    // Check if the coordination mode is decentralized and if the reaction has any effects to inherit the STP violation
    if (isFederatedAndDecentralized && !(reaction.getEffects() == null || reaction.getEffects().isEmpty())) {
        intendedTagInheritenceCode.pr(String.join("\n", "#pragma GCC diagnostic push", "#pragma GCC diagnostic ignored \"-Wunused-variable\"", "if (self->_lf__reaction_" + reactionIndex + ".is_STP_violated == true) {"));
        intendedTagInheritenceCode.indent();
        intendedTagInheritenceCode.pr(String.join("\n", "// The operations inside this if clause (if any exists) are expensive ", "// and must only be done if the reaction has unhandled STP violation.", "// Otherwise, all intended_tag values are (NEVER, 0) by default.", "", "// Inherited intended tag. This will take the minimum", "// intended_tag of all input triggers", types.getTargetTagType() + " inherited_min_intended_tag = (" + types.getTargetTagType() + ") { .time = FOREVER, .microstep = UINT_MAX };"));
        intendedTagInheritenceCode.pr("// Find the minimum intended tag");
        // value of intended_tag to choose the minimum.
        for (TriggerRef inputTrigger : ASTUtils.convertToEmptyListIfNull(reaction.getTriggers())) {
            if (inputTrigger instanceof VarRef) {
                VarRef inputTriggerAsVarRef = (VarRef) inputTrigger;
                Variable variable = inputTriggerAsVarRef.getVariable();
                String variableName = inputTriggerAsVarRef.getVariable().getName();
                if (variable instanceof Output) {
                    // Output from a contained reactor
                    String containerName = inputTriggerAsVarRef.getContainer().getName();
                    Output outputPort = (Output) variable;
                    if (ASTUtils.isMultiport(outputPort)) {
                        intendedTagInheritenceCode.pr(String.join("\n", "for (int i=0; i < " + containerName + "." + generateWidthVariable(variableName) + "; i++) {", "    if (compare_tags(" + containerName + "." + variableName + "[i]->intended_tag,", "                        inherited_min_intended_tag) < 0) {", "        inherited_min_intended_tag = " + containerName + "." + variableName + "[i]->intended_tag;", "    }", "}"));
                    } else
                        intendedTagInheritenceCode.pr(String.join("\n", "if (compare_tags(" + containerName + "." + variableName + "->intended_tag,", "                    inherited_min_intended_tag) < 0) {", "    inherited_min_intended_tag = " + containerName + "." + variableName + "->intended_tag;", "}"));
                } else if (variable instanceof Port) {
                    // Input port
                    Port inputPort = (Port) variable;
                    if (ASTUtils.isMultiport(inputPort)) {
                        intendedTagInheritenceCode.pr(String.join("\n", "for (int i=0; i < " + generateWidthVariable(variableName) + "; i++) {", "    if (compare_tags(" + variableName + "[i]->intended_tag, inherited_min_intended_tag) < 0) {", "        inherited_min_intended_tag = " + variableName + "[i]->intended_tag;", "    }", "}"));
                    } else {
                        intendedTagInheritenceCode.pr(String.join("\n", "if (compare_tags(" + variableName + "->intended_tag, inherited_min_intended_tag) < 0) {", "    inherited_min_intended_tag = " + variableName + "->intended_tag;", "}"));
                    }
                } else if (variable instanceof Action) {
                    intendedTagInheritenceCode.pr(String.join("\n", "if (compare_tags(" + variableName + "->trigger->intended_tag, inherited_min_intended_tag) < 0) {", "    inherited_min_intended_tag = " + variableName + "->trigger->intended_tag;", "}"));
                }
            }
        }
        if (reaction.getTriggers() == null || reaction.getTriggers().size() == 0) {
            // NOTE: this does not include contained outputs.
            for (Input input : ((Reactor) reaction.eContainer()).getInputs()) {
                intendedTagInheritenceCode.pr(String.join("\n", "if (compare_tags(" + input.getName() + "->intended_tag, inherited_min_intended_tag) > 0) {", "    inherited_min_intended_tag = " + input.getName() + "->intended_tag;", "}"));
            }
        }
        // Once the minimum intended tag has been found,
        // it will be passed down to the port effects
        // of the reaction. Note that the intended tag
        // will not pass on to actions downstream.
        // Last reaction that sets the intended tag for the effect
        // will be seen.
        intendedTagInheritenceCode.pr(String.join("\n", "// All effects inherit the minimum intended tag of input triggers", "if (inherited_min_intended_tag.time != NEVER) {"));
        intendedTagInheritenceCode.indent();
        for (VarRef effect : ASTUtils.convertToEmptyListIfNull(reaction.getEffects())) {
            Variable effectVar = effect.getVariable();
            Instantiation effContainer = effect.getContainer();
            if (effectVar instanceof Input) {
                if (ASTUtils.isMultiport((Port) effectVar)) {
                    intendedTagInheritenceCode.pr(String.join("\n", "for(int i=0; i < " + effContainer.getName() + "." + generateWidthVariable(effectVar.getName()) + "; i++) {", "    " + effContainer.getName() + "." + effectVar.getName() + "[i]->intended_tag = inherited_min_intended_tag;", "}"));
                } else {
                    if (effContainer.getWidthSpec() != null) {
                        // Contained reactor is a bank.
                        intendedTagInheritenceCode.pr(String.join("\n", "for (int bankIndex = 0; bankIndex < self->_lf_" + generateWidthVariable(effContainer.getName()) + "; bankIndex++) {", "    " + effContainer.getName() + "[bankIndex]." + effectVar.getName() + " = &(self->_lf_" + effContainer.getName() + "[bankIndex]." + effectVar.getName() + ");", "}"));
                    } else {
                        // Input to a contained reaction
                        intendedTagInheritenceCode.pr(String.join("\n", "// Don't reset the intended tag of the output port if it has already been set.", effContainer.getName() + "." + effectVar.getName() + "->intended_tag = inherited_min_intended_tag;"));
                    }
                }
            }
        }
        intendedTagInheritenceCode.unindent();
        intendedTagInheritenceCode.pr("}");
        intendedTagInheritenceCode.unindent();
        intendedTagInheritenceCode.pr("#pragma GCC diagnostic pop");
        intendedTagInheritenceCode.pr("}");
    }
    return intendedTagInheritenceCode.toString();
}
Also used : VarRef(org.lflang.lf.VarRef) Action(org.lflang.lf.Action) Input(org.lflang.lf.Input) Variable(org.lflang.lf.Variable) CUtil.generateWidthVariable(org.lflang.generator.c.CUtil.generateWidthVariable) Output(org.lflang.lf.Output) Port(org.lflang.lf.Port) TriggerRef(org.lflang.lf.TriggerRef) Reactor(org.lflang.lf.Reactor) Instantiation(org.lflang.lf.Instantiation) CodeBuilder(org.lflang.generator.CodeBuilder)

Aggregations

VarRef (org.lflang.lf.VarRef)21 Reactor (org.lflang.lf.Reactor)16 Action (org.lflang.lf.Action)10 Instantiation (org.lflang.lf.Instantiation)9 Reaction (org.lflang.lf.Reaction)8 Input (org.lflang.lf.Input)7 Output (org.lflang.lf.Output)7 Port (org.lflang.lf.Port)7 ArrayList (java.util.ArrayList)6 LinkedHashSet (java.util.LinkedHashSet)6 TriggerRef (org.lflang.lf.TriggerRef)6 Variable (org.lflang.lf.Variable)6 Connection (org.lflang.lf.Connection)5 ImportedReactor (org.lflang.lf.ImportedReactor)5 LfFactory (org.lflang.lf.LfFactory)5 TimeValue (org.lflang.TimeValue)4 Delay (org.lflang.lf.Delay)4 LinkedList (java.util.LinkedList)3 List (java.util.List)3 Collectors (java.util.stream.Collectors)3