From 26df5862d8319833c20038d7663b1c4d711faaee Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 14 Feb 2023 15:37:15 -0800 Subject: [PATCH 01/92] Add a minimal test case. --- test/C/c/count.c | 11 +++++++++++ test/C/c/count.cmake | 0 test/C/src/bodyless-reactions/Count.lf | 16 ++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 test/C/c/count.c create mode 100644 test/C/c/count.cmake create mode 100644 test/C/src/bodyless-reactions/Count.lf diff --git a/test/C/c/count.c b/test/C/c/count.c new file mode 100644 index 0000000000..e3970cbf34 --- /dev/null +++ b/test/C/c/count.c @@ -0,0 +1,11 @@ +#include "../include/count.h" +#include "../include/api/api.h" +#include "../include/core/reactor.h" + +void increment(count_self_t* self) { + self->count++; +} + +void done(count_self_t* self) { + if (self->count > 10) lf_request_stop(); +} diff --git a/test/C/c/count.cmake b/test/C/c/count.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/C/src/bodyless-reactions/Count.lf b/test/C/src/bodyless-reactions/Count.lf new file mode 100644 index 0000000000..7e72ddc96c --- /dev/null +++ b/test/C/src/bodyless-reactions/Count.lf @@ -0,0 +1,16 @@ +target C { + cmake-include: [ + "../../c/count.cmake" + ], + files: [ + "../../c/count.c" + ] +} + +reactor Count { + timer t(1 sec) + + reaction add(t) + + reaction done(t) +} From 38343170fa33796a2bff46127f1996ce4e19bc01 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 14 Feb 2023 16:08:00 -0800 Subject: [PATCH 02/92] Add header file. This is to be code generated. --- test/C/c/count.c | 2 -- test/C/include/count.h | 9 +++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 test/C/include/count.h diff --git a/test/C/c/count.c b/test/C/c/count.c index e3970cbf34..d602ab26fd 100644 --- a/test/C/c/count.c +++ b/test/C/c/count.c @@ -1,6 +1,4 @@ #include "../include/count.h" -#include "../include/api/api.h" -#include "../include/core/reactor.h" void increment(count_self_t* self) { self->count++; diff --git a/test/C/include/count.h b/test/C/include/count.h new file mode 100644 index 0000000000..3fca1ad5a9 --- /dev/null +++ b/test/C/include/count.h @@ -0,0 +1,9 @@ +// File generated by LFC + +typedef struct count_self_t { + int count; +} count_self_t; + +void increment(count_self_t* self); + +void done(count_self_t* self); From 2d3d9e0ddcc4d532c9f5ca8b0fa9207f7e38d1fb Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 14 Feb 2023 16:41:16 -0800 Subject: [PATCH 03/92] Start working on code generator (WIP). --- org.lflang/src/org/lflang/LinguaFranca.xtext | 73 +++++++------- .../generator/c/CReactionGenerator.java | 14 ++- .../c/CReactorHeaderFileGenerator.java | 97 +++++++++++++++++++ 3 files changed, 145 insertions(+), 39 deletions(-) create mode 100644 org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index dfa604d7cd..bdf3581602 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -13,22 +13,22 @@ are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************/ -/** +/** * Grammar for Lingua Franca. * A note of caution: extending this grammar with productions that introduce - * new terminals (i.e., anything written between quotes), will require those + * new terminals (i.e., anything written between quotes), will require those * terminals to also be added to the Token production at the bottom of this * file. Failing to do so will cause a parse error whenever a terminal not * listed in the Token production is featured in a segment of target-language @@ -44,7 +44,7 @@ import "http://www.eclipse.org/emf/2002/Ecore" as ecore // Use the package name "lf" for generated files defining the classes // in the metamodel (i.e., the classes representing nodes in the -// abstract syntax tree (AST), i.e., the eCore model). +// abstract syntax tree (AST), i.e., the eCore model). generate lf "https://lf-lang.org" /////////// Overall file @@ -105,7 +105,7 @@ TypeExpr: /** * Specification of the target language. Target properties can be specified in - * YAML format to pass on configuration details to the runtime environment. + * YAML format to pass on configuration details to the runtime environment. */ TargetDecl: 'target' name=ID (config=KeyValuePairs)? ';'?; @@ -114,11 +114,11 @@ TargetDecl: /////////// Statements /** - * Declaration of a state variable. Types are optional, but may be required - * during validation (depending on the target language). Initialization is also + * Declaration of a state variable. Types are optional, but may be required + * during validation (depending on the target language). Initialization is also * optional. A state variable can be initialized by assigning a `Expression` or list * of these. Note that a `Expression` may also be a reference to a parameter. - * The following checks must be carried out during validation: + * The following checks must be carried out during validation: * - if the list of initialization expressions has more than one element in it, a * type must be specified; * - if the `time` type is specified, there can only be a single initialization @@ -180,10 +180,10 @@ Mode: )* '}'; // Action that has either a physical or logical origin. -// +// // If the origin is logical, the minDelay is a minimum logical delay // after the logical time at which schedule() is called that the -// action will occur. If the origin is physical, then the +// action will occur. If the origin is physical, then the // minDelay is a minimum logical delay after the physical time // at which schedule() is called that the action will occur. // @@ -198,10 +198,11 @@ Action: Reaction: (attributes+=Attribute)* (('reaction') | mutation ?= 'mutation') + (name=ID)? ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')')? (sources+=VarRef (',' sources+=VarRef)*)? ('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)? - code=Code + (code=Code)? (stp=STP)? (deadline=Deadline)?; @@ -213,7 +214,7 @@ BuiltinTriggerRef: Deadline: 'deadline' '(' delay=Expression ')' code=Code; - + STP: 'STP' '(' value=Expression ')' code=Code; @@ -223,14 +224,14 @@ Preamble: Instantiation: (attributes+=Attribute)* name=ID '=' 'new' (widthSpec=WidthSpec)? - reactorClass=[ReactorDecl] ('<' typeParms+=TypeParm (',' typeParms+=TypeParm)* '>')? '(' - (parameters+=Assignment (',' parameters+=Assignment)*)? + reactorClass=[ReactorDecl] ('<' typeParms+=TypeParm (',' typeParms+=TypeParm)* '>')? '(' + (parameters+=Assignment (',' parameters+=Assignment)*)? ')' (('at' host=Host ';') | ';'?); Connection: ((leftPorts += VarRef (',' leftPorts += VarRef)*) | ( '(' leftPorts += VarRef (',' leftPorts += VarRef)* ')' iterated ?= '+'?)) - ('->' | physical?='~>') + ('->' | physical?='~>') rightPorts += VarRef (',' rightPorts += VarRef)* ('after' delay=Expression)? (serializer=Serializer)? @@ -264,7 +265,7 @@ Array: // todo allow empty array in grammar, replace with validator error Element: keyvalue=KeyValuePairs | array=Array - | literal=Literal + | literal=Literal | (time=INT unit=TimeUnit) | id=Path; @@ -322,11 +323,11 @@ Time: Port: Input | Output; - + // A type is in the target language, hence either an ID or target code. Type: - time?='time' (arraySpec=ArraySpec)? - | id=DottedName ('<' typeParms+=Type (',' typeParms+=Type)* '>')? (stars+='*')* (arraySpec=ArraySpec)? + time?='time' (arraySpec=ArraySpec)? + | id=DottedName ('<' typeParms+=Type (',' typeParms+=Type)* '>')? (stars+='*')* (arraySpec=ArraySpec)? | code=Code ; @@ -419,24 +420,24 @@ IPV4Addr: ; IPV6Seg: - // NOTE: This rule is too permissive by design. + // NOTE: This rule is too permissive by design. // Further checking is done during validation. (INT | (INT? ID)) ; IPV6Addr: - // NOTE: This rule is too permissive by design. - // Further checking is done during validation. + // NOTE: This rule is too permissive by design. + // Further checking is done during validation. // IPV6 with truncation. - '::' | ('::' (IPV6Seg (':'))* IPV6Seg) | ((IPV6Seg (':'|'::'))+ IPV6Seg?) | - + '::' | ('::' (IPV6Seg (':'))* IPV6Seg) | ((IPV6Seg (':'|'::'))+ IPV6Seg?) | + // (Link-local IPv6 addresses with zone index) "fe80::7:8%1" (ID '::' IPV6Seg (':' IPV6Seg)* '%' (INT | ID)+) | // IPv4-mapped IPv6 addresses and IPv4-translated addresses ('::' IPV4Addr) | ('::' ID ':' (INT ':')? IPV4Addr) | - + // IPv4-Embedded IPv6 Address (((IPV6Seg (':' IPV6Seg)* '::') | (IPV6Seg (':' IPV6Seg)*) ':') IPV4Addr) ; @@ -453,7 +454,7 @@ Code: {Code} '{=' body=Body '=}' ; -FSName: +FSName: (ID | '.' | '_')+ ; // Absolute or relative directory path in Windows, Linux, or MacOS. @@ -492,8 +493,8 @@ Token: // Non-constant terminals ID | INT | FLOAT_EXP_SUFFIX | LT_ANNOT | STRING | CHAR_LIT | ML_COMMENT | SL_COMMENT | WS | ANY_OTHER | // Keywords - 'target' | 'import' | 'main' | 'realtime' | 'reactor' | 'state' | 'time' | - 'mutable' | 'input' | 'output' | 'timer' | 'action' | 'reaction' | + 'target' | 'import' | 'main' | 'realtime' | 'reactor' | 'state' | 'time' | + 'mutable' | 'input' | 'output' | 'timer' | 'action' | 'reaction' | 'startup' | 'shutdown' | 'after' | 'deadline' | 'mutation' | 'preamble' | 'new' | 'federated' | 'at' | 'as' | 'from' | 'widthof' | 'const' | 'method' | 'interleaved' | 'mode' | 'initial' | 'reset' | 'history' | @@ -516,7 +517,7 @@ Token: // Underscore '_' | // Arrow - '->' | + '->' | // Assignment '=' | // Percentage diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index 5b5d26bbf3..d5fba36f22 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -23,6 +23,7 @@ import org.lflang.lf.Code; import org.lflang.lf.Input; import org.lflang.lf.Instantiation; +import org.lflang.lf.LfFactory; import org.lflang.lf.Mode; import org.lflang.lf.ModeTransition; import org.lflang.lf.Output; @@ -1053,12 +1054,12 @@ public static String generateReaction( body, reaction, decl, reactionIndex, types, errorReporter, mainDef, requiresType); - - String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; + + String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; code.pr( "#include " + StringUtil.addDoubleQuotes( srcPrefix + CCoreFilesUtils.getCTargetSetHeader())); - + CMethodGenerator.generateMacrosForMethods(ASTUtils.toDefinition(decl), code); code.pr(generateFunction( generateReactionFunctionHeader(decl, reactionIndex), @@ -1086,6 +1087,13 @@ public static String generateReaction( return code.toString(); } + private static Code getCode(Reaction r) { + if (r.getCode() != null) return r.getCode(); + Code ret = LfFactory.eINSTANCE.createCode(); + ret.setBody(r.getName() + "( self + sizeof(lf_base_t) );"); + return ret; + } + public static String generateFunction(String header, String init, Code code) { var function = new CodeBuilder(); function.pr(header + " {"); diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java new file mode 100644 index 0000000000..1bad737e71 --- /dev/null +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -0,0 +1,97 @@ +package org.lflang.generator.c; + +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.lflang.InferredType; +import org.lflang.generator.CodeBuilder; +import org.lflang.lf.Port; +import org.lflang.lf.Reaction; +import org.lflang.lf.Reactor; +import org.lflang.lf.StateVar; +import org.lflang.lf.TriggerRef; +import org.lflang.lf.TypedVariable; +import org.lflang.lf.VarRef; +import org.lflang.lf.Variable; + +public class CReactorHeaderFileGenerator { + public static String generateHeaderFile(CTypes types, Reactor r) { + CodeBuilder builder = new CodeBuilder(); + appendPoundIncludes(builder); + appendSelfStruct(builder, types, r); + for (Reaction reaction : r.getReactions()) { + appendSignature(builder, types, reaction); + } + return builder.getCode(); + } + private static void appendPoundIncludes(CodeBuilder builder) { + builder.pr(""" + #include "../include/api/api.h" + #include "../include/core/reactor.h" + """); + } + + private static String selfStructName(Reactor r) { + return r.getName() + "_self_t"; + } + + private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { + builder.pr("typedef struct " + selfStructName(r) + "{"); + for (StateVar s : r.getStateVars()) { + builder.pr(types.getTargetType(s.getType()) + " " + s.getName() + ";"); + } + builder.pr("}"); + } + + private static void appendSignature(CodeBuilder builder, CTypes types, Reaction r) { + builder.pr("void " + r.getName() + "(" + reactionParameters(types, r) + ");"); + } + + private static String reactionParameters(CTypes types, Reaction r) { + return inputVarRefStream(r) + .map((varRef) -> (TypedVariable) varRef.getVariable() ) + .map((tv) -> types.getVariableDeclaration(InferredType.fromAST(tv.getType()), tv.getName(), false)) + .collect(Collectors.joining(", ")); + } + + private static Stream inputVarRefStream(Reaction reaction) { + return varRefStream(Stream.concat(reaction.getTriggers().stream(), reaction.getSources().stream())); + } + + private static Stream triggerVarRefStream(Reaction reaction) { + return varRefStream(reaction.getTriggers().stream()); + } + + private static Stream varRefStream(Stream toFilter) { + return toFilter.map(it -> it instanceof VarRef v ? v : null) + .filter(Objects::nonNull); + } + + private static Stream outputVarRefStream(Reaction reaction) { + return reaction.getEffects().stream(); + } + + private static Stream inputVariableStream(Reaction reaction) { + return inputVarRefStream(reaction).map(VarRef::getVariable); + } + + private static String representVarRef(VarRef it, String multiportIndex, String bankIndex) { + String containerRepresentation = it.getContainer() == null ? null : + it.getContainer().getName() + ( + it.getContainer().getWidthSpec() == null ? "" : "[" + bankIndex + "]" + ); + String varRepresentation = it.getVariable().getName() + ( + !(it instanceof Port p) ? "" : p.getWidthSpec() == null ? "" : "[" + multiportIndex + "]" + ); + return (containerRepresentation == null ? "" : containerRepresentation + ".") + varRepresentation; + } + + private static String cVariableOfVarRef(VarRef it) { + return it.getContainer() != null ? it.getContainer().getName() : it.getVariable().getName(); + } + + private static Stream varRefStream(Reaction reaction) { + return Stream.concat(inputVarRefStream(reaction), outputVarRefStream(reaction)); + } +} From 74ce30e55df7a1788fc1b75d6c77b780dc6a8a2f Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 14 Feb 2023 21:40:09 -0800 Subject: [PATCH 04/92] Get a basic smoke test to work. --- .../org/lflang/generator/c/CFileConfig.java | 11 +++--- .../org/lflang/generator/c/CGenerator.java | 25 ++++++++++--- .../generator/c/CReactionGenerator.java | 8 ++--- .../c/CReactorHeaderFileGenerator.java | 35 ++++++++++++------- test/C/.gitignore | 1 + test/C/c/count.c | 14 +++++--- test/C/c/count.cmake | 1 + test/C/include/count.h | 9 ----- test/C/src/bodyless-reactions/Count.lf | 16 ++++++--- 9 files changed, 77 insertions(+), 43 deletions(-) create mode 100644 test/C/.gitignore delete mode 100644 test/C/include/count.h diff --git a/org.lflang/src/org/lflang/generator/c/CFileConfig.java b/org.lflang/src/org/lflang/generator/c/CFileConfig.java index 8bd70b74c3..37826d585f 100644 --- a/org.lflang/src/org/lflang/generator/c/CFileConfig.java +++ b/org.lflang/src/org/lflang/generator/c/CFileConfig.java @@ -11,9 +11,12 @@ public class CFileConfig extends FileConfig { public CFileConfig(Resource resource, Path srcGenBasePath, boolean useHierarchicalBin) throws IOException { super(resource, srcGenBasePath, useHierarchicalBin); } -} - - - + public Path getIncludePath() { + return getOutPath().resolve("include"); + } + public String getRuntimeIncludePath() { + return "/lib/c/reactor-c/include"; + } +} diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index faa6e5fb0c..c62e57930c 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -458,6 +458,7 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { FileUtil.createDirectoryIfDoesNotExist(fileConfig.getSrcGenPath().toFile()); FileUtil.createDirectoryIfDoesNotExist(fileConfig.binPath.toFile()); + FileUtil.createDirectoryIfDoesNotExist(fileConfig.getIncludePath().toFile()); handleProtoFiles(); var lfModuleName = fileConfig.name; @@ -500,6 +501,8 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { ); } + generateHeaders(); + // Write the generated code code.writeToFile(targetFile); } catch (IOException e) { @@ -940,6 +943,18 @@ private void generateReactorDefinitions() { } } + private void generateHeaders() throws IOException { + FileUtil.copyDirectoryFromClassPath( + fileConfig.getRuntimeIncludePath(), + fileConfig.getIncludePath(), + false + ); + for (Reactor r : reactors) { + CReactorHeaderFileGenerator.doGenerate(types, r, fileConfig); + } + FileUtil.copyDirectory(fileConfig.getIncludePath(), fileConfig.getSrcGenPath().resolve("include"), false); + } + /** * Generate code for the children of 'reactor' that belong to 'federate'. * Duplicates are avoided. @@ -991,11 +1006,6 @@ protected void copyTargetFiles() throws IOException { String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; - FileUtil.copyDirectoryFromClassPath( - "/lib/c/reactor-c/include", - fileConfig.getSrcGenPath().resolve(srcPrefix + "include"), - false - ); FileUtil.copyDirectoryFromClassPath( "/lib/c/reactor-c/lib", fileConfig.getSrcGenPath().resolve(srcPrefix + "lib"), @@ -1039,6 +1049,7 @@ private void generateReactorClass(ReactorDecl reactor) { // Some of the following methods create lines of code that need to // go into the constructor. Collect those lines of code here: var constructorCode = new CodeBuilder(); + generateIncludes(reactor); generateAuxiliaryStructs(reactor); generateSelfStruct(reactor, constructorCode); generateMethods(reactor); @@ -1084,6 +1095,10 @@ protected void generateConstructor( )); } + protected void generateIncludes(ReactorDecl decl) { + code.pr("#include \"" + decl.getName() + ".h\""); + } + /** * Generate the struct type definitions for inputs, outputs, and * actions of the specified reactor. diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index d5fba36f22..0bf1f9c952 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -1049,7 +1049,7 @@ public static String generateReaction( boolean requiresType ) { var code = new CodeBuilder(); - var body = ASTUtils.toText(reaction.getCode()); + var body = ASTUtils.toText(getCode(reaction, decl)); String init = generateInitializationForReaction( body, reaction, decl, reactionIndex, types, errorReporter, mainDef, @@ -1063,7 +1063,7 @@ public static String generateReaction( CMethodGenerator.generateMacrosForMethods(ASTUtils.toDefinition(decl), code); code.pr(generateFunction( generateReactionFunctionHeader(decl, reactionIndex), - init, reaction.getCode() + init, getCode(reaction, decl) )); // Now generate code for the late function, if there is one // Note that this function can only be defined on reactions @@ -1087,10 +1087,10 @@ public static String generateReaction( return code.toString(); } - private static Code getCode(Reaction r) { + private static Code getCode(Reaction r, ReactorDecl container) { if (r.getCode() != null) return r.getCode(); Code ret = LfFactory.eINSTANCE.createCode(); - ret.setBody(r.getName() + "( self + sizeof(lf_base_t) );"); + ret.setBody(r.getName() + "( (" + CReactorHeaderFileGenerator.selfStructName(container.getName()) + "*) (((char*) self) + sizeof(self_base_t)) );"); return ret; } diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 1bad737e71..3b37aad1c0 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -1,5 +1,6 @@ package org.lflang.generator.c; +import java.io.IOException; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -14,14 +15,20 @@ import org.lflang.lf.TypedVariable; import org.lflang.lf.VarRef; import org.lflang.lf.Variable; +import org.lflang.util.FileUtil; public class CReactorHeaderFileGenerator { - public static String generateHeaderFile(CTypes types, Reactor r) { + + public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig) throws IOException { + String contents = generateHeaderFile(types, r); + FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(r.getName() + ".h")); + } + private static String generateHeaderFile(CTypes types, Reactor r) { CodeBuilder builder = new CodeBuilder(); appendPoundIncludes(builder); appendSelfStruct(builder, types, r); for (Reaction reaction : r.getReactions()) { - appendSignature(builder, types, reaction); + appendSignature(builder, types, reaction, r); } return builder.getCode(); } @@ -32,29 +39,33 @@ private static void appendPoundIncludes(CodeBuilder builder) { """); } - private static String selfStructName(Reactor r) { - return r.getName() + "_self_t"; + public static String selfStructName(String name) { + return name + "_self_t"; } private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { - builder.pr("typedef struct " + selfStructName(r) + "{"); + builder.pr("typedef struct " + selfStructName(r.getName()) + "{"); for (StateVar s : r.getStateVars()) { builder.pr(types.getTargetType(s.getType()) + " " + s.getName() + ";"); } - builder.pr("}"); + builder.pr("} " + selfStructName(r.getName()) + ";"); } - private static void appendSignature(CodeBuilder builder, CTypes types, Reaction r) { - builder.pr("void " + r.getName() + "(" + reactionParameters(types, r) + ");"); + private static void appendSignature(CodeBuilder builder, CTypes types, Reaction r, Reactor reactor) { + builder.pr("void " + r.getName() + "(" + reactionParameters(types, r, reactor) + ");"); } - private static String reactionParameters(CTypes types, Reaction r) { - return inputVarRefStream(r) - .map((varRef) -> (TypedVariable) varRef.getVariable() ) - .map((tv) -> types.getVariableDeclaration(InferredType.fromAST(tv.getType()), tv.getName(), false)) + private static String reactionParameters(CTypes types, Reaction r, Reactor reactor) { + return Stream.concat(Stream.of(selfStructName(reactor.getName()) + "* self"), inputTypedVariableStream(r) + .map((tv) -> types.getVariableDeclaration(InferredType.fromAST(tv.getType()), tv.getName(), false))) .collect(Collectors.joining(", ")); } + private static Stream inputTypedVariableStream(Reaction r) { + return inputVarRefStream(r).map(it -> it.getVariable() instanceof TypedVariable tv ? tv : null) + .filter(Objects::nonNull); + } + private static Stream inputVarRefStream(Reaction reaction) { return varRefStream(Stream.concat(reaction.getTriggers().stream(), reaction.getSources().stream())); } diff --git a/test/C/.gitignore b/test/C/.gitignore new file mode 100644 index 0000000000..08f514ebc5 --- /dev/null +++ b/test/C/.gitignore @@ -0,0 +1 @@ +include/ diff --git a/test/C/c/count.c b/test/C/c/count.c index d602ab26fd..f0cee87e27 100644 --- a/test/C/c/count.c +++ b/test/C/c/count.c @@ -1,9 +1,15 @@ -#include "../include/count.h" +#include +#include "../include/Count.h" -void increment(count_self_t* self) { +void increment(Count_self_t* self) { + printf("in increment, count=%d\n", self->count); self->count++; } -void done(count_self_t* self) { - if (self->count > 10) lf_request_stop(); +void check_done(Count_self_t* self) { + printf("in done, count=%d\n", self->count); + if (self->count > 10) { + printf("%s", "requesting stop\n"); + lf_request_stop(); + } } diff --git a/test/C/c/count.cmake b/test/C/c/count.cmake index e69de29bb2..a9b364a871 100644 --- a/test/C/c/count.cmake +++ b/test/C/c/count.cmake @@ -0,0 +1 @@ +target_sources(${LF_MAIN_TARGET} PRIVATE c/count.c) diff --git a/test/C/include/count.h b/test/C/include/count.h deleted file mode 100644 index 3fca1ad5a9..0000000000 --- a/test/C/include/count.h +++ /dev/null @@ -1,9 +0,0 @@ -// File generated by LFC - -typedef struct count_self_t { - int count; -} count_self_t; - -void increment(count_self_t* self); - -void done(count_self_t* self); diff --git a/test/C/src/bodyless-reactions/Count.lf b/test/C/src/bodyless-reactions/Count.lf index 7e72ddc96c..9df8010043 100644 --- a/test/C/src/bodyless-reactions/Count.lf +++ b/test/C/src/bodyless-reactions/Count.lf @@ -3,14 +3,20 @@ target C { "../../c/count.cmake" ], files: [ - "../../c/count.c" + "../../c" ] } -reactor Count { - timer t(1 sec) +main reactor Count { + timer t(0, 1 msec) - reaction add(t) + state count: int - reaction done(t) + reaction increment(t) + + reaction check_done(t) + + reaction(shutdown) {= + printf("%s", "shutting down\n"); + =} } From f037bcc8962b9d50357308f7cd4551b7c4c4d705 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 14 Feb 2023 23:08:43 -0800 Subject: [PATCH 05/92] Get a test involving inputs/outputs to work. No hierarchical inputs/outputs yet. --- org.lflang/src/org/lflang/ASTUtils.java | 4 ++ .../org/lflang/generator/c/CGenerator.java | 35 +++++------------ .../generator/c/CReactionGenerator.java | 8 ++-- .../c/CReactorHeaderFileGenerator.java | 39 ++++++++++++++----- .../generator/python/PythonGenerator.java | 19 +++++---- test/C/c/sendreceive.c | 15 +++++++ test/C/c/sendreceive.cmake | 1 + test/C/src/bodyless-reactions/IntPrint.lf | 26 +++++++++++++ 8 files changed, 99 insertions(+), 48 deletions(-) create mode 100644 test/C/c/sendreceive.c create mode 100644 test/C/c/sendreceive.cmake create mode 100644 test/C/src/bodyless-reactions/IntPrint.lf diff --git a/org.lflang/src/org/lflang/ASTUtils.java b/org.lflang/src/org/lflang/ASTUtils.java index fe6fdfeb2b..1384b3c852 100644 --- a/org.lflang/src/org/lflang/ASTUtils.java +++ b/org.lflang/src/org/lflang/ASTUtils.java @@ -363,6 +363,10 @@ public static List allInputs(Reactor definition) { return ASTUtils.collectElements(definition, featurePackage.getReactor_Inputs()); } + public static List allPorts(Reactor definition) { + return Stream.concat(ASTUtils.allInputs(definition).stream(), ASTUtils.allOutputs(definition).stream()).toList(); + } + /** * Given a reactor class, return a list of all its instantiations, * which includes instantiations of base classes that it extends. diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index c62e57930c..cbe53af971 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -27,6 +27,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import static org.lflang.ASTUtils.allActions; import static org.lflang.ASTUtils.allInputs; import static org.lflang.ASTUtils.allOutputs; +import static org.lflang.ASTUtils.allPorts; import static org.lflang.ASTUtils.allReactions; import static org.lflang.ASTUtils.allStateVars; import static org.lflang.ASTUtils.convertToEmptyListIfNull; @@ -950,7 +951,7 @@ private void generateHeaders() throws IOException { false ); for (Reactor r : reactors) { - CReactorHeaderFileGenerator.doGenerate(types, r, fileConfig); + CReactorHeaderFileGenerator.doGenerate(types, r, fileConfig, this::generateAuxiliaryStructs); } FileUtil.copyDirectory(fileConfig.getIncludePath(), fileConfig.getSrcGenPath().resolve("include"), false); } @@ -1050,7 +1051,6 @@ private void generateReactorClass(ReactorDecl reactor) { // go into the constructor. Collect those lines of code here: var constructorCode = new CodeBuilder(); generateIncludes(reactor); - generateAuxiliaryStructs(reactor); generateSelfStruct(reactor, constructorCode); generateMethods(reactor); generateReactions(reactor); @@ -1102,10 +1102,8 @@ protected void generateIncludes(ReactorDecl decl) { /** * Generate the struct type definitions for inputs, outputs, and * actions of the specified reactor. - * @param decl The parsed reactor data structure. */ - protected void generateAuxiliaryStructs(ReactorDecl decl) { - var reactor = ASTUtils.toDefinition(decl); + protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r) { // In the case where there are incoming // p2p logical connections in decentralized // federated execution, there will be an @@ -1123,35 +1121,22 @@ protected void generateAuxiliaryStructs(ReactorDecl decl) { #endif """.formatted(types.getTargetTagType(), types.getTargetTimeType()) ); - // First, handle inputs. - for (Input input : allInputs(reactor)) { - code.pr(CPortGenerator.generateAuxiliaryStruct( - decl, - input, - getTarget(), - errorReporter, - types, - federatedExtension - )); - } - // Next, handle outputs. - for (Output output : allOutputs(reactor)) { - code.pr(CPortGenerator.generateAuxiliaryStruct( - decl, - output, + for (Port p : allPorts(r)) { + builder.pr(CPortGenerator.generateAuxiliaryStruct( + r, + p, getTarget(), errorReporter, types, federatedExtension )); } - // Finally, handle actions. // The very first item on this struct needs to be // a trigger_t* because the struct will be cast to (trigger_t*) // by the lf_schedule() functions to get to the trigger. - for (Action action : allActions(reactor)) { - code.pr(CActionGenerator.generateAuxiliaryStruct( - decl, + for (Action action : allActions(r)) { + builder.pr(CActionGenerator.generateAuxiliaryStruct( + r, action, getTarget(), types, diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index 0bf1f9c952..e41589d970 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -1049,7 +1049,7 @@ public static String generateReaction( boolean requiresType ) { var code = new CodeBuilder(); - var body = ASTUtils.toText(getCode(reaction, decl)); + var body = ASTUtils.toText(getCode(types, reaction, decl)); String init = generateInitializationForReaction( body, reaction, decl, reactionIndex, types, errorReporter, mainDef, @@ -1063,7 +1063,7 @@ public static String generateReaction( CMethodGenerator.generateMacrosForMethods(ASTUtils.toDefinition(decl), code); code.pr(generateFunction( generateReactionFunctionHeader(decl, reactionIndex), - init, getCode(reaction, decl) + init, getCode(types, reaction, decl) )); // Now generate code for the late function, if there is one // Note that this function can only be defined on reactions @@ -1087,10 +1087,10 @@ init, getCode(reaction, decl) return code.toString(); } - private static Code getCode(Reaction r, ReactorDecl container) { + private static Code getCode(CTypes types, Reaction r, ReactorDecl container) { if (r.getCode() != null) return r.getCode(); Code ret = LfFactory.eINSTANCE.createCode(); - ret.setBody(r.getName() + "( (" + CReactorHeaderFileGenerator.selfStructName(container.getName()) + "*) (((char*) self) + sizeof(self_base_t)) );"); + ret.setBody(r.getName() + "( " + CReactorHeaderFileGenerator.reactionArguments(types, r, ASTUtils.toDefinition(container)) + " );"); return ret; } diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 3b37aad1c0..1b920ce6a5 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -7,9 +7,11 @@ import org.lflang.InferredType; import org.lflang.generator.CodeBuilder; +import org.lflang.lf.Parameter; import org.lflang.lf.Port; import org.lflang.lf.Reaction; import org.lflang.lf.Reactor; +import org.lflang.lf.ReactorDecl; import org.lflang.lf.StateVar; import org.lflang.lf.TriggerRef; import org.lflang.lf.TypedVariable; @@ -19,14 +21,19 @@ public class CReactorHeaderFileGenerator { - public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig) throws IOException { - String contents = generateHeaderFile(types, r); + public interface GenerateAuxiliaryStructs { + void generate(CodeBuilder b, Reactor r); + } + + public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator) throws IOException { + String contents = generateHeaderFile(types, r, generator); FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(r.getName() + ".h")); } - private static String generateHeaderFile(CTypes types, Reactor r) { + private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator) { CodeBuilder builder = new CodeBuilder(); appendPoundIncludes(builder); appendSelfStruct(builder, types, r); + generator.generate(builder, r); for (Reaction reaction : r.getReactions()) { appendSignature(builder, types, reaction, r); } @@ -34,8 +41,9 @@ private static String generateHeaderFile(CTypes types, Reactor r) { } private static void appendPoundIncludes(CodeBuilder builder) { builder.pr(""" - #include "../include/api/api.h" - #include "../include/core/reactor.h" + #include "../include/api/api.h" + #include "../include/api/set.h" + #include "../include/core/reactor.h" """); } @@ -45,6 +53,9 @@ public static String selfStructName(String name) { private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { builder.pr("typedef struct " + selfStructName(r.getName()) + "{"); + for (Parameter p : r.getParameters()) { + builder.pr(types.getTargetType(p.getType()) + " " + p.getName() + ";"); + } for (StateVar s : r.getStateVars()) { builder.pr(types.getTargetType(s.getType()) + " " + s.getName() + ";"); } @@ -56,13 +67,23 @@ private static void appendSignature(CodeBuilder builder, CTypes types, Reaction } private static String reactionParameters(CTypes types, Reaction r, Reactor reactor) { - return Stream.concat(Stream.of(selfStructName(reactor.getName()) + "* self"), inputTypedVariableStream(r) - .map((tv) -> types.getVariableDeclaration(InferredType.fromAST(tv.getType()), tv.getName(), false))) + return Stream.concat(Stream.of(selfStructName(reactor.getName()) + "* self"), ioTypedVariableStream(r) + .map((tv) -> reactor.getName().toLowerCase() + "_" + tv.getName() + "_t* " + tv.getName())) + .collect(Collectors.joining(", ")); + } + + public static String reactionArguments(CTypes types, Reaction r, Reactor reactor) { + return Stream.concat(Stream.of(getApiSelfStruct(reactor)), ioTypedVariableStream(r) + .map(TypedVariable::getName)) .collect(Collectors.joining(", ")); } - private static Stream inputTypedVariableStream(Reaction r) { - return inputVarRefStream(r).map(it -> it.getVariable() instanceof TypedVariable tv ? tv : null) + private static String getApiSelfStruct(Reactor reactor) { + return "(" + CReactorHeaderFileGenerator.selfStructName(reactor.getName()) + "*) (((char*) self) + sizeof(self_base_t))"; + } + + private static Stream ioTypedVariableStream(Reaction r) { + return varRefStream(r).map(it -> it.getVariable() instanceof TypedVariable tv ? tv : null) .filter(Objects::nonNull); } diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 46bcc4f811..9cd3ca6dda 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -358,24 +358,23 @@ public void processProtoFile(String filename) { */ @Override public void generateAuxiliaryStructs( - ReactorDecl decl + CodeBuilder builder, Reactor r ) { - Reactor reactor = ASTUtils.toDefinition(decl); // First, handle inputs. - for (Input input : ASTUtils.allInputs(reactor)) { - generateAuxiliaryStructsForPort(decl, input); + for (Input input : ASTUtils.allInputs(r)) { + generateAuxiliaryStructsForPort(builder, r, input); } // Next, handle outputs. - for (Output output : ASTUtils.allOutputs(reactor)) { - generateAuxiliaryStructsForPort(decl, output); + for (Output output : ASTUtils.allOutputs(r)) { + generateAuxiliaryStructsForPort(builder, r, output); } // Finally, handle actions. - for (Action action : ASTUtils.allActions(reactor)) { - generateAuxiliaryStructsForAction(decl, action); + for (Action action : ASTUtils.allActions(r)) { + generateAuxiliaryStructsForAction(builder, r, action); } } - private void generateAuxiliaryStructsForPort(ReactorDecl decl, + private void generateAuxiliaryStructsForPort(CodeBuilder builder, ReactorDecl decl, Port port) { boolean isTokenType = CUtil.isTokenType(ASTUtils.getInferredType(port), types); code.pr(port, @@ -383,7 +382,7 @@ private void generateAuxiliaryStructsForPort(ReactorDecl decl, genericPortType)); } - private void generateAuxiliaryStructsForAction(ReactorDecl decl, + private void generateAuxiliaryStructsForAction(CodeBuilder builder, ReactorDecl decl, Action action) { code.pr(action, PythonActionGenerator.generateAliasTypeDef(decl, action, genericActionType)); } diff --git a/test/C/c/sendreceive.c b/test/C/c/sendreceive.c new file mode 100644 index 0000000000..a8455385a0 --- /dev/null +++ b/test/C/c/sendreceive.c @@ -0,0 +1,15 @@ +#include "../include/Print.h" +#include "../include/Check.h" +#include "../include/api/set.h" + +void send(Print_self_t* self, print_out_t* out) { + lf_set(out, 42); +} + +void receive(Check_self_t* self, check_in_t* in) { + printf("Received: %d\n", in->value); + if (in->value != self->expected) { + printf("ERROR: Expected value to be %d.\n", self->expected); + exit(1); + } +} diff --git a/test/C/c/sendreceive.cmake b/test/C/c/sendreceive.cmake new file mode 100644 index 0000000000..acd63f229c --- /dev/null +++ b/test/C/c/sendreceive.cmake @@ -0,0 +1 @@ +target_sources(${LF_MAIN_TARGET} PRIVATE c/sendreceive.c) diff --git a/test/C/src/bodyless-reactions/IntPrint.lf b/test/C/src/bodyless-reactions/IntPrint.lf new file mode 100644 index 0000000000..21f6639346 --- /dev/null +++ b/test/C/src/bodyless-reactions/IntPrint.lf @@ -0,0 +1,26 @@ +target C { + cmake-include: [ + "../../c/sendreceive.cmake" + ], + files: [ + "../../c" + ] +} + +reactor Print { + output out: int + + reaction send(startup) -> out +} + +reactor Check(expected: int(42)) { // expected parameter is for testing. + input in: int + + reaction receive(in) +} + +main reactor { + s = new Print() + p = new Check() + s.out -> p.in +} From 308db3bf52603deaa8960133a4064f1a1042d4ff Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 14 Feb 2023 23:16:08 -0800 Subject: [PATCH 06/92] Adjust self struct names. --- .../org/lflang/generator/c/CReactorHeaderFileGenerator.java | 2 +- org.lflang/src/org/lflang/generator/c/CUtil.java | 4 ++-- test/C/c/count.c | 4 ++-- test/C/c/sendreceive.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 1b920ce6a5..c540733523 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -48,7 +48,7 @@ private static void appendPoundIncludes(CodeBuilder builder) { } public static String selfStructName(String name) { - return name + "_self_t"; + return name.toLowerCase() + "_self_t"; } private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { diff --git a/org.lflang/src/org/lflang/generator/c/CUtil.java b/org.lflang/src/org/lflang/generator/c/CUtil.java index 411a0a464b..dd8411ae2e 100644 --- a/org.lflang/src/org/lflang/generator/c/CUtil.java +++ b/org.lflang/src/org/lflang/generator/c/CUtil.java @@ -516,9 +516,9 @@ public static String runtimeIndex(ReactorInstance reactor) { */ public static String selfType(ReactorDecl reactor) { if (reactor instanceof Reactor r && r.isMain()) { - return reactor.getName().toLowerCase() + "_main_self_t"; + return "_" + reactor.getName().toLowerCase() + "_main_self_t"; } - return reactor.getName().toLowerCase() + "_self_t"; + return "_" + reactor.getName().toLowerCase() + "_self_t"; } /** Construct a unique type for the "self" struct of the class of the given reactor. */ diff --git a/test/C/c/count.c b/test/C/c/count.c index f0cee87e27..80f7a1e2a1 100644 --- a/test/C/c/count.c +++ b/test/C/c/count.c @@ -1,12 +1,12 @@ #include #include "../include/Count.h" -void increment(Count_self_t* self) { +void increment(count_self_t* self) { printf("in increment, count=%d\n", self->count); self->count++; } -void check_done(Count_self_t* self) { +void check_done(count_self_t* self) { printf("in done, count=%d\n", self->count); if (self->count > 10) { printf("%s", "requesting stop\n"); diff --git a/test/C/c/sendreceive.c b/test/C/c/sendreceive.c index a8455385a0..603146d473 100644 --- a/test/C/c/sendreceive.c +++ b/test/C/c/sendreceive.c @@ -2,11 +2,11 @@ #include "../include/Check.h" #include "../include/api/set.h" -void send(Print_self_t* self, print_out_t* out) { +void send(print_self_t* self, print_out_t* out) { lf_set(out, 42); } -void receive(Check_self_t* self, check_in_t* in) { +void receive(check_self_t* self, check_in_t* in) { printf("Received: %d\n", in->value); if (in->value != self->expected) { printf("ERROR: Expected value to be %d.\n", self->expected); From 6d2a177b7ced825005eb372c63da96bb8ba75828 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Wed, 15 Feb 2023 18:36:07 -0800 Subject: [PATCH 07/92] Draft proposal for making the grammar unambiguous --- org.lflang/src/org/lflang/LinguaFranca.xtext | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index bdf3581602..0f5a52abad 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -199,12 +199,13 @@ Reaction: (attributes+=Attribute)* (('reaction') | mutation ?= 'mutation') (name=ID)? - ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')')? + ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')') (sources+=VarRef (',' sources+=VarRef)*)? ('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)? - (code=Code)? - (stp=STP)? - (deadline=Deadline)?; + (((code=Code)(stp=STP)?(deadline=Deadline)?) | + ('{' '}' (stp=STP)?(deadline=Deadline)?) | + ';' + ); TriggerRef: BuiltinTriggerRef | VarRef; From 72ffe96673fac4d9f5960b09a439eb33374ddac9 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Fri, 17 Feb 2023 00:17:00 -0800 Subject: [PATCH 08/92] Alternative proposal without semicolons and optional naming --- org.lflang/src/org/lflang/LinguaFranca.xtext | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index 0f5a52abad..c4fd33f897 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -202,10 +202,8 @@ Reaction: ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')') (sources+=VarRef (',' sources+=VarRef)*)? ('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)? - (((code=Code)(stp=STP)?(deadline=Deadline)?) | - ('{' '}' (stp=STP)?(deadline=Deadline)?) | - ';' - ); + ((code=Code ('named' ID)?) | 'named' ID)(stp=STP)?(deadline=Deadline)? + ; TriggerRef: BuiltinTriggerRef | VarRef; From 7214350a8b74f7a673de7371ea7c1dd70c5df2a0 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Fri, 17 Feb 2023 10:28:43 -0800 Subject: [PATCH 09/92] Swap name and body following suggestion by @cmnrd. --- org.lflang/src/org/lflang/LinguaFranca.xtext | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index c4fd33f897..7a0b8a720c 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -202,7 +202,7 @@ Reaction: ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')') (sources+=VarRef (',' sources+=VarRef)*)? ('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)? - ((code=Code ('named' ID)?) | 'named' ID)(stp=STP)?(deadline=Deadline)? + ((('named' ID)? code=Code) | 'named' ID)(stp=STP)?(deadline=Deadline)? ; TriggerRef: From e8faf9da1da7b9947b8b0594a7aafa17125aac93 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Fri, 17 Feb 2023 15:21:47 -0800 Subject: [PATCH 10/92] Update LinguaFranca.xtext --- org.lflang/src/org/lflang/LinguaFranca.xtext | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index 7a0b8a720c..65e8a327a8 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -496,7 +496,7 @@ Token: 'mutable' | 'input' | 'output' | 'timer' | 'action' | 'reaction' | 'startup' | 'shutdown' | 'after' | 'deadline' | 'mutation' | 'preamble' | 'new' | 'federated' | 'at' | 'as' | 'from' | 'widthof' | 'const' | 'method' | - 'interleaved' | 'mode' | 'initial' | 'reset' | 'history' | + 'interleaved' | 'mode' | 'initial' | 'reset' | 'history' | 'named' | // Other terminals NEGINT | TRUE | FALSE | // Action origins From ff2240ae62d7966216622def3b3720c6fcb55617 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 22 Feb 2023 14:42:32 -0800 Subject: [PATCH 11/92] Minor grammar repair. --- org.lflang/src/org/lflang/LinguaFranca.xtext | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index 65e8a327a8..7600e2e5c6 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -198,11 +198,10 @@ Action: Reaction: (attributes+=Attribute)* (('reaction') | mutation ?= 'mutation') - (name=ID)? ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')') (sources+=VarRef (',' sources+=VarRef)*)? ('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)? - ((('named' ID)? code=Code) | 'named' ID)(stp=STP)?(deadline=Deadline)? + ((('named' name=ID)? code=Code) | 'named' name=ID)(stp=STP)?(deadline=Deadline)? ; TriggerRef: From ec935f201250d10d483bbf4adce5c09f703b005e Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 22 Feb 2023 21:21:24 -0800 Subject: [PATCH 12/92] Minor bugfixes. --- .../lflang/tests/compiler/RoundTripTests.java | 1 + org.lflang/src/org/lflang/LinguaFranca.xtext | 4 ++-- org.lflang/src/org/lflang/ast/IsEqual.java | 1 + org.lflang/src/org/lflang/ast/ToLf.java | 12 ++++++------ .../generator/c/CReactorHeaderFileGenerator.java | 1 + test/C/src/bodyless-reactions/Count.lf | 16 +++++----------- test/C/src/bodyless-reactions/IntPrint.lf | 12 ++++-------- 7 files changed, 20 insertions(+), 27 deletions(-) diff --git a/org.lflang.tests/src/org/lflang/tests/compiler/RoundTripTests.java b/org.lflang.tests/src/org/lflang/tests/compiler/RoundTripTests.java index d1ea81e5be..4007a020ee 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/RoundTripTests.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/RoundTripTests.java @@ -40,6 +40,7 @@ public void roundTripTest() throws Exception { private void run(Path file) throws Exception { Model originalModel = LfParsingUtil.parse(file); + System.out.println(file); assertThat(originalModel.eResource().getErrors(), equalTo(emptyList())); // TODO: Check that the output is a fixed point final int smallLineLength = 20; diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index 7600e2e5c6..817406e4c9 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -276,8 +276,8 @@ Variable: TypedVariable | Timer | Mode; VarRef: - variable=[Variable] | container=[Instantiation] '.' variable=[Variable] - | interleaved?='interleaved' '(' (variable=[Variable] | container=[Instantiation] '.' variable=[Variable]) ')' + (variable=[Variable] | container=[Instantiation] '.' variable=[Variable] + | interleaved?='interleaved' '(' (variable=[Variable] | container=[Instantiation] '.' variable=[Variable]) ')') ('as' (name=ID))? ; VarRefOrModeTransition returns VarRef: VarRef | transition=ModeTransition '(' variable=[Mode] ')'; diff --git a/org.lflang/src/org/lflang/ast/IsEqual.java b/org.lflang/src/org/lflang/ast/IsEqual.java index b4614edcf0..2b61c3eb89 100644 --- a/org.lflang/src/org/lflang/ast/IsEqual.java +++ b/org.lflang/src/org/lflang/ast/IsEqual.java @@ -283,6 +283,7 @@ public Boolean caseReaction(Reaction object) { .listsEquivalent(Reaction::getSources) .listsEquivalent(Reaction::getEffects) .equalAsObjects(Reaction::isMutation) + .equalAsObjects(Reaction::getName) .equivalent(Reaction::getCode) .equivalent(Reaction::getStp) .equivalent(Reaction::getDeadline) diff --git a/org.lflang/src/org/lflang/ast/ToLf.java b/org.lflang/src/org/lflang/ast/ToLf.java index 7582ee3a59..c245c20672 100644 --- a/org.lflang/src/org/lflang/ast/ToLf.java +++ b/org.lflang/src/org/lflang/ast/ToLf.java @@ -592,13 +592,12 @@ public MalleableString caseAction(Action object) { @Override public MalleableString caseReaction(Reaction object) { - // ('reaction') - // ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')')? + // (attributes+=Attribute)* + // (('reaction') | mutation ?= 'mutation') + // ('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')') // (sources+=VarRef (',' sources+=VarRef)*)? // ('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)? - // code=Code - // (stp=STP)? - // (deadline=Deadline)? + // ((('named' name=ID)? code=Code) | 'named' name=ID)(stp=STP)?(deadline=Deadline)? Builder msb = new Builder(); addAttributes(msb, object::getAttributes); if (object.isMutation()) { @@ -627,7 +626,8 @@ public MalleableString caseReaction(Reaction object) { : doSwitch(varRef)) .collect(new Joiner(", "))); } - msb.append(" ").append(doSwitch(object.getCode())); + if (object.getName() != null) msb.append(" named ").append(object.getName()); + if (object.getCode() != null) msb.append(" ").append(doSwitch(object.getCode())); if (object.getStp() != null) msb.append(" ").append(doSwitch(object.getStp())); if (object.getDeadline() != null) msb.append(" ").append(doSwitch(object.getDeadline())); return msb.get(); diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index c540733523..247404ad92 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -59,6 +59,7 @@ private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor for (StateVar s : r.getStateVars()) { builder.pr(types.getTargetType(s.getType()) + " " + s.getName() + ";"); } + builder.pr("int end[0]; // placeholder; MSVC does not compile empty structs"); builder.pr("} " + selfStructName(r.getName()) + ";"); } diff --git a/test/C/src/bodyless-reactions/Count.lf b/test/C/src/bodyless-reactions/Count.lf index 9df8010043..f8fd51bec7 100644 --- a/test/C/src/bodyless-reactions/Count.lf +++ b/test/C/src/bodyless-reactions/Count.lf @@ -1,10 +1,6 @@ target C { - cmake-include: [ - "../../c/count.cmake" - ], - files: [ - "../../c" - ] + cmake-include: ["../../c/count.cmake"], + files: ["../../c"] } main reactor Count { @@ -12,11 +8,9 @@ main reactor Count { state count: int - reaction increment(t) + reaction(t) named increment - reaction check_done(t) + reaction(t) named check_done - reaction(shutdown) {= - printf("%s", "shutting down\n"); - =} + reaction(shutdown) {= printf("%s", "shutting down\n"); =} } diff --git a/test/C/src/bodyless-reactions/IntPrint.lf b/test/C/src/bodyless-reactions/IntPrint.lf index 21f6639346..919b8e9998 100644 --- a/test/C/src/bodyless-reactions/IntPrint.lf +++ b/test/C/src/bodyless-reactions/IntPrint.lf @@ -1,22 +1,18 @@ target C { - cmake-include: [ - "../../c/sendreceive.cmake" - ], - files: [ - "../../c" - ] + cmake-include: ["../../c/sendreceive.cmake"], + files: ["../../c"] } reactor Print { output out: int - reaction send(startup) -> out + reaction(startup) -> out named send } reactor Check(expected: int(42)) { // expected parameter is for testing. input in: int - reaction receive(in) + reaction(in) named receive } main reactor { From 8e29e39f9f6709aeda480b4df71b1a97b9590337 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 22 Feb 2023 21:39:48 -0800 Subject: [PATCH 13/92] Do not generate prototypes for inlined reactions. --- .../src/org/lflang/generator/c/CReactorHeaderFileGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 247404ad92..3a1f187a3d 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -64,7 +64,7 @@ private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor } private static void appendSignature(CodeBuilder builder, CTypes types, Reaction r, Reactor reactor) { - builder.pr("void " + r.getName() + "(" + reactionParameters(types, r, reactor) + ");"); + if (r.getName() != null) builder.pr("void " + r.getName() + "(" + reactionParameters(types, r, reactor) + ");"); } private static String reactionParameters(CTypes types, Reaction r, Reactor reactor) { From 538da7cdb5dfe90b4d123bd023c6d7be15854f43 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 22 Feb 2023 22:08:05 -0800 Subject: [PATCH 14/92] Addressing NPE in C++ tests. --- org.lflang/src/org/lflang/LinguaFranca.xtext | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/LinguaFranca.xtext b/org.lflang/src/org/lflang/LinguaFranca.xtext index 817406e4c9..730a58e65c 100644 --- a/org.lflang/src/org/lflang/LinguaFranca.xtext +++ b/org.lflang/src/org/lflang/LinguaFranca.xtext @@ -277,7 +277,7 @@ Variable: VarRef: (variable=[Variable] | container=[Instantiation] '.' variable=[Variable] - | interleaved?='interleaved' '(' (variable=[Variable] | container=[Instantiation] '.' variable=[Variable]) ')') ('as' (name=ID))? + | interleaved?='interleaved' '(' (variable=[Variable] | container=[Instantiation] '.' variable=[Variable]) ')') ('as' (alias=ID))? ; VarRefOrModeTransition returns VarRef: VarRef | transition=ModeTransition '(' variable=[Mode] ')'; From f037ab4ff06ea7cccc2649b9cb0b9c8b54b4092a Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 22 Feb 2023 23:05:16 -0800 Subject: [PATCH 15/92] Hack around the Arduino #includes. --- .../org/lflang/generator/c/CGenerator.java | 9 ++++-- .../generator/c/CPreambleGenerator.java | 28 ++++++------------- .../generator/c/CReactionGenerator.java | 5 ++-- org.lflang/src/org/lflang/util/FileUtil.java | 13 ++++++--- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index cbe53af971..f1e49a3903 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -542,8 +542,11 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { } } else { try { - FileUtil.arduinoDeleteHelper(fileConfig.getSrcGenPath().resolve("src/"), targetConfig.threading); - FileUtil.relativeIncludeHelper(fileConfig.getSrcGenPath().resolve("src/")); + Path include = fileConfig.getSrcGenPath().resolve("include/"); + Path src = fileConfig.getSrcGenPath().resolve("src/"); + FileUtil.arduinoDeleteHelper(src, targetConfig.threading); + FileUtil.relativeIncludeHelper(src, include); + FileUtil.relativeIncludeHelper(include, include); } catch (IOException e) { //noinspection ThrowableNotThrown,ResultOfMethodCallIgnored Exceptions.sneakyThrow(e); @@ -1096,7 +1099,7 @@ protected void generateConstructor( } protected void generateIncludes(ReactorDecl decl) { - code.pr("#include \"" + decl.getName() + ".h\""); + code.pr("#include \"include/" + decl.getName() + ".h\""); } /** diff --git a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java index d78456e4ae..47bdb63caa 100644 --- a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java @@ -36,30 +36,20 @@ public static String generateIncludeStatements( if (cppMode || targetConfig.platformOptions.platform == Platform.ARDUINO) { code.pr("extern \"C\" {"); } - - String relPathHeader = ""; - if (targetConfig.platformOptions.platform == Platform.ARDUINO) { - relPathHeader = "src/include/"; - - CCoreFilesUtils.getCTargetHeader().forEach( - it -> code.pr("#include " + StringUtil.addDoubleQuotes("src/" + it)) - ); - } else { - CCoreFilesUtils.getCTargetHeader().forEach( - it -> code.pr("#include " + StringUtil.addDoubleQuotes(it)) - ); - } - code.pr("#include \"" + relPathHeader + "core/reactor.h\""); - code.pr("#include \"" + relPathHeader + "core/reactor_common.h\""); + CCoreFilesUtils.getCTargetHeader().forEach( + it -> code.pr("#include " + StringUtil.addDoubleQuotes(it)) + ); + code.pr("#include \"include/core/reactor.h\""); + code.pr("#include \"include/core/reactor_common.h\""); if (targetConfig.threading) { - code.pr("#include \"" + relPathHeader + "core/threaded/scheduler.h\""); + code.pr("#include \"include/core/threaded/scheduler.h\""); } if (tracing != null) { - code.pr("#include \"" + relPathHeader + "core/trace.h\""); + code.pr("#include \"include/core/trace.h\""); } - code.pr("#include \"" + relPathHeader + "core/mixed_radix.h\""); - code.pr("#include \"" + relPathHeader + "core/port.h\""); + code.pr("#include \"include/core/mixed_radix.h\""); + code.pr("#include \"include/core/port.h\""); code.pr("int lf_reactor_c_main(int argc, const char* argv[]);"); if(targetConfig.fedSetupPreamble != null) { code.pr("#include \"" + relPathHeader + "core/federated/federate.h\""); diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index e41589d970..61d9fd71ad 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -1055,10 +1055,9 @@ public static String generateReaction( types, errorReporter, mainDef, requiresType); - String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; code.pr( "#include " + StringUtil.addDoubleQuotes( - srcPrefix + CCoreFilesUtils.getCTargetSetHeader())); + CCoreFilesUtils.getCTargetSetHeader())); CMethodGenerator.generateMacrosForMethods(ASTUtils.toDefinition(decl), code); code.pr(generateFunction( @@ -1083,7 +1082,7 @@ init, getCode(types, reaction, decl) CMethodGenerator.generateMacroUndefsForMethods(ASTUtils.toDefinition(decl), code); code.pr( "#include " + StringUtil.addDoubleQuotes( - srcPrefix + CCoreFilesUtils.getCTargetSetUndefHeader())); + CCoreFilesUtils.getCTargetSetUndefHeader())); return code.toString(); } diff --git a/org.lflang/src/org/lflang/util/FileUtil.java b/org.lflang/src/org/lflang/util/FileUtil.java index 61fa3d8816..d4d34c7b08 100644 --- a/org.lflang/src/org/lflang/util/FileUtil.java +++ b/org.lflang/src/org/lflang/util/FileUtil.java @@ -455,15 +455,20 @@ public static boolean isCFile(Path path) { * @param dir The folder to search for includes to change. * @throws IOException If the given set of files cannot be relativized. */ - public static void relativeIncludeHelper(Path dir) throws IOException { + public static void relativeIncludeHelper(Path dir, Path includePath) throws IOException { System.out.println("Relativizing all includes in " + dir.toString()); - List allPaths = Files.walk(dir) + List includePaths = Files.walk(includePath) + .filter(Files::isRegularFile) + .filter(FileUtil::isCFile) + .sorted(Comparator.reverseOrder()) + .collect(Collectors.toList()); + List srcPaths = Files.walk(dir) .filter(Files::isRegularFile) .filter(FileUtil::isCFile) .sorted(Comparator.reverseOrder()) .collect(Collectors.toList()); Map fileStringToFilePath = new HashMap(); - for (Path path : allPaths) { + for (Path path : includePaths) { String fileName = path.getFileName().toString(); if (path.getFileName().toString().contains("CMakeLists.txt")) continue; if (fileStringToFilePath.put(fileName, path) != null) { @@ -471,7 +476,7 @@ public static void relativeIncludeHelper(Path dir) throws IOException { } } Pattern regexExpression = Pattern.compile("#include\s+[\"]([^\"]+)*[\"]"); - for (Path path : allPaths) { + for (Path path : srcPaths) { String fileName = path.getFileName().toString(); String fileContents = Files.readString(path); Matcher matcher = regexExpression.matcher(fileContents); From ede2f9faf293e5e55d551212153108c8519e3a15 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 22 Feb 2023 23:18:47 -0800 Subject: [PATCH 16/92] Address another name conflict in C++ generator. --- org.lflang/src/org/lflang/generator/cpp/CppExtensions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/cpp/CppExtensions.kt b/org.lflang/src/org/lflang/generator/cpp/CppExtensions.kt index f2386bf96a..2944cd3b67 100644 --- a/org.lflang/src/org/lflang/generator/cpp/CppExtensions.kt +++ b/org.lflang/src/org/lflang/generator/cpp/CppExtensions.kt @@ -45,7 +45,7 @@ import org.lflang.lf.WidthSpec */ /** Get the "name" a reaction is represented with in target code.*/ -val Reaction.name +val Reaction.codeName get(): String = "r$indexInContainer" /* ********************************************************************************************** From 29ad2768c38a7660b562401ed0fad48190f9f0ff Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 22 Feb 2023 23:58:05 -0800 Subject: [PATCH 17/92] Address Python test failure. --- .../src/org/lflang/generator/python/PythonGenerator.java | 7 ++----- test/Python/.gitignore | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 test/Python/.gitignore diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 9cd3ca6dda..abc998e243 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -360,15 +360,12 @@ public void processProtoFile(String filename) { public void generateAuxiliaryStructs( CodeBuilder builder, Reactor r ) { - // First, handle inputs. for (Input input : ASTUtils.allInputs(r)) { generateAuxiliaryStructsForPort(builder, r, input); } - // Next, handle outputs. for (Output output : ASTUtils.allOutputs(r)) { generateAuxiliaryStructsForPort(builder, r, output); } - // Finally, handle actions. for (Action action : ASTUtils.allActions(r)) { generateAuxiliaryStructsForAction(builder, r, action); } @@ -377,14 +374,14 @@ public void generateAuxiliaryStructs( private void generateAuxiliaryStructsForPort(CodeBuilder builder, ReactorDecl decl, Port port) { boolean isTokenType = CUtil.isTokenType(ASTUtils.getInferredType(port), types); - code.pr(port, + builder.pr(port, PythonPortGenerator.generateAliasTypeDef(decl, port, isTokenType, genericPortType)); } private void generateAuxiliaryStructsForAction(CodeBuilder builder, ReactorDecl decl, Action action) { - code.pr(action, PythonActionGenerator.generateAliasTypeDef(decl, action, genericActionType)); + builder.pr(action, PythonActionGenerator.generateAliasTypeDef(decl, action, genericActionType)); } /** diff --git a/test/Python/.gitignore b/test/Python/.gitignore new file mode 100644 index 0000000000..08f514ebc5 --- /dev/null +++ b/test/Python/.gitignore @@ -0,0 +1 @@ +include/ From 31fef2ea7f8d44a433ff27069cd481650461bf87 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Feb 2023 00:11:15 -0800 Subject: [PATCH 18/92] Try again to address C++ name conflict. --- .../cpp/CppAssembleMethodGenerator.kt | 16 ++++++------- .../generator/cpp/CppReactionGenerator.kt | 24 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/cpp/CppAssembleMethodGenerator.kt b/org.lflang/src/org/lflang/generator/cpp/CppAssembleMethodGenerator.kt index 45f6f10b0a..fb4f8605d2 100644 --- a/org.lflang/src/org/lflang/generator/cpp/CppAssembleMethodGenerator.kt +++ b/org.lflang/src/org/lflang/generator/cpp/CppAssembleMethodGenerator.kt @@ -100,41 +100,41 @@ class CppAssembleMethodGenerator(private val reactor: Reactor) { private fun declareTrigger(reaction: Reaction, trigger: TriggerRef): String = if (trigger is VarRef && trigger.variable is Port) { // if the trigger is a port, then it could be a multiport or contained in a bank - iterateOverAllPortsAndApply(trigger) { port: String -> "${reaction.name}.declare_trigger(&$port);" } + iterateOverAllPortsAndApply(trigger) { port: String -> "${reaction.codeName}.declare_trigger(&$port);" } } else { // treat as single trigger otherwise - "${reaction.name}.declare_trigger(&${trigger.name});" + "${reaction.codeName}.declare_trigger(&${trigger.name});" } private fun declareDependency(reaction: Reaction, dependency: VarRef): String { assert(dependency.variable is Port) // if the trigger is a port, then it could be a multiport or contained in a bank - return iterateOverAllPortsAndApply(dependency) { port: String -> "${reaction.name}.declare_dependency(&$port);" } + return iterateOverAllPortsAndApply(dependency) { port: String -> "${reaction.codeName}.declare_dependency(&$port);" } } private fun declareAntidependency(reaction: Reaction, antidependency: VarRef): String { val variable = antidependency.variable return if (variable is Port) { // if the trigger is a port, then it could be a multiport or contained in a bank - iterateOverAllPortsAndApply(antidependency) { port: String -> "${reaction.name}.declare_antidependency(&$port);" } + iterateOverAllPortsAndApply(antidependency) { port: String -> "${reaction.codeName}.declare_antidependency(&$port);" } } else { // treat as single antidependency otherwise - if (variable is Action) "${reaction.name}.declare_schedulable_action(&${antidependency.name});" - else "${reaction.name}.declare_antidependency(&${antidependency.name});" + if (variable is Action) "${reaction.codeName}.declare_schedulable_action(&${antidependency.name});" + else "${reaction.codeName}.declare_antidependency(&${antidependency.name});" } } private fun setDeadline(reaction: Reaction): String { val delay = reaction.deadline.delay val value = if (delay is ParameterReference) "__lf_inner.${delay.parameter.name}" else delay.toCppTime() - return "${reaction.name}.set_deadline($value, [this]() { ${reaction.name}_deadline_handler(); });" + return "${reaction.codeName}.set_deadline($value, [this]() { ${reaction.codeName}_deadline_handler(); });" } private fun assembleReaction(reaction: Reaction): String { val sources = reaction.sources.filter { it.variable is Port } return with(PrependOperator) { """ - |// ${reaction.name} + |// ${reaction.codeName} ${" |"..reaction.triggers.joinToString(separator = "\n") { declareTrigger(reaction, it) }} ${" |"..sources.joinToString(separator = "\n") { declareDependency(reaction, it) }} ${" |"..reaction.effects.joinToString(separator = "\n") { declareAntidependency(reaction, it) }} diff --git a/org.lflang/src/org/lflang/generator/cpp/CppReactionGenerator.kt b/org.lflang/src/org/lflang/generator/cpp/CppReactionGenerator.kt index c1e66f3632..de34478723 100644 --- a/org.lflang/src/org/lflang/generator/cpp/CppReactionGenerator.kt +++ b/org.lflang/src/org/lflang/generator/cpp/CppReactionGenerator.kt @@ -67,8 +67,8 @@ class CppReactionGenerator( private fun Reaction.getAllReferencedVariablesForContainer(container: Instantiation) = allVariableReferences.filter { it.container == container }.distinct() - private fun Reaction.getViewClassName(container: Instantiation) = "__lf_view_of_${name}_on_${container.name}_t" - private fun Reaction.getViewInstanceName(container: Instantiation) = "__lf_view_of_${name}_on_${container.name}" + private fun Reaction.getViewClassName(container: Instantiation) = "__lf_view_of_${codeName}_on_${container.name}_t" + private fun Reaction.getViewInstanceName(container: Instantiation) = "__lf_view_of_${codeName}_on_${container.name}" private val VarRef.cppType get() = @@ -102,20 +102,20 @@ class CppReactionGenerator( allUncontainedSources.map { it.name } + allUncontainedEffects.map { it.name } + allReferencedContainers.map { getViewInstanceName(it) } - val body = "void ${name}_body() { __lf_inner.${name}_body(${parameters.joinToString(", ")}); }" + val body = "void ${codeName}_body() { __lf_inner.${codeName}_body(${parameters.joinToString(", ")}); }" val deadlineHandler = - "void ${name}_deadline_handler() { __lf_inner.${name}_deadline_handler(${parameters.joinToString(", ")}); }" + "void ${codeName}_deadline_handler() { __lf_inner.${codeName}_deadline_handler(${parameters.joinToString(", ")}); }" return if (deadline == null) """ $body - reactor::Reaction $name{"$label", $priority, this, [this]() { ${name}_body(); }}; + reactor::Reaction $codeName{"$label", $priority, this, [this]() { ${codeName}_body(); }}; """.trimIndent() else """ $body $deadlineHandler - reactor::Reaction $name{"$label", $priority, this, [this]() { ${name}_body(); }}; + reactor::Reaction $codeName{"$label", $priority, this, [this]() { ${codeName}_body(); }}; """.trimIndent() } } @@ -123,11 +123,11 @@ class CppReactionGenerator( private fun generateFunctionDeclaration(reaction: Reaction, postfix: String): String { val params = reaction.getBodyParameters() return when (params.size) { - 0 -> "void ${reaction.name}_$postfix();" - 1 -> "void ${reaction.name}_$postfix(${params[0]});" + 0 -> "void ${reaction.codeName}_$postfix();" + 1 -> "void ${reaction.codeName}_$postfix(${params[0]});" else -> with(PrependOperator) { """ - |void ${reaction.name}_$postfix( + |void ${reaction.codeName}_$postfix( ${" | "..params.joinToString(",\n")}); """.trimMargin() } @@ -137,11 +137,11 @@ class CppReactionGenerator( private fun getFunctionDefinitionSignature(reaction: Reaction, postfix: String): String { val params = reaction.getBodyParameters() return when (params.size) { - 0 -> "void ${reactor.templateName}::Inner::${reaction.name}_$postfix()" - 1 -> "void ${reactor.templateName}::Inner::${reaction.name}_$postfix(${params[0]})" + 0 -> "void ${reactor.templateName}::Inner::${reaction.codeName}_$postfix()" + 1 -> "void ${reactor.templateName}::Inner::${reaction.codeName}_$postfix(${params[0]})" else -> with(PrependOperator) { """ - |void ${reactor.templateName}::Inner::${reaction.name}_$postfix( + |void ${reactor.templateName}::Inner::${reaction.codeName}_$postfix( ${" | "..params.joinToString(",\n")}) """.trimMargin() } From 6a8430c96518d1315297e3995736933d2d1b4961 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Feb 2023 14:47:40 -0800 Subject: [PATCH 19/92] Address failing CCpp tests. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index f1e49a3903..471018ab55 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1099,7 +1099,9 @@ protected void generateConstructor( } protected void generateIncludes(ReactorDecl decl) { + if (CCppMode) code.pr("extern \"C\" {"); code.pr("#include \"include/" + decl.getName() + ".h\""); + if (CCppMode) code.pr("}"); } /** From 6e5b7a167ac8e221ec010373af954382092d3829 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Feb 2023 14:56:23 -0800 Subject: [PATCH 20/92] Fix type inference issue. --- .../org/lflang/generator/c/CReactorHeaderFileGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 3a1f187a3d..ad66849579 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -54,10 +54,10 @@ public static String selfStructName(String name) { private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { builder.pr("typedef struct " + selfStructName(r.getName()) + "{"); for (Parameter p : r.getParameters()) { - builder.pr(types.getTargetType(p.getType()) + " " + p.getName() + ";"); + builder.pr(types.getTargetType(p) + " " + p.getName() + ";"); } for (StateVar s : r.getStateVars()) { - builder.pr(types.getTargetType(s.getType()) + " " + s.getName() + ";"); + builder.pr(types.getTargetType(s) + " " + s.getName() + ";"); } builder.pr("int end[0]; // placeholder; MSVC does not compile empty structs"); builder.pr("} " + selfStructName(r.getName()) + ";"); From 7fa42ba1f9daf5170c1e356bb33e4bb29e9877f9 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Feb 2023 19:24:03 -0800 Subject: [PATCH 21/92] Replace ReactorDecl.getName() -> Reactor.getName() --- .../lflang/generator/c/CActionGenerator.java | 7 ++- .../generator/c/CConstructorGenerator.java | 4 +- .../org/lflang/generator/c/CGenerator.java | 44 ++++++++++--------- .../lflang/generator/c/CMethodGenerator.java | 2 +- .../lflang/generator/c/CPortGenerator.java | 16 +++---- .../generator/c/CReactionGenerator.java | 33 +++++++------- .../c/CReactorHeaderFileGenerator.java | 20 ++++++--- .../src/org/lflang/generator/c/CUtil.java | 7 +-- .../python/PythonActionGenerator.java | 6 +-- .../generator/python/PythonGenerator.java | 12 ++--- .../generator/python/PythonPortGenerator.java | 5 ++- .../python/PythonReactionGenerator.java | 23 +++++----- 12 files changed, 93 insertions(+), 86 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CActionGenerator.java b/org.lflang/src/org/lflang/generator/c/CActionGenerator.java index e800328e18..37867f9101 100644 --- a/org.lflang/src/org/lflang/generator/c/CActionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CActionGenerator.java @@ -98,13 +98,12 @@ public static String generateTokenInitializer( */ public static void generateDeclarations( Reactor reactor, - ReactorDecl decl, CodeBuilder body, CodeBuilder constructorCode ) { for (Action action : ASTUtils.allActions(reactor)) { var actionName = action.getName(); - body.pr(action, CGenerator.variableStructType(action, decl)+" _lf_"+actionName+";"); + body.pr(action, CGenerator.variableStructType(action, reactor)+" _lf_"+actionName+";"); // Initialize the trigger pointer in the action. constructorCode.pr(action, "self->_lf_"+actionName+".trigger = &self->_lf__"+actionName+";"); } @@ -122,7 +121,7 @@ public static void generateDeclarations( * @return The auxiliary struct for the port as a string */ public static String generateAuxiliaryStruct( - ReactorDecl decl, + Reactor r, Action action, Target target, CTypes types, @@ -146,7 +145,7 @@ public static String generateAuxiliaryStruct( code.pr(valueDeclaration(action, target, types)); code.pr(federatedExtension.toString()); code.unindent(); - code.pr("} " + variableStructType(action, decl) + ";"); + code.pr("} " + variableStructType(action, r) + ";"); return code.toString(); } diff --git a/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java b/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java index 0cc2199cae..e066c3752d 100644 --- a/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java @@ -1,7 +1,9 @@ package org.lflang.generator.c; +import org.lflang.ASTUtils; import org.lflang.federated.generator.FederateInstance; import org.lflang.generator.CodeBuilder; +import org.lflang.lf.Reactor; import org.lflang.lf.ReactorDecl; /** @@ -16,7 +18,7 @@ public class CConstructorGenerator { * go into the constructor. */ public static String generateConstructor( - ReactorDecl reactor, + Reactor reactor, String constructorCode ) { var structType = CUtil.selfType(reactor); diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 471018ab55..d98c73a343 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -922,13 +922,13 @@ public void copyUserFiles(TargetConfig targetConfig, FileConfig fileConfig) { * - If there are any preambles, add them to the preambles of the reactor. */ private void generateReactorDefinitions() { - var generatedReactorDecls = new LinkedHashSet(); + var generatedReactors = new LinkedHashSet(); if (this.main != null) { - generateReactorChildren(this.main, generatedReactorDecls); + generateReactorChildren(this.main, generatedReactors); } if (this.mainDef != null) { - generateReactorClass(this.mainDef.getReactorClass()); + generateReactorClass(ASTUtils.toDefinition(this.mainDef.getReactorClass())); } if (mainDef == null) { @@ -948,6 +948,7 @@ private void generateReactorDefinitions() { } private void generateHeaders() throws IOException { + FileUtil.deleteDirectory(fileConfig.getIncludePath()); FileUtil.copyDirectoryFromClassPath( fileConfig.getRuntimeIncludePath(), fileConfig.getIncludePath(), @@ -973,15 +974,15 @@ private void generateHeaders() throws IOException { */ private void generateReactorChildren( ReactorInstance reactor, - LinkedHashSet generatedReactorDecls + LinkedHashSet generatedReactors ) { for (ReactorInstance r : reactor.children) { if (r.reactorDeclaration != null && - !generatedReactorDecls.contains(r.reactorDeclaration)) { - generatedReactorDecls.add(r.reactorDeclaration); - generateReactorChildren(r, generatedReactorDecls); + !generatedReactors.contains(r.reactorDefinition)) { + generatedReactors.add(r.reactorDefinition); + generateReactorChildren(r, generatedReactors); inspectReactorEResource(r.reactorDeclaration); - generateReactorClass(r.reactorDeclaration); + generateReactorClass(r.reactorDefinition); } } } @@ -1036,7 +1037,7 @@ protected void copyTargetFiles() throws IOException { * data to contained reactors that are not in the federate. * @param reactor The parsed reactor data structure. */ - private void generateReactorClass(ReactorDecl reactor) { + private void generateReactorClass(Reactor reactor) { // FIXME: Currently we're not reusing definitions for declarations that point to the same definition. Reactor defn = ASTUtils.toDefinition(reactor); @@ -1090,7 +1091,7 @@ protected void generateUserPreamblesForReactor(Reactor reactor) { * go into the constructor. */ protected void generateConstructor( - ReactorDecl reactor, CodeBuilder constructorCode + Reactor reactor, CodeBuilder constructorCode ) { code.pr(CConstructorGenerator.generateConstructor( reactor, @@ -1100,7 +1101,7 @@ protected void generateConstructor( protected void generateIncludes(ReactorDecl decl) { if (CCppMode) code.pr("extern \"C\" {"); - code.pr("#include \"include/" + decl.getName() + ".h\""); + code.pr("#include \"include/" + ASTUtils.toDefinition(decl).getName() + ".h\""); if (CCppMode) code.pr("}"); } @@ -1159,7 +1160,7 @@ protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r) { */ private void generateSelfStruct(ReactorDecl decl, CodeBuilder constructorCode) { var reactor = toDefinition(decl); - var selfType = CUtil.selfType(decl); + var selfType = CUtil.selfType(ASTUtils.toDefinition(decl)); // Construct the typedef for the "self" struct. // Create a type name for the self struct. @@ -1175,7 +1176,7 @@ private void generateSelfStruct(ReactorDecl decl, CodeBuilder constructorCode) { body.pr(CStateGenerator.generateDeclarations(reactor, types)); // Next handle actions. - CActionGenerator.generateDeclarations(reactor, decl, body, constructorCode); + CActionGenerator.generateDeclarations(reactor, body, constructorCode); // Next handle inputs and outputs. CPortGenerator.generateDeclarations(reactor, decl, body, constructorCode); @@ -1237,6 +1238,7 @@ private void generateInteractingContainedReactors( var contained = new InteractingContainedReactors(reactor); // Next generate the relevant code. for (Instantiation containedReactor : contained.containedReactors()) { + Reactor containedReactorType = ASTUtils.toDefinition(containedReactor.getReactorClass()); // First define an _width variable in case it is a bank. var array = ""; var width = -2; @@ -1264,12 +1266,12 @@ private void generateInteractingContainedReactors( // to be malloc'd at initialization. if (!ASTUtils.isMultiport(port)) { // Not a multiport. - body.pr(port, variableStructType(port, containedReactor.getReactorClass())+" "+port.getName()+";"); + body.pr(port, variableStructType(port, containedReactorType)+" "+port.getName()+";"); } else { // Is a multiport. // Memory will be malloc'd in initialization. body.pr(port, String.join("\n", - variableStructType(port, containedReactor.getReactorClass())+"** "+port.getName()+";", + variableStructType(port, containedReactorType)+"** "+port.getName()+";", "int "+port.getName()+"_width;" )); } @@ -1279,13 +1281,13 @@ private void generateInteractingContainedReactors( // self struct of the container. if (!ASTUtils.isMultiport(port)) { // Not a multiport. - body.pr(port, variableStructType(port, containedReactor.getReactorClass())+"* "+port.getName()+";"); + body.pr(port, variableStructType(port, containedReactorType)+"* "+port.getName()+";"); } else { // Is a multiport. // Here, we will use an array of pointers. // Memory will be malloc'd in initialization. body.pr(port, String.join("\n", - variableStructType(port, containedReactor.getReactorClass())+"** "+port.getName()+";", + variableStructType(port, containedReactorType)+"** "+port.getName()+";", "int "+port.getName()+"_width;" )); } @@ -1638,7 +1640,7 @@ public void processProtoFile(String filename) { * @param reactor The reactor class. * @return The name of the self struct. */ - public static String variableStructType(Variable variable, ReactorDecl reactor) { + public static String variableStructType(Variable variable, Reactor reactor) { return reactor.getName().toLowerCase()+"_"+variable.getName()+"_t"; } @@ -1646,12 +1648,12 @@ public static String variableStructType(Variable variable, ReactorDecl reactor) * Construct a unique type for the struct of the specified * instance (port or action). * This is required to be the same as the type name returned by - * {@link #variableStructType(Variable, ReactorDecl)}. + * {@link #variableStructType(Variable, Reactor)}. * @param portOrAction The port or action instance. * @return The name of the self struct. */ public static String variableStructType(TriggerInstance portOrAction) { - return portOrAction.getParent().reactorDeclaration.getName().toLowerCase()+"_"+portOrAction.getName()+"_t"; + return portOrAction.getParent().reactorDefinition.getName().toLowerCase()+"_"+portOrAction.getName()+"_t"; } /** @@ -1674,7 +1676,7 @@ private void generateTraceTableEntries(ReactorInstance instance) { * @param instance A reactor instance. */ public void generateReactorInstance(ReactorInstance instance) { - var reactorClass = instance.getDefinition().getReactorClass(); + var reactorClass = ASTUtils.toDefinition(instance.getDefinition().getReactorClass()); var fullName = instance.getFullName(); initializeTriggerObjects.pr( "// ***** Start initializing " + fullName + " of class " + reactorClass.getName()); diff --git a/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java b/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java index 41ef785d60..a9329c6036 100644 --- a/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java @@ -67,7 +67,7 @@ public static String generateMethod( code.indent(); // Define the "self" struct. - String structType = CUtil.selfType(decl); + String structType = CUtil.selfType(ASTUtils.toDefinition(decl)); // A null structType means there are no inputs, state, // or anything else. No need to declare it. if (structType != null) { diff --git a/org.lflang/src/org/lflang/generator/c/CPortGenerator.java b/org.lflang/src/org/lflang/generator/c/CPortGenerator.java index 0db76a16ff..543514ff71 100644 --- a/org.lflang/src/org/lflang/generator/c/CPortGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CPortGenerator.java @@ -53,7 +53,7 @@ public static void generateDeclarations( * @return The auxiliary struct for the port as a string */ public static String generateAuxiliaryStruct( - ReactorDecl decl, + Reactor decl, Port port, Target target, ErrorReporter errorReporter, @@ -210,21 +210,21 @@ private static void generateInputDeclarations( if (ASTUtils.isMultiport(input)) { body.pr(input, String.join("\n", "// Multiport input array will be malloc'd later.", - variableStructType(input, decl)+"** _lf_"+inputName+";", + variableStructType(input, reactor)+"** _lf_"+inputName+";", "int _lf_"+inputName+"_width;", "// Default input (in case it does not get connected)", - variableStructType(input, decl)+" _lf_default__"+inputName+";", + variableStructType(input, reactor)+" _lf_default__"+inputName+";", "// Struct to support efficiently reading sparse inputs.", "lf_sparse_io_record_t* _lf_"+inputName+"__sparse;" )); } else { // input is not a multiport. body.pr(input, String.join("\n", - variableStructType(input, decl)+"* _lf_"+inputName+";", + variableStructType(input, reactor)+"* _lf_"+inputName+";", "// width of -2 indicates that it is not a multiport.", "int _lf_"+inputName+"_width;", "// Default input (in case it does not get connected)", - variableStructType(input, decl)+" _lf_default__"+inputName+";" + variableStructType(input, reactor)+" _lf_default__"+inputName+";" )); constructorCode.pr(input, String.join("\n", @@ -256,7 +256,7 @@ private static void generateOutputDeclarations( if (ASTUtils.isMultiport(output)) { body.pr(output, String.join("\n", "// Array of output ports.", - variableStructType(output, decl)+"* _lf_"+outputName+";", + variableStructType(output, reactor)+"* _lf_"+outputName+";", "int _lf_"+outputName+"_width;", "// An array of pointers to the individual ports. Useful", "// for the lf_set macros to work out-of-the-box for", @@ -264,11 +264,11 @@ private static void generateOutputDeclarations( "// value can be accessed via a -> operator (e.g.,foo[i]->value).", "// So we have to handle multiports specially here a construct that", "// array of pointers.", - variableStructType(output, decl)+"** _lf_"+outputName+"_pointers;" + variableStructType(output, reactor)+"** _lf_"+outputName+"_pointers;" )); } else { body.pr(output, String.join("\n", - variableStructType(output, decl)+" _lf_"+outputName+";", + variableStructType(output, reactor)+" _lf_"+outputName+";", "int _lf_"+outputName+"_width;" )); } diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index 61d9fd71ad..64705fa5dc 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -50,7 +50,7 @@ public class CReactionGenerator { */ public static String generateInitializationForReaction(String body, Reaction reaction, - ReactorDecl decl, + Reactor decl, int reactionIndex, CTypes types, ErrorReporter errorReporter, @@ -355,7 +355,7 @@ private static void generateVariablesForSendingToContainedReactors( structBuilder = new CodeBuilder(); structs.put(definition, structBuilder); } - String inputStructType = CGenerator.variableStructType(input, definition.getReactorClass()); + String inputStructType = CGenerator.variableStructType(input, ASTUtils.toDefinition(definition.getReactorClass())); String defName = definition.getName(); String defWidth = generateWidthVariable(defName); String inputName = input.getName(); @@ -409,22 +409,20 @@ private static void generateVariablesForSendingToContainedReactors( * @param builder The place into which to write the code. * @param structs A map from reactor instantiations to a place to write * struct fields. - * @param port The port. - * @param decl The reactor or import statement. */ private static void generatePortVariablesInReaction( CodeBuilder builder, Map structs, VarRef port, - ReactorDecl decl, + Reactor r, CTypes types ) { if (port.getVariable() instanceof Input) { - builder.pr(generateInputVariablesInReaction((Input) port.getVariable(), decl, types)); + builder.pr(generateInputVariablesInReaction((Input) port.getVariable(), r, types)); } else { // port is an output of a contained reactor. Output output = (Output) port.getVariable(); - String portStructType = CGenerator.variableStructType(output, port.getContainer().getReactorClass()); + String portStructType = CGenerator.variableStructType(output, ASTUtils.toDefinition(port.getContainer().getReactorClass())); CodeBuilder structBuilder = structs.get(port.getContainer()); if (structBuilder == null) { @@ -475,14 +473,13 @@ private static void generatePortVariablesInReaction( /** Generate action variables for a reaction. * @param action The action. - * @param decl The reactor. */ private static String generateActionVariablesInReaction( Action action, - ReactorDecl decl, + Reactor r, CTypes types ) { - String structType = CGenerator.variableStructType(action, decl); + String structType = CGenerator.variableStructType(action, r); // If the action has a type, create variables for accessing the value. InferredType type = ASTUtils.getInferredType(action); // Pointer to the lf_token_t sent as the payload in the trigger. @@ -519,14 +516,14 @@ private static String generateActionVariablesInReaction( * initialize local variables for the specified input port * in a reaction function from the "self" struct. * @param input The input statement from the AST. - * @param decl The reactor. + * @param r The reactor. */ private static String generateInputVariablesInReaction( Input input, - ReactorDecl decl, + Reactor r, CTypes types ) { - String structType = CGenerator.variableStructType(input, decl); + String structType = CGenerator.variableStructType(input, r); InferredType inputType = ASTUtils.getInferredType(input); CodeBuilder builder = new CodeBuilder(); String inputName = input.getName(); @@ -627,11 +624,11 @@ private static String generateInputVariablesInReaction( * initialize local variables for outputs in a reaction function * from the "self" struct. * @param effect The effect declared by the reaction. This must refer to an output. - * @param decl The reactor containing the reaction or the import statement. + * @param r The reactor containing the reaction. */ public static String generateOutputVariablesInReaction( VarRef effect, - ReactorDecl decl, + Reactor r, ErrorReporter errorReporter, boolean requiresTypes ) { @@ -645,9 +642,9 @@ public static String generateOutputVariablesInReaction( // The container of the output may be a contained reactor or // the reactor containing the reaction. String outputStructType = (effect.getContainer() == null) ? - CGenerator.variableStructType(output, decl) + CGenerator.variableStructType(output, r) : - CGenerator.variableStructType(output, effect.getContainer().getReactorClass()); + CGenerator.variableStructType(output, ASTUtils.toDefinition(effect.getContainer().getReactorClass())); if (!ASTUtils.isMultiport(output)) { // Output port is not a multiport. return outputStructType+"* "+outputName+" = &self->_lf_"+outputName+";"; @@ -1051,7 +1048,7 @@ public static String generateReaction( var code = new CodeBuilder(); var body = ASTUtils.toText(getCode(types, reaction, decl)); String init = generateInitializationForReaction( - body, reaction, decl, reactionIndex, + body, reaction, ASTUtils.toDefinition(decl), reactionIndex, types, errorReporter, mainDef, requiresType); diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index ad66849579..f1ce833281 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -31,14 +31,22 @@ public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, G } private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator) { CodeBuilder builder = new CodeBuilder(); + appendIncludeGuard(builder, r); appendPoundIncludes(builder); appendSelfStruct(builder, types, r); generator.generate(builder, r); for (Reaction reaction : r.getReactions()) { appendSignature(builder, types, reaction, r); } + builder.pr("#endif"); return builder.getCode(); } + + private static void appendIncludeGuard(CodeBuilder builder, Reactor r) { + String macro = r.getName().toUpperCase() + "_H"; + builder.pr("#ifndef " + macro); + builder.pr("#define " + macro); + } private static void appendPoundIncludes(CodeBuilder builder) { builder.pr(""" #include "../include/api/api.h" @@ -47,12 +55,12 @@ private static void appendPoundIncludes(CodeBuilder builder) { """); } - public static String selfStructName(String name) { - return name.toLowerCase() + "_self_t"; + private static String userFacingSelfType(Reactor r) { + return r.getName().toLowerCase() + "_self_t"; } private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { - builder.pr("typedef struct " + selfStructName(r.getName()) + "{"); + builder.pr("typedef struct " + userFacingSelfType(r) + "{"); for (Parameter p : r.getParameters()) { builder.pr(types.getTargetType(p) + " " + p.getName() + ";"); } @@ -60,7 +68,7 @@ private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor builder.pr(types.getTargetType(s) + " " + s.getName() + ";"); } builder.pr("int end[0]; // placeholder; MSVC does not compile empty structs"); - builder.pr("} " + selfStructName(r.getName()) + ";"); + builder.pr("} " + userFacingSelfType(r) + ";"); } private static void appendSignature(CodeBuilder builder, CTypes types, Reaction r, Reactor reactor) { @@ -68,7 +76,7 @@ private static void appendSignature(CodeBuilder builder, CTypes types, Reaction } private static String reactionParameters(CTypes types, Reaction r, Reactor reactor) { - return Stream.concat(Stream.of(selfStructName(reactor.getName()) + "* self"), ioTypedVariableStream(r) + return Stream.concat(Stream.of(userFacingSelfType(reactor) + "* self"), ioTypedVariableStream(r) .map((tv) -> reactor.getName().toLowerCase() + "_" + tv.getName() + "_t* " + tv.getName())) .collect(Collectors.joining(", ")); } @@ -80,7 +88,7 @@ public static String reactionArguments(CTypes types, Reaction r, Reactor reactor } private static String getApiSelfStruct(Reactor reactor) { - return "(" + CReactorHeaderFileGenerator.selfStructName(reactor.getName()) + "*) (((char*) self) + sizeof(self_base_t))"; + return "(" + userFacingSelfType(reactor) + "*) (((char*) self) + sizeof(self_base_t))"; } private static Stream ioTypedVariableStream(Reaction r) { diff --git a/org.lflang/src/org/lflang/generator/c/CUtil.java b/org.lflang/src/org/lflang/generator/c/CUtil.java index dd8411ae2e..97f3e35d8f 100644 --- a/org.lflang/src/org/lflang/generator/c/CUtil.java +++ b/org.lflang/src/org/lflang/generator/c/CUtil.java @@ -38,6 +38,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import java.util.Objects; import java.util.stream.Collectors; +import org.lflang.ASTUtils; import org.lflang.ErrorReporter; import org.lflang.FileConfig; import org.lflang.InferredType; @@ -514,8 +515,8 @@ public static String runtimeIndex(ReactorInstance reactor) { * @param reactor The reactor class. * @return The type of a self struct for the specified reactor class. */ - public static String selfType(ReactorDecl reactor) { - if (reactor instanceof Reactor r && r.isMain()) { + public static String selfType(Reactor reactor) { + if (reactor.isMain()) { return "_" + reactor.getName().toLowerCase() + "_main_self_t"; } return "_" + reactor.getName().toLowerCase() + "_self_t"; @@ -523,7 +524,7 @@ public static String selfType(ReactorDecl reactor) { /** Construct a unique type for the "self" struct of the class of the given reactor. */ public static String selfType(ReactorInstance instance) { - return selfType(instance.getDefinition().getReactorClass()); + return selfType(ASTUtils.toDefinition(instance.getDefinition().getReactorClass())); } /** diff --git a/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java index f1a095403f..bcf202b98c 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java @@ -1,13 +1,13 @@ package org.lflang.generator.python; import org.lflang.lf.Action; -import org.lflang.lf.ReactorDecl; +import org.lflang.lf.Reactor; import org.lflang.generator.c.CGenerator; public class PythonActionGenerator { - public static String generateAliasTypeDef(ReactorDecl decl, Action action, + public static String generateAliasTypeDef(Reactor r, Action action, String genericActionType) { - return "typedef "+genericActionType+" "+CGenerator.variableStructType(action, decl)+";"; + return "typedef "+genericActionType+" "+CGenerator.variableStructType(action, r)+";"; } } diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index abc998e243..76fffe7c00 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -354,7 +354,7 @@ public void processProtoFile(String filename) { /** * Generate the aliases for inputs, outputs, and struct type definitions for * actions of the specified reactor in the specified federate. - * @param decl The parsed reactor data structure. + * @param r The parsed reactor data structure. */ @Override public void generateAuxiliaryStructs( @@ -371,17 +371,17 @@ public void generateAuxiliaryStructs( } } - private void generateAuxiliaryStructsForPort(CodeBuilder builder, ReactorDecl decl, + private void generateAuxiliaryStructsForPort(CodeBuilder builder, Reactor r, Port port) { boolean isTokenType = CUtil.isTokenType(ASTUtils.getInferredType(port), types); builder.pr(port, - PythonPortGenerator.generateAliasTypeDef(decl, port, isTokenType, + PythonPortGenerator.generateAliasTypeDef(r, port, isTokenType, genericPortType)); } - private void generateAuxiliaryStructsForAction(CodeBuilder builder, ReactorDecl decl, + private void generateAuxiliaryStructsForAction(CodeBuilder builder, Reactor r, Action action) { - builder.pr(action, PythonActionGenerator.generateAliasTypeDef(decl, action, genericActionType)); + builder.pr(action, PythonActionGenerator.generateAliasTypeDef(r, action, genericActionType)); } /** @@ -469,7 +469,7 @@ protected void generateReaction(Reaction reaction, ReactorDecl decl, int reactio super.generateReaction(reaction, decl, reactionIndex); return; } - code.pr(PythonReactionGenerator.generateCReaction(reaction, decl, reactionIndex, mainDef, errorReporter, types)); + code.pr(PythonReactionGenerator.generateCReaction(reaction, reactor, reactionIndex, mainDef, errorReporter, types)); } /** diff --git a/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java index 2c7512b499..4eb4ba54fa 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java @@ -5,6 +5,7 @@ import org.lflang.lf.Output; import org.lflang.lf.Port; import org.lflang.lf.Action; +import org.lflang.lf.Reactor; import org.lflang.lf.ReactorDecl; import org.lflang.lf.VarRef; import java.util.List; @@ -194,8 +195,8 @@ public static String generatePythonListForContainedBank(String reactorName, Port ); } - public static String generateAliasTypeDef(ReactorDecl decl, Port port, boolean isTokenType, String genericPortType) { - return "typedef "+genericPortType+" "+CGenerator.variableStructType(port, decl)+";"; + public static String generateAliasTypeDef(Reactor r, Port port, boolean isTokenType, String genericPortType) { + return "typedef "+genericPortType+" "+CGenerator.variableStructType(port, r)+";"; } private static String generateConvertCPortToPy(String port) { diff --git a/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java index 77f7352f08..b3b87cdcb6 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java @@ -37,7 +37,6 @@ public class PythonReactionGenerator { * Generate code to call reaction numbered "reactionIndex" in reactor "decl". * @param decl The reactor containing the reaction * @param reactionIndex The index of the reaction - * @param pyObjectDescriptor CPython related descriptors for each object in "pyObjects". * @param pyObjects CPython related objects */ public static String generateCPythonReactionCaller(ReactorDecl decl, @@ -53,7 +52,6 @@ public static String generateCPythonReactionCaller(ReactorDecl decl, * Generate code to call deadline function numbered "reactionIndex" in reactor "decl". * @param decl The reactor containing the reaction * @param reactionIndex The index of the reaction - * @param pyObjectDescriptor CPython related descriptors for each object in "pyObjects". * @param pyObjects CPython related objects */ public static String generateCPythonDeadlineCaller(ReactorDecl decl, @@ -68,7 +66,6 @@ public static String generateCPythonDeadlineCaller(ReactorDecl decl, * Generate code to call deadline function numbered "reactionIndex" in reactor "decl". * @param decl The reactor containing the reaction * @param reactionIndex The index of the reaction - * @param pyObjectDescriptor CPython related descriptors for each object in "pyObjects". * @param pyObjects CPython related objects */ public static String generateCPythonSTPCaller(ReactorDecl decl, @@ -122,7 +119,7 @@ private static String generateCPythonFunctionCaller(String reactorDeclName, * Generate the reaction in the .c file, which calls the Python reaction through the CPython interface. * * @param reaction The reaction to generate Python-specific initialization for. - * @param decl The reactor to which reaction belongs to. + * @param r The reactor to which reaction belongs to. * @param reactionIndex The index number of the reaction in decl. * @param mainDef The main reactor. * @param errorReporter An error reporter. @@ -130,7 +127,7 @@ private static String generateCPythonFunctionCaller(String reactorDeclName, */ public static String generateCReaction( Reaction reaction, - ReactorDecl decl, + Reactor r, int reactionIndex, Instantiation mainDef, ErrorReporter errorReporter, @@ -140,34 +137,34 @@ public static String generateCReaction( // Each input must be cast to (PyObject *) (aka their descriptors for Py_BuildValue are "O") List pyObjects = new ArrayList<>(); CodeBuilder code = new CodeBuilder(); - String cPyInit = generateCPythonInitializers(reaction, decl, pyObjects, errorReporter); + String cPyInit = generateCPythonInitializers(reaction, r, pyObjects, errorReporter); String cInit = CReactionGenerator.generateInitializationForReaction( - "", reaction, decl, reactionIndex, + "", reaction, r, reactionIndex, types, errorReporter, mainDef, Target.Python.requiresTypes); code.pr( "#include " + StringUtil.addDoubleQuotes( CCoreFilesUtils.getCTargetSetHeader())); code.pr(generateFunction( - CReactionGenerator.generateReactionFunctionHeader(decl, reactionIndex), + CReactionGenerator.generateReactionFunctionHeader(r, reactionIndex), cInit, reaction.getCode(), - generateCPythonReactionCaller(decl, reactionIndex, pyObjects, cPyInit) + generateCPythonReactionCaller(r, reactionIndex, pyObjects, cPyInit) )); // Generate code for the STP violation handler, if there is one. if (reaction.getStp() != null) { code.pr(generateFunction( - CReactionGenerator.generateStpFunctionHeader(decl, reactionIndex), + CReactionGenerator.generateStpFunctionHeader(r, reactionIndex), cInit, reaction.getStp().getCode(), - generateCPythonSTPCaller(decl, reactionIndex, pyObjects) + generateCPythonSTPCaller(r, reactionIndex, pyObjects) )); } // Generate code for the deadline violation function, if there is one. if (reaction.getDeadline() != null) { code.pr(generateFunction( - CReactionGenerator.generateDeadlineFunctionHeader(decl, reactionIndex), + CReactionGenerator.generateDeadlineFunctionHeader(r, reactionIndex), cInit, reaction.getDeadline().getCode(), - generateCPythonDeadlineCaller(decl, reactionIndex, pyObjects) + generateCPythonDeadlineCaller(r, reactionIndex, pyObjects) )); } code.pr( From 84a9114e4ff8e40774c511069b0241d10c517aae Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Feb 2023 21:25:09 -0800 Subject: [PATCH 22/92] Use hashes to prevent name conflicts. For non-user-facing code, this seems OK. For the user-facing generated header files, we need a better alternative. --- .../generator/ReactionInstanceGraph.java | 76 ++++---- .../org/lflang/generator/ReactorInstance.java | 181 +++++++++--------- .../generator/c/CConstructorGenerator.java | 5 +- .../org/lflang/generator/c/CGenerator.java | 30 ++- .../lflang/generator/c/CMethodGenerator.java | 2 +- .../generator/c/CReactionGenerator.java | 65 ++++--- .../c/CReactorHeaderFileGenerator.java | 8 +- .../src/org/lflang/generator/c/CUtil.java | 13 +- .../generator/python/PythonGenerator.java | 8 +- .../python/PythonReactionGenerator.java | 24 +-- .../python/PythonReactorGenerator.java | 4 +- .../org/lflang/validation/LFValidator.java | 48 ++--- 12 files changed, 227 insertions(+), 237 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java b/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java index 116cbf3046..3422ee0d50 100644 --- a/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java +++ b/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java @@ -44,23 +44,23 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * In the worst case, of these runtime instances may have distinct dependencies, * and hence distinct levels in the graph. Moreover, some of these instances * may be involved in cycles while others are not. - * + * * Upon construction of this class, the runtime instances are created if necessary, * stored each ReactionInstance, and assigned levels (maximum number of * upstream reaction instances), deadlines, and single dominating reactions. - * + * * After creation, the resulting graph will be empty unless there are causality * cycles, in which case, the resulting graph is a graph of runtime reaction * instances that form cycles. - * + * * @author Marten Lohstroh * @author Edward A. Lee */ public class ReactionInstanceGraph extends PrecedenceGraph { - + /** - * Create a new graph by traversing the maps in the named instances - * embedded in the hierarchy of the program. + * Create a new graph by traversing the maps in the named instances + * embedded in the hierarchy of the program. */ public ReactionInstanceGraph(ReactorInstance main) { this.main = main; @@ -74,12 +74,12 @@ public ReactionInstanceGraph(ReactorInstance main) { * The main reactor instance that this graph is associated with. */ public final ReactorInstance main; - + /////////////////////////////////////////////////////////// //// Public methods - + /** - * Rebuild this graph by clearing and repeating the traversal that + * Rebuild this graph by clearing and repeating the traversal that * adds all the nodes and edges. */ public void rebuild() { @@ -89,7 +89,7 @@ public void rebuild() { // FIXME: Use {@link TargetProperty#EXPORT_DEPENDENCY_GRAPH}. // System.out.println(toDOT()); - // Assign a level to each reaction. + // Assign a level to each reaction. // If there are cycles present in the graph, it will be detected here. assignLevels(); if (nodeCount() != 0) { @@ -109,9 +109,9 @@ public void rebuildAndAssignDeadlines() { assignInferredDeadlines(); this.clear(); } - + /* - * Get an array of non-negative integers representing the number of reactions + * Get an array of non-negative integers representing the number of reactions * per each level, where levels are indices of the array. */ public Integer[] getNumReactionsPerLevel() { @@ -133,7 +133,7 @@ public int getBreadth() { /////////////////////////////////////////////////////////// //// Protected methods - + /** * Add to the graph edges between the given reaction and all the reactions * that depend on the specified port. @@ -144,19 +144,19 @@ protected void addDownstreamReactions(PortInstance port, ReactionInstance reacti // Use mixed-radix numbers to increment over the ranges. List srcRuntimes = reaction.getRuntimeInstances(); List eventualDestinations = port.eventualDestinations(); - + int srcDepth = (port.isInput())? 2 : 1; - + for (SendRange sendRange : eventualDestinations) { for (RuntimeRange dstRange : sendRange.destinations) { - + int dstDepth = (dstRange.instance.isOutput())? 2 : 1; MixedRadixInt dstRangePosition = dstRange.startMR(); int dstRangeCount = 0; MixedRadixInt sendRangePosition = sendRange.startMR(); int sendRangeCount = 0; - + while (dstRangeCount++ < dstRange.width) { int srcIndex = sendRangePosition.get(srcDepth); int dstIndex = dstRangePosition.get(dstDepth); @@ -177,7 +177,7 @@ protected void addDownstreamReactions(PortInstance port, ReactionInstance reacti if (srcRuntime.deadline.compareTo(dstRuntime.deadline) > 0) { srcRuntime.deadline = dstRuntime.deadline; } - + // If this seems to be a single dominating reaction, set it. // If another upstream reaction shows up, then this will be // reset to null. @@ -203,7 +203,7 @@ protected void addDownstreamReactions(PortInstance port, ReactionInstance reacti } /** - * Build the graph by adding nodes and edges based on the given reactor + * Build the graph by adding nodes and edges based on the given reactor * instance. * @param reactor The reactor on the basis of which to add nodes and edges. */ @@ -211,12 +211,12 @@ protected void addNodesAndEdges(ReactorInstance reactor) { ReactionInstance previousReaction = null; for (ReactionInstance reaction : reactor.reactions) { List runtimes = reaction.getRuntimeInstances(); - + // Add reactions of this reactor. for (Runtime runtime : runtimes) { - this.addNode(runtime); + this.addNode(runtime); } - + // If this is not an unordered reaction, then create a dependency // on any previously defined reaction. if (!reaction.isUnordered) { @@ -251,12 +251,12 @@ protected void addNodesAndEdges(ReactorInstance reactor) { addNodesAndEdges(child); } } - + /////////////////////////////////////////////////////////// //// Private fields - + /** - * Number of reactions per level, represented as a list of + * Number of reactions per level, represented as a list of * integers where the indices are the levels. */ private List numReactionsPerLevel = new ArrayList<>(List.of(0)); @@ -268,7 +268,7 @@ protected void addNodesAndEdges(ReactorInstance reactor) { * Analyze the dependencies between reactions and assign each reaction * instance a level. This method removes nodes from this graph as it * assigns levels. Any remaining nodes are part of causality cycles. - * + * * This procedure is based on Kahn's algorithm for topological sorting. * Rather than establishing a total order, we establish a partial order. * In this order, the level of each reaction is the least upper bound of @@ -276,13 +276,13 @@ protected void addNodesAndEdges(ReactorInstance reactor) { */ private void assignLevels() { List start = new ArrayList<>(rootNodes()); - + // All root nodes start with level 0. for (Runtime origin : start) { origin.level = 0; } - // No need to do any of this if there are no root nodes; + // No need to do any of this if there are no root nodes; // the graph must be cyclic. while (!start.isEmpty()) { Runtime origin = start.remove(0); @@ -293,7 +293,7 @@ private void assignLevels() { for (Runtime effect : downstreamAdjacentNodes) { // Stage edge between origin and effect for removal. toRemove.add(effect); - + // Update level of downstream node. effect.level = origin.level + 1; } @@ -306,7 +306,7 @@ private void assignLevels() { start.add(effect); } } - + // Remove visited origin. removeNode(origin); @@ -314,16 +314,16 @@ private void assignLevels() { adjustNumReactionsPerLevel(origin.level, 1); } } - + /** * This function assigns inferred deadlines to all the reactions in the graph. * It is modeled after `assignLevels` but it starts at the leaf nodes and uses * Kahns algorithm to build a reverse topologically sorted graph - * + * */ private void assignInferredDeadlines() { List start = new ArrayList<>(leafNodes()); - + // All leaf nodes have deadline initialized to their declared deadline or MAX_VALUE while (!start.isEmpty()) { Runtime origin = start.remove(0); @@ -334,7 +334,7 @@ private void assignInferredDeadlines() { for (Runtime upstream : upstreamAdjacentNodes) { // Stage edge between origin and upstream for removal. toRemove.add(upstream); - + // Update deadline of upstream node if origins deadline is earlier. if (origin.deadline.isEarlierThan(upstream.deadline)) { upstream.deadline = origin.deadline; @@ -349,12 +349,12 @@ private void assignInferredDeadlines() { start.add(upstream); } } - + // Remove visited origin. removeNode(origin); } } - + /** * Adjust {@link #numReactionsPerLevel} at index level by * adding to the previously recorded number valueToAdd. @@ -411,7 +411,7 @@ public String toDOT() { var currentLevelNodes = groupedNodes.get(level); for (var node: currentLevelNodes) { // Draw the node - var label = CUtil.getName(node.getReaction().getParent().reactorDeclaration) + "." + node.getReaction().getName(); + var label = CUtil.getName(node.getReaction().getParent().reactorDefinition) + "." + node.getReaction().getName(); // Need a positive number to name the nodes in GraphViz var labelHashCode = label.hashCode() & 0xfffffff; dotRepresentation.pr(" node_" + labelHashCode + " [label=\""+ label +"\"];"); @@ -419,7 +419,7 @@ public String toDOT() { // Draw the edges var downstreamNodes = getDownstreamAdjacentNodes(node); for (var downstreamNode: downstreamNodes) { - var downstreamLabel = CUtil.getName(downstreamNode.getReaction().getParent().reactorDeclaration) + "." + downstreamNode.getReaction().getName(); + var downstreamLabel = CUtil.getName(downstreamNode.getReaction().getParent().reactorDefinition) + "." + downstreamNode.getReaction().getName(); edges.append(" node_" + labelHashCode + " -> node_" + (downstreamLabel.hashCode() & 0xfffffff) + ";\n" ); diff --git a/org.lflang/src/org/lflang/generator/ReactorInstance.java b/org.lflang/src/org/lflang/generator/ReactorInstance.java index 305ef420c4..ee05a57b5b 100644 --- a/org.lflang/src/org/lflang/generator/ReactorInstance.java +++ b/org.lflang/src/org/lflang/generator/ReactorInstance.java @@ -74,7 +74,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * instance and the bank widths of all of its parents. * There is exactly one instance of this ReactorInstance class for each * graphical rendition of a reactor in the diagram view. - * + * * For the main reactor, which has no parent, once constructed, * this object represents the entire Lingua Franca program. * If the program has causality loops (a programming error), then @@ -131,7 +131,7 @@ public ReactorInstance(Reactor reactor, ReactorInstance parent, ErrorReporter re * bank members (which have bankIndex >= 0). */ public final List children = new ArrayList<>(); - + /** The input port instances belonging to this reactor instance. */ public final List inputs = new ArrayList<>(); @@ -146,7 +146,7 @@ public ReactorInstance(Reactor reactor, ReactorInstance parent, ErrorReporter re /** The timer instances belonging to this reactor instance. */ public final List timers = new ArrayList<>(); - + /** The mode instances belonging to this reactor instance. */ public final List modes = new ArrayList<>(); @@ -161,18 +161,18 @@ public ReactorInstance(Reactor reactor, ReactorInstance parent, ErrorReporter re ////////////////////////////////////////////////////// //// Public methods. - + /** * Assign levels to all reactions within the same root as this * reactor. The level of a reaction r is equal to the length of the * longest chain of reactions that must have the opportunity to * execute before r at each logical tag. This fails and returns * false if a causality cycle exists. - * + * * This method uses a variant of Kahn's algorithm, which is linear * in V + E, where V is the number of vertices (reactions) and E * is the number of edges (dependencies between reactions). - * + * * @return An empty graph if successful and otherwise a graph * with runtime reaction instances that form cycles. */ @@ -199,8 +199,8 @@ public ReactionInstanceGraph assignDeadlines() { cachedReactionLoopGraph.rebuildAndAssignDeadlines(); return cachedReactionLoopGraph; } - - /** + + /** * Return the instance of a child rector created by the specified * definition or null if there is none. * @param definition The definition of the child reactor ("new" statement). @@ -213,7 +213,7 @@ public ReactorInstance getChildReactorInstance(Instantiation definition) { } return null; } - + /** * Clear any cached data in this reactor and its children. * This is useful if a mutation has been realized. @@ -245,7 +245,7 @@ public void clearCaches(boolean includingRuntimes) { } cachedCycles = null; } - + /** * Return the set of ReactionInstance and PortInstance that form causality * loops in the topmost parent reactor in the instantiation hierarchy. This will return an @@ -255,7 +255,7 @@ public Set> getCycles() { if (depth != 0) return root().getCycles(); if (cachedCycles != null) return cachedCycles; cachedCycles = new LinkedHashSet<>(); - + ReactionInstanceGraph reactionRuntimes = assignLevels(); if (reactionRuntimes.nodes().size() > 0) { Set reactions = new LinkedHashSet<>(); @@ -281,7 +281,7 @@ public Set> getCycles() { cachedCycles.addAll(reactions); cachedCycles.addAll(ports); } - + return cachedCycles; } @@ -297,8 +297,8 @@ public PortInstance getInput(String name) { } return null; } - - /** + + /** * Override the base class to append [i_d], where d is the depth, * if this reactor is in a bank of reactors. * @return The name of this instance. @@ -334,7 +334,7 @@ public PortInstance getOutput(String name) { } return null; } - + /** * Return a parameter matching the specified name if the reactor has one * and otherwise return null. @@ -348,7 +348,7 @@ public ParameterInstance getParameter(String name) { } return null; } - + /** * Return the startup trigger or null if not used in any reaction. */ @@ -362,7 +362,7 @@ public TriggerInstance getStartupTrigger() { public TriggerInstance getShutdownTrigger() { return builtinTriggers.get(BuiltinTrigger.SHUTDOWN); } - + /** * If this reactor is a bank or any of its parents is a bank, * return the total number of runtime instances, which is the product @@ -372,7 +372,7 @@ public TriggerInstance getShutdownTrigger() { public int getTotalWidth() { return getTotalWidth(0); } - + /** * If this reactor is a bank or any of its parents is a bank, * return the total number of runtime instances, which is the product @@ -381,7 +381,7 @@ public int getTotalWidth() { * @param atDepth The depth at which to determine the width. * Use 0 to get the total number of instances. * Use 1 to get the number of instances within a single top-level - * bank member (this is useful for federates). + * bank member (this is useful for federates). */ public int getTotalWidth(int atDepth) { if (width <= 0) return -1; @@ -396,7 +396,7 @@ public int getTotalWidth(int atDepth) { return result; } - /** + /** * Return the trigger instances (input ports, timers, and actions * that trigger reactions) belonging to this reactor instance. */ @@ -409,11 +409,11 @@ public Set> getTriggers() { return triggers; } - /** + /** * Return the trigger instances (input ports, timers, and actions * that trigger reactions) together the ports that the reaction reads * but that don't trigger it. - * + * * @return The trigger instances belonging to this reactor instance. */ public Set> getTriggersAndReads() { @@ -425,42 +425,42 @@ public Set> getTriggersAndReads() { } return triggers; } - + /** * Return true if the top-level parent of this reactor has causality cycles. */ public boolean hasCycles() { return assignLevels().nodeCount() != 0; } - + /** * Given a parameter definition for this reactor, return the initial integer * value of the parameter. If the parameter is overridden when instantiating * this reactor or any of its containing reactors, use that value. * Otherwise, use the default value in the reactor definition. * If the parameter cannot be found or its value is not an integer, return null. - * + * * @param parameter The parameter definition (a syntactic object in the AST). - * + * * @return An integer value or null. */ public Integer initialIntParameterValue(Parameter parameter) { return ASTUtils.initialValueInt(parameter, instantiations()); - } + } /** * Given a parameter definition for this reactor, return the initial value * of the parameter. If the parameter is overridden when instantiating * this reactor or any of its containing reactors, use that value. * Otherwise, use the default value in the reactor definition. - * + * * The returned list of Value objects is such that each element is an * instance of Time, String, or Code, never Parameter. * For most uses, this list has only one element, but parameter * values can be lists of elements, so the returned value is a list. - * + * * @param parameter The parameter definition (a syntactic object in the AST). - * + * * @return A list of Value objects, or null if the parameter is not found. * Return an empty list if no initial value is given. * Each value is an instance of Literal if a literal value is given, @@ -505,10 +505,10 @@ public boolean isBank() { * @return true if reactor definition is marked as main or federated, false otherwise. */ public boolean isMainOrFederated() { - return reactorDefinition != null + return reactorDefinition != null && (reactorDefinition.isMain() || reactorDefinition.isFederated()); } - + /** * Return true if the specified reactor instance is either equal to this * reactor instance or a parent of it. @@ -522,12 +522,12 @@ public boolean isParent(ReactorInstance r) { } return false; } - + /////////////////////////////////////////////////// //// Methods for finding instances in this reactor given an AST node. - - /** - * Return the action instance within this reactor + + /** + * Return the action instance within this reactor * instance corresponding to the specified action reference. * @param action The action as an AST node. * @return The corresponding action instance or null if the @@ -542,7 +542,7 @@ public ActionInstance lookupActionInstance(Action action) { return null; } - /** + /** * Given a parameter definition, return the parameter instance * corresponding to that definition, or null if there is * no such instance. @@ -557,8 +557,8 @@ public ParameterInstance lookupParameterInstance(Parameter parameter) { } return null; } - - /** + + /** * Given a port definition, return the port instance * corresponding to that definition, or null if there is * no such instance. @@ -581,7 +581,7 @@ public PortInstance lookupPortInstance(Port port) { return null; } - /** + /** * Given a reference to a port belonging to this reactor * instance, return the port instance. * Return null if there is no such instance. @@ -604,8 +604,8 @@ public PortInstance lookupPortInstance(VarRef reference) { } } - /** - * Return the reaction instance within this reactor + /** + * Return the reaction instance within this reactor * instance corresponding to the specified reaction. * @param reaction The reaction as an AST node. * @return The corresponding reaction instance or null if the @@ -619,7 +619,7 @@ public ReactionInstance lookupReactionInstance(Reaction reaction) { } return null; } - + /** * Return the reactor instance within this reactor * that has the specified instantiation. Note that this @@ -634,9 +634,9 @@ public ReactorInstance lookupReactorInstance(Instantiation instantiation) { } return null; } - - /** - * Return the timer instance within this reactor + + /** + * Return the timer instance within this reactor * instance corresponding to the specified timer reference. * @param timer The timer as an AST node. * @return The corresponding timer instance or null if the @@ -650,8 +650,8 @@ public TimerInstance lookupTimerInstance(Timer timer) { } return null; } - - /** Returns the mode instance within this reactor + + /** Returns the mode instance within this reactor * instance corresponding to the specified mode reference. * @param mode The mode as an AST node. * @return The corresponding mode instance or null if the @@ -666,14 +666,14 @@ public ModeInstance lookupModeInstance(Mode mode) { return null; } - /** + /** * Return a descriptive string. */ @Override public String toString() { return "ReactorInstance " + getFullName(); } - + /** * Assuming that the given expression denotes a valid time, return a time value. * @@ -690,7 +690,7 @@ public TimeValue getTimeValue(Expression expr) { return ASTUtils.getLiteralTimeValue(expr); } } - + ////////////////////////////////////////////////////// //// Protected fields. @@ -714,8 +714,8 @@ public TimeValue getTimeValue(Expression expr) { ////////////////////////////////////////////////////// //// Protected methods. - - /** + + /** * Create all the reaction instances of this reactor instance * and record the dependencies and antidependencies * between ports, actions, and timers and reactions. @@ -735,7 +735,7 @@ protected void createReactionInstances() { // Create the reaction instance. var reactionInstance = new ReactionInstance(reaction, this, unorderedReactions.contains(reaction), count++); - + // Add the reaction instance to the map of reactions for this // reactor. this.reactions.add(reactionInstance); @@ -748,15 +748,15 @@ protected void createReactionInstances() { */ protected TriggerInstance getOrCreateBuiltinTrigger(BuiltinTriggerRef trigger) { if (!builtinTriggers.containsKey(trigger.getType())) { - builtinTriggers.put(trigger.getType(), + builtinTriggers.put(trigger.getType(), new TriggerInstance<>(trigger.getType(), trigger, this)); } return builtinTriggers.get(trigger.getType()); } - + //////////////////////////////////////// //// Private constructors - + /** * Create a runtime instance from the specified definition * and with the specified parent that instantiated it. @@ -766,7 +766,7 @@ protected TriggerInstance getOrCreateBuiltinTrigger(BuiltinT * @param desiredDepth The depth to which to expand the hierarchy. */ private ReactorInstance( - Instantiation definition, + Instantiation definition, ReactorInstance parent, ErrorReporter reporter, int desiredDepth) { @@ -774,7 +774,7 @@ private ReactorInstance( this.reporter = reporter; this.reactorDeclaration = definition.getReactorClass(); this.reactorDefinition = ASTUtils.toDefinition(reactorDeclaration); - + // check for recursive instantiation var currentParent = parent; var foundSelfAsParent = false; @@ -788,21 +788,21 @@ private ReactorInstance( } } } while(currentParent != null); - + this.recursive = foundSelfAsParent; if (recursive) { reporter.reportError(definition, "Recursive reactor instantiation."); } - + // If the reactor definition is null, give up here. Otherwise, diagram generation // will fail an NPE. if (reactorDefinition == null) { reporter.reportError(definition, "Reactor instantiation has no matching reactor definition."); return; } - + setInitialWidth(); - + // Apply overrides and instantiate parameters for this reactor instance. for (Parameter parameter : ASTUtils.allParameters(reactorDefinition)) { this.parameters.add(new ParameterInstance(parameter, this)); @@ -824,9 +824,9 @@ private ReactorInstance( // While doing this, assign an index offset to each. for (Instantiation child : ASTUtils.allInstantiations(reactorDefinition)) { var childInstance = new ReactorInstance( - child, - this, - reporter, + child, + this, + reporter, desiredDepth ); this.children.add(childInstance); @@ -846,10 +846,10 @@ private ReactorInstance( // Create the reaction instances in this reactor instance. // This also establishes all the implied dependencies. - // Note that this can only happen _after_ the children, + // Note that this can only happen _after_ the children, // port, action, and timer instances have been created. createReactionInstances(); - + // Instantiate modes for this reactor instance // This must come after the child elements (reactions, etc) of this reactor // are created in order to allow their association with modes @@ -861,17 +861,17 @@ private ReactorInstance( } } } - + ////////////////////////////////////////////////////// //// Private methods. /** * Connect the given left port range to the given right port range. - * + * * NOTE: This method is public to enable its use in unit tests. * Otherwise, it should be private. This is why it is defined here, * in the section labeled "Private methods." - * + * * @param src The source range. * @param dst The destination range. * @param connection The connection establishing this relationship. @@ -901,7 +901,7 @@ private void establishPortConnections() { Iterator> srcRanges = leftPorts.iterator(); List> rightPorts = listPortInstances(connection.getRightPorts(), connection); Iterator> dstRanges = rightPorts.iterator(); - + // Check for empty lists. if (!srcRanges.hasNext()) { if (dstRanges.hasNext()) { @@ -912,7 +912,7 @@ private void establishPortConnections() { reporter.reportWarning(connection, "No destination. Outputs will be lost."); return; } - + RuntimeRange src = srcRanges.next(); RuntimeRange dst = dstRanges.next(); @@ -922,7 +922,7 @@ private void establishPortConnections() { if (!dstRanges.hasNext()) { if (srcRanges.hasNext()) { // Should not happen (checked by the validator). - reporter.reportWarning(connection, + reporter.reportWarning(connection, "Source is wider than the destination. Outputs will be lost."); } break; @@ -933,7 +933,7 @@ private void establishPortConnections() { } else { if (dstRanges.hasNext()) { // Should not happen (checked by the validator). - reporter.reportWarning(connection, + reporter.reportWarning(connection, "Destination is wider than the source. Inputs will be missing."); } break; @@ -947,7 +947,7 @@ private void establishPortConnections() { src = src.tail(dst.width); if (!dstRanges.hasNext()) { // Should not happen (checked by the validator). - reporter.reportWarning(connection, + reporter.reportWarning(connection, "Source is wider than the destination. Outputs will be lost."); break; } @@ -960,7 +960,7 @@ private void establishPortConnections() { if (connection.isIterated()) { srcRanges = leftPorts.iterator(); } else { - reporter.reportWarning(connection, + reporter.reportWarning(connection, "Destination is wider than the source. Inputs will be missing."); break; } @@ -970,7 +970,7 @@ private void establishPortConnections() { } } } - + /** * If path exists from the specified port to any reaction in the specified * set of reactions, then add the specified port and all ports along the path @@ -978,7 +978,7 @@ private void establishPortConnections() { * @return True if the specified port was added. */ private boolean findPaths( - PortInstance port, + PortInstance port, Set reactions, Set ports ) { @@ -1000,22 +1000,22 @@ private boolean findPaths( } return result; } - + /** * Given a list of port references, as found on either side of a connection, * return a list of the port instance ranges referenced. These may be multiports, * and may be ports of a contained bank (a port representing ports of the bank * members) so the returned list includes ranges of banks and channels. - * + * * If a given port reference has the form `interleaved(b.m)`, where `b` is * a bank and `m` is a multiport, then the corresponding range in the returned * list is marked interleaved. - * + * * For example, if `b` and `m` have width 2, without the interleaved keyword, * the returned range represents the sequence `[b0.m0, b0.m1, b1.m0, b1.m1]`. * With the interleaved marking, the returned range represents the sequence * `[b0.m0, b1.m0, b0.m1, b1.m1]`. Both ranges will have width 4. - * + * * @param references The variable references on one side of the connection. * @param connection The connection. */ @@ -1043,7 +1043,7 @@ private List> listPortInstances( if (reactor != null) { PortInstance portInstance = reactor.lookupPortInstance( (Port) portRef.getVariable()); - + Set interleaved = new LinkedHashSet<>(); if (portRef.isInterleaved()) { // NOTE: Here, we are assuming that the interleaved() @@ -1070,11 +1070,11 @@ private List> listPortInstances( portParentWidth = 1; } int widthBound = portWidth * portParentWidth; - + // If either of these widths cannot be determined, assume infinite. if (portWidth < 0) widthBound = Integer.MAX_VALUE; if (portParentWidth < 0) widthBound = Integer.MAX_VALUE; - + if (widthBound < range.width) { // Need to split the range. tails.add(range.tail(widthBound)); @@ -1096,7 +1096,7 @@ private List> listPortInstances( } // If the width cannot be determined, assume infinite. if (widthBound < 0) widthBound = Integer.MAX_VALUE; - + if (widthBound < tail.width) { // Need to split the range again moreTails.add(tail.tail(widthBound)); @@ -1122,7 +1122,7 @@ private void setInitialWidth() { width = ASTUtils.width(widthSpec, parent.instantiations()); } } - + ////////////////////////////////////////////////////// //// Private fields. @@ -1135,14 +1135,15 @@ private void setInitialWidth() { * Cached reaction graph containing reactions that form a causality loop. */ private ReactionInstanceGraph cachedReactionLoopGraph = null; - + /** * Return true if this is a generated delay reactor that originates from * an "after" delay on a connection. - * + * * @return True if this is a generated delay, false otherwise. */ public boolean isGeneratedDelay() { + // FIXME: hacky string matching again... if (this.definition.getReactorClass().getName().contains(DelayBodyGenerator.GEN_DELAY_CLASS_NAME)) { return true; } diff --git a/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java b/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java index e066c3752d..41172cabed 100644 --- a/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java @@ -1,10 +1,7 @@ package org.lflang.generator.c; -import org.lflang.ASTUtils; -import org.lflang.federated.generator.FederateInstance; import org.lflang.generator.CodeBuilder; import org.lflang.lf.Reactor; -import org.lflang.lf.ReactorDecl; /** * Generates C constructor code for a reactor. @@ -23,7 +20,7 @@ public static String generateConstructor( ) { var structType = CUtil.selfType(reactor); var code = new CodeBuilder(); - code.pr(structType+"* new_"+reactor.getName()+"() {"); + code.pr(structType+"* new_"+CUtil.getName(reactor)+"() {"); code.indent(); code.pr(structType+"* self = ("+structType+"*)_lf_new_reactor(sizeof("+structType+"));"); code.pr(constructorCode); diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index d98c73a343..26dfe5200a 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -25,8 +25,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY package org.lflang.generator.c; import static org.lflang.ASTUtils.allActions; -import static org.lflang.ASTUtils.allInputs; -import static org.lflang.ASTUtils.allOutputs; import static org.lflang.ASTUtils.allPorts; import static org.lflang.ASTUtils.allReactions; import static org.lflang.ASTUtils.allStateVars; @@ -37,9 +35,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import static org.lflang.ASTUtils.toText; import static org.lflang.util.StringUtil.addDoubleQuotes; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -90,7 +86,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import org.lflang.lf.Instantiation; import org.lflang.lf.Mode; import org.lflang.lf.Model; -import org.lflang.lf.Output; import org.lflang.lf.Port; import org.lflang.lf.Preamble; import org.lflang.lf.Reaction; @@ -100,7 +95,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import org.lflang.lf.Variable; import org.lflang.util.ArduinoUtil; import org.lflang.util.FileUtil; -import org.lflang.util.LFCommand; import com.google.common.base.Objects; import com.google.common.collect.Iterables; @@ -1101,7 +1095,7 @@ protected void generateConstructor( protected void generateIncludes(ReactorDecl decl) { if (CCppMode) code.pr("extern \"C\" {"); - code.pr("#include \"include/" + ASTUtils.toDefinition(decl).getName() + ".h\""); + code.pr("#include \"include/" + CUtil.getName(ASTUtils.toDefinition(decl)) + ".h\""); if (CCppMode) code.pr("}"); } @@ -1193,7 +1187,7 @@ private void generateSelfStruct(ReactorDecl decl, CodeBuilder constructorCode) { // Next, generate the fields needed for each reaction. CReactionGenerator.generateReactionAndTriggerStructs( body, - decl, + reactor, constructorCode, types ); @@ -1367,13 +1361,13 @@ protected void generateSelfStructExtension( * These functions have a single argument that is a void* pointing to * a struct that contains parameters, state variables, inputs (triggering or not), * actions (triggering or produced), and outputs. - * @param decl The reactor. + * @param r The reactor. */ - public void generateReactions(ReactorDecl decl) { + public void generateReactions(Reactor r) { var reactionIndex = 0; - var reactor = ASTUtils.toDefinition(decl); + var reactor = ASTUtils.toDefinition(r); for (Reaction reaction : allReactions(reactor)) { - generateReaction(reaction, decl, reactionIndex); + generateReaction(reaction, r, reactionIndex); // Increment reaction index even if the reaction is not in the federate // so that across federates, the reaction indices are consistent. reactionIndex++; @@ -1385,14 +1379,14 @@ public void generateReactions(ReactorDecl decl) { * a struct that contains parameters, state variables, inputs (triggering or not), * actions (triggering or produced), and outputs. * @param reaction The reaction. - * @param decl The reactor. + * @param r The reactor. * @param reactionIndex The position of the reaction within the reactor. */ - protected void generateReaction(Reaction reaction, ReactorDecl decl, int reactionIndex) { + protected void generateReaction(Reaction reaction, Reactor r, int reactionIndex) { code.pr(CReactionGenerator.generateReaction( reaction, - decl, + r, reactionIndex, mainDef, errorReporter, @@ -1641,7 +1635,7 @@ public void processProtoFile(String filename) { * @return The name of the self struct. */ public static String variableStructType(Variable variable, Reactor reactor) { - return reactor.getName().toLowerCase()+"_"+variable.getName()+"_t"; + return CUtil.getName(reactor)+"_"+variable.getName()+"_t"; } /** @@ -1653,7 +1647,7 @@ public static String variableStructType(Variable variable, Reactor reactor) { * @return The name of the self struct. */ public static String variableStructType(TriggerInstance portOrAction) { - return portOrAction.getParent().reactorDefinition.getName().toLowerCase()+"_"+portOrAction.getName()+"_t"; + return CUtil.getName(portOrAction.getParent().reactorDefinition)+"_"+portOrAction.getName()+"_t"; } /** @@ -1682,7 +1676,7 @@ public void generateReactorInstance(ReactorInstance instance) { "// ***** Start initializing " + fullName + " of class " + reactorClass.getName()); // Generate the instance self struct containing parameters, state variables, // and outputs (the "self" struct). - initializeTriggerObjects.pr(CUtil.reactorRefName(instance)+"["+CUtil.runtimeIndex(instance)+"] = new_"+reactorClass.getName()+"();"); + initializeTriggerObjects.pr(CUtil.reactorRefName(instance)+"["+CUtil.runtimeIndex(instance)+"] = new_"+CUtil.getName(reactorClass)+"();"); // Generate code to initialize the "self" struct in the // _lf_initialize_trigger_objects function. generateTraceTableEntries(instance); diff --git a/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java b/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java index a9329c6036..a4e3dba149 100644 --- a/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CMethodGenerator.java @@ -134,7 +134,7 @@ public static void signatures( * @return The function name for the method. */ private static String methodFunctionName(ReactorDecl reactor, Method method) { - return reactor.getName().toLowerCase() + "_method_" + method.getName(); + return CUtil.getName(ASTUtils.toDefinition(reactor)) + "_method_" + method.getName(); } /** diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index 64705fa5dc..8dc34fdde3 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -666,17 +666,16 @@ public static String generateOutputVariablesInReaction( * specified reactor and a trigger_t struct for each trigger (input, action, * timer, or output of a contained reactor). * @param body The place to put the code for the self struct. - * @param decl The reactor. + * @param reactor The reactor. * @param constructorCode The place to put the constructor code. */ public static void generateReactionAndTriggerStructs( CodeBuilder body, - ReactorDecl decl, + Reactor reactor, CodeBuilder constructorCode, CTypes types ) { var reactionCount = 0; - var reactor = ASTUtils.toDefinition(decl); // Iterate over reactions and create initialize the reaction_t struct // on the self struct. Also, collect a map from triggers to the reactions // that are triggered by that trigger. Also, collect a set of sources @@ -732,7 +731,7 @@ public static void generateReactionAndTriggerStructs( var deadlineFunctionPointer = "NULL"; if (reaction.getDeadline() != null) { // The following has to match the name chosen in generateReactions - var deadlineFunctionName = generateDeadlineFunctionName(decl, reactionCount); + var deadlineFunctionName = generateDeadlineFunctionName(reactor, reactionCount); deadlineFunctionPointer = "&" + deadlineFunctionName; } @@ -740,7 +739,7 @@ public static void generateReactionAndTriggerStructs( var STPFunctionPointer = "NULL"; if (reaction.getStp() != null) { // The following has to match the name chosen in generateReactions - var STPFunctionName = generateStpFunctionName(decl, reactionCount); + var STPFunctionName = generateStpFunctionName(reactor, reactionCount); STPFunctionPointer = "&" + STPFunctionName; } @@ -754,7 +753,7 @@ public static void generateReactionAndTriggerStructs( // self->_lf__reaction_"+reactionCount+".is_STP_violated = false; constructorCode.pr(reaction, String.join("\n", "self->_lf__reaction_"+reactionCount+".number = "+reactionCount+";", - "self->_lf__reaction_"+reactionCount+".function = "+CReactionGenerator.generateReactionFunctionName(decl, reactionCount)+";", + "self->_lf__reaction_"+reactionCount+".function = "+CReactionGenerator.generateReactionFunctionName(reactor, reactionCount)+";", "self->_lf__reaction_"+reactionCount+".self = self;", "self->_lf__reaction_"+reactionCount+".deadline_violation_handler = "+deadlineFunctionPointer+";", "self->_lf__reaction_"+reactionCount+".STP_handler = "+STPFunctionPointer+";", @@ -1032,12 +1031,12 @@ public static String generateLfModeTriggeredReactions( * a struct that contains parameters, state variables, inputs (triggering or not), * actions (triggering or produced), and outputs. * @param reaction The reaction. - * @param decl The reactor. + * @param r The reactor. * @param reactionIndex The position of the reaction within the reactor. */ public static String generateReaction( Reaction reaction, - ReactorDecl decl, + Reactor r, int reactionIndex, Instantiation mainDef, ErrorReporter errorReporter, @@ -1046,9 +1045,9 @@ public static String generateReaction( boolean requiresType ) { var code = new CodeBuilder(); - var body = ASTUtils.toText(getCode(types, reaction, decl)); + var body = ASTUtils.toText(getCode(types, reaction, r)); String init = generateInitializationForReaction( - body, reaction, ASTUtils.toDefinition(decl), reactionIndex, + body, reaction, ASTUtils.toDefinition(r), reactionIndex, types, errorReporter, mainDef, requiresType); @@ -1056,27 +1055,27 @@ public static String generateReaction( "#include " + StringUtil.addDoubleQuotes( CCoreFilesUtils.getCTargetSetHeader())); - CMethodGenerator.generateMacrosForMethods(ASTUtils.toDefinition(decl), code); + CMethodGenerator.generateMacrosForMethods(ASTUtils.toDefinition(r), code); code.pr(generateFunction( - generateReactionFunctionHeader(decl, reactionIndex), - init, getCode(types, reaction, decl) + generateReactionFunctionHeader(r, reactionIndex), + init, getCode(types, reaction, r) )); // Now generate code for the late function, if there is one // Note that this function can only be defined on reactions // in federates that have inputs from a logical connection. if (reaction.getStp() != null) { code.pr(generateFunction( - generateStpFunctionHeader(decl, reactionIndex), + generateStpFunctionHeader(r, reactionIndex), init, reaction.getStp().getCode())); } // Now generate code for the deadline violation function, if there is one. if (reaction.getDeadline() != null) { code.pr(generateFunction( - generateDeadlineFunctionHeader(decl, reactionIndex), + generateDeadlineFunctionHeader(r, reactionIndex), init, reaction.getDeadline().getCode())); } - CMethodGenerator.generateMacroUndefsForMethods(ASTUtils.toDefinition(decl), code); + CMethodGenerator.generateMacroUndefsForMethods(ASTUtils.toDefinition(r), code); code.pr( "#include " + StringUtil.addDoubleQuotes( CCoreFilesUtils.getCTargetSetUndefHeader())); @@ -1104,11 +1103,11 @@ public static String generateFunction(String header, String init, Code code) { /** * Returns the name of the deadline function for reaction. - * @param decl The reactor with the deadline + * @param r The reactor with the deadline * @param reactionIndex The number assigned to this reaction deadline */ - public static String generateDeadlineFunctionName(ReactorDecl decl, int reactionIndex) { - return CUtil.getName(decl).toLowerCase() + "_deadline_function" + reactionIndex; + public static String generateDeadlineFunctionName(Reactor r, int reactionIndex) { + return CUtil.getName(r).toLowerCase() + "_deadline_function" + reactionIndex; } /** @@ -1118,44 +1117,44 @@ public static String generateDeadlineFunctionName(ReactorDecl decl, int reaction * @param reactionIndex The reaction index. * @return The function name for the reaction. */ - public static String generateReactionFunctionName(ReactorDecl reactor, int reactionIndex) { + public static String generateReactionFunctionName(Reactor reactor, int reactionIndex) { return CUtil.getName(reactor).toLowerCase() + "reaction_function_" + reactionIndex; } /** * Returns the name of the stp function for reaction. - * @param decl The reactor with the stp + * @param r The reactor with the stp * @param reactionIndex The number assigned to this reaction deadline */ - public static String generateStpFunctionName(ReactorDecl decl, int reactionIndex) { - return CUtil.getName(decl).toLowerCase() + "_STP_function" + reactionIndex; + public static String generateStpFunctionName(Reactor r, int reactionIndex) { + return CUtil.getName(r).toLowerCase() + "_STP_function" + reactionIndex; } - /** Return the top level C function header for the deadline function numbered "reactionIndex" in "decl" - * @param decl The reactor declaration + /** Return the top level C function header for the deadline function numbered "reactionIndex" in "r" + * @param r The reactor declaration * @param reactionIndex The reaction index. * @return The function name for the deadline function. */ - public static String generateDeadlineFunctionHeader(ReactorDecl decl, + public static String generateDeadlineFunctionHeader(Reactor r, int reactionIndex) { - String functionName = generateDeadlineFunctionName(decl, reactionIndex); + String functionName = generateDeadlineFunctionName(r, reactionIndex); return generateFunctionHeader(functionName); } - /** Return the top level C function header for the reaction numbered "reactionIndex" in "decl" - * @param decl The reactor declaration + /** Return the top level C function header for the reaction numbered "reactionIndex" in "r" + * @param r The reactor declaration * @param reactionIndex The reaction index. * @return The function name for the reaction. */ - public static String generateReactionFunctionHeader(ReactorDecl decl, + public static String generateReactionFunctionHeader(Reactor r, int reactionIndex) { - String functionName = generateReactionFunctionName(decl, reactionIndex); + String functionName = generateReactionFunctionName(r, reactionIndex); return generateFunctionHeader(functionName); } - public static String generateStpFunctionHeader(ReactorDecl decl, + public static String generateStpFunctionHeader(Reactor r, int reactionIndex) { - String functionName = generateStpFunctionName(decl, reactionIndex); + String functionName = generateStpFunctionName(r, reactionIndex); return generateFunctionHeader(functionName); } diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index f1ce833281..a0f5f96d43 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -5,13 +5,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.lflang.InferredType; import org.lflang.generator.CodeBuilder; import org.lflang.lf.Parameter; import org.lflang.lf.Port; import org.lflang.lf.Reaction; import org.lflang.lf.Reactor; -import org.lflang.lf.ReactorDecl; import org.lflang.lf.StateVar; import org.lflang.lf.TriggerRef; import org.lflang.lf.TypedVariable; @@ -27,7 +25,7 @@ public interface GenerateAuxiliaryStructs { public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator) throws IOException { String contents = generateHeaderFile(types, r, generator); - FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(r.getName() + ".h")); + FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(CUtil.getName(r) + ".h")); } private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator) { CodeBuilder builder = new CodeBuilder(); @@ -43,7 +41,7 @@ private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxili } private static void appendIncludeGuard(CodeBuilder builder, Reactor r) { - String macro = r.getName().toUpperCase() + "_H"; + String macro = CUtil.getName(r) + "_H"; builder.pr("#ifndef " + macro); builder.pr("#define " + macro); } @@ -56,7 +54,7 @@ private static void appendPoundIncludes(CodeBuilder builder) { } private static String userFacingSelfType(Reactor r) { - return r.getName().toLowerCase() + "_self_t"; + return r.getName().toLowerCase() + r.hashCode() + "_self_t"; } private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { diff --git a/org.lflang/src/org/lflang/generator/c/CUtil.java b/org.lflang/src/org/lflang/generator/c/CUtil.java index 97f3e35d8f..69e9ec30ae 100644 --- a/org.lflang/src/org/lflang/generator/c/CUtil.java +++ b/org.lflang/src/org/lflang/generator/c/CUtil.java @@ -147,11 +147,12 @@ public static String channelIndexName(PortInstance port) { * reactor is main (to allow for instantiations that have the same name as * the main reactor or the .lf file). */ - public static String getName(ReactorDecl reactor) { - if (reactor instanceof Reactor r && r.isMain()) { - return reactor.getName() + "_main"; + public static String getName(Reactor reactor) { + String name = reactor.getName().toLowerCase() + reactor.hashCode(); + if (reactor.isMain()) { + return name + "_main"; } - return reactor.getName(); + return name; } /** @@ -517,9 +518,9 @@ public static String runtimeIndex(ReactorInstance reactor) { */ public static String selfType(Reactor reactor) { if (reactor.isMain()) { - return "_" + reactor.getName().toLowerCase() + "_main_self_t"; + return "_" + CUtil.getName(reactor) + "_main_self_t"; } - return "_" + reactor.getName().toLowerCase() + "_self_t"; + return "_" + CUtil.getName(reactor) + "_self_t"; } /** Construct a unique type for the "self" struct of the class of the given reactor. */ diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 76fffe7c00..7f6c0412e8 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -457,16 +457,16 @@ protected PythonDockerGenerator getDockerGenerator(LFGeneratorContext context) { * a struct that contains parameters, state variables, inputs (triggering or not), * actions (triggering or produced), and outputs. * @param reaction The reaction. - * @param decl The reactor. + * @param r The reactor. * @param reactionIndex The position of the reaction within the reactor. */ @Override - protected void generateReaction(Reaction reaction, ReactorDecl decl, int reactionIndex) { - Reactor reactor = ASTUtils.toDefinition(decl); + protected void generateReaction(Reaction reaction, Reactor r, int reactionIndex) { + Reactor reactor = ASTUtils.toDefinition(r); // Reactions marked with a `@_c_body` attribute are generated in C if (AttributeUtils.hasCBody(reaction)) { - super.generateReaction(reaction, decl, reactionIndex); + super.generateReaction(reaction, r, reactionIndex); return; } code.pr(PythonReactionGenerator.generateCReaction(reaction, reactor, reactionIndex, mainDef, errorReporter, types)); diff --git a/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java index b3b87cdcb6..bcc1beeaed 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonReactionGenerator.java @@ -34,46 +34,46 @@ public class PythonReactionGenerator { /** - * Generate code to call reaction numbered "reactionIndex" in reactor "decl". - * @param decl The reactor containing the reaction + * Generate code to call reaction numbered "reactionIndex" in reactor "reactor". + * @param reactor The reactor containing the reaction * @param reactionIndex The index of the reaction * @param pyObjects CPython related objects */ - public static String generateCPythonReactionCaller(ReactorDecl decl, + public static String generateCPythonReactionCaller(Reactor reactor, int reactionIndex, List pyObjects, String inits) { String pythonFunctionName = generatePythonReactionFunctionName(reactionIndex); String cpythonFunctionName = generateCPythonReactionFunctionName(reactionIndex); - return generateCPythonFunctionCaller(decl.getName(), pythonFunctionName, cpythonFunctionName, pyObjects, inits); + return generateCPythonFunctionCaller(CUtil.getName(reactor), pythonFunctionName, cpythonFunctionName, pyObjects, inits); } /** - * Generate code to call deadline function numbered "reactionIndex" in reactor "decl". - * @param decl The reactor containing the reaction + * Generate code to call deadline function numbered "reactionIndex" in reactor "r". + * @param r The reactor containing the reaction * @param reactionIndex The index of the reaction * @param pyObjects CPython related objects */ - public static String generateCPythonDeadlineCaller(ReactorDecl decl, + public static String generateCPythonDeadlineCaller(Reactor r, int reactionIndex, List pyObjects) { String pythonFunctionName = generatePythonDeadlineFunctionName(reactionIndex); String cpythonFunctionName = generateCPythonDeadlineFunctionName(reactionIndex); - return generateCPythonFunctionCaller(decl.getName(), pythonFunctionName, cpythonFunctionName, pyObjects, ""); + return generateCPythonFunctionCaller(CUtil.getName(r), pythonFunctionName, cpythonFunctionName, pyObjects, ""); } /** - * Generate code to call deadline function numbered "reactionIndex" in reactor "decl". - * @param decl The reactor containing the reaction + * Generate code to call deadline function numbered "reactionIndex" in reactor "r". + * @param r The reactor containing the reaction * @param reactionIndex The index of the reaction * @param pyObjects CPython related objects */ - public static String generateCPythonSTPCaller(ReactorDecl decl, + public static String generateCPythonSTPCaller(Reactor r, int reactionIndex, List pyObjects) { String pythonFunctionName = generatePythonSTPFunctionName(reactionIndex); String cpythonFunctionName = generateCPythonSTPFunctionName(reactionIndex); - return generateCPythonFunctionCaller(decl.getName(), pythonFunctionName, cpythonFunctionName, pyObjects, ""); + return generateCPythonFunctionCaller(CUtil.getName(r), pythonFunctionName, cpythonFunctionName, pyObjects, ""); } /** diff --git a/org.lflang/src/org/lflang/generator/python/PythonReactorGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonReactorGenerator.java index 5778791f76..fd954ca956 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonReactorGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonReactorGenerator.java @@ -34,7 +34,7 @@ public static String generatePythonClass(ReactorInstance instance, CodeBuilder pythonClasses = new CodeBuilder(); ReactorDecl decl = instance.getDefinition().getReactorClass(); Reactor reactor = ASTUtils.toDefinition(decl); - String className = PyUtil.getName(decl); + String className = PyUtil.getName(reactor); if (instantiatedClasses == null) { return ""; } @@ -113,7 +113,7 @@ public static String generatePythonClassInstantiations(ReactorInstance instance, ReactorInstance main) { CodeBuilder code = new CodeBuilder(); - String className = PyUtil.getName(instance.reactorDeclaration); + String className = PyUtil.getName(instance.reactorDefinition); if (instance.getWidth() > 0) { // For each reactor instance, create a list regardless of whether it is a bank or not. diff --git a/org.lflang/src/org/lflang/validation/LFValidator.java b/org.lflang/src/org/lflang/validation/LFValidator.java index c78c12ce91..acb7b8fe00 100644 --- a/org.lflang/src/org/lflang/validation/LFValidator.java +++ b/org.lflang/src/org/lflang/validation/LFValidator.java @@ -199,9 +199,9 @@ public void checkConnection(Connection connection) { 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())) + if ((lp.getContainer() == null && it.getDefinition().equals(lp.getVariable())) || (it.getDefinition().equals(lp.getVariable()) && it.getParent().equals(lp.getContainer()))) { leftInCycle = true; break; @@ -209,7 +209,7 @@ public void checkConnection(Connection connection) { } for (NamedInstance it : cycles) { - if ((rp.getContainer() == null && it.getDefinition().equals(rp.getVariable())) + 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); @@ -485,7 +485,7 @@ public void checkInstantiation(Instantiation instantiation) { for (Reactor r : cycle) { names.add(r.getName()); } - + error( "Instantiation is part of a cycle: " + String.join(", ", names) + ".", Literals.INSTANTIATION__REACTOR_CLASS @@ -538,12 +538,12 @@ public void checkKeyValuePair(KeyValuePair param) { // Report problem with the assigned value. prop.type.check(param.getValue(), param.getName(), this); } - + for (String it : targetPropertyErrors) { error(it, Literals.KEY_VALUE_PAIR__VALUE); } targetPropertyErrors.clear(); - + for (String it : targetPropertyWarnings) { error(it, Literals.KEY_VALUE_PAIR__VALUE); } @@ -639,7 +639,7 @@ public void checkParameter(Parameter param) { TimeValue.MAX_LONG_DEADLINE + " nanoseconds.", Literals.PARAMETER__INIT); } - + } @Check(CheckType.FAST) @@ -666,7 +666,7 @@ public void checkPreamble(Preamble preamble) { } } else if (preamble.getVisibility() != Visibility.NONE) { warning( - String.format("The %s qualifier has no meaning for the %s target. It should be removed.", + String.format("The %s qualifier has no meaning for the %s target. It should be removed.", preamble.getVisibility(), this.target.name()), Literals.PREAMBLE__VISIBILITY ); @@ -957,12 +957,12 @@ public void checkSerializer(Serializer serializer) { for (SupportedSerializers method : SupportedSerializers.values()) { if (method.name().equalsIgnoreCase(serializer.getType())){ isValidSerializer = true; - } + } } - + if (!isValidSerializer) { error( - "Serializer can be " + Arrays.asList(SupportedSerializers.values()), + "Serializer can be " + Arrays.asList(SupportedSerializers.values()), Literals.SERIALIZER__TYPE ); } @@ -1193,7 +1193,7 @@ public void checkVarRef(VarRef varRef) { /** * Check whether an attribute is supported * and the validity of the attribute. - * + * * @param attr The attribute being checked */ @Check(CheckType.FAST) @@ -1233,7 +1233,7 @@ public void checkWidthSpec(WidthSpec widthSpec) { } } } - + @Check(CheckType.FAST) public void checkReactorIconAttribute(Reactor reactor) { var path = AttributeUtils.getIconPath(reactor); @@ -1248,7 +1248,7 @@ public void checkReactorIconAttribute(Reactor reactor) { param, Literals.ATTR_PARM__VALUE); return; } - + // Check file location var iconLocation = FileUtil.locateFile(path, reactor.eResource()); if (iconLocation == null) { @@ -1362,7 +1362,7 @@ public void checkMissingStateResetInMode(Reactor reactor) { if (!m.getStateVars().isEmpty()) { var hasResetReaction = m.getReactions().stream().anyMatch( r -> r.getTriggers().stream().anyMatch( - t -> (t instanceof BuiltinTriggerRef && + t -> (t instanceof BuiltinTriggerRef && ((BuiltinTriggerRef) t).getType() == BuiltinTrigger.RESET))); if (!hasResetReaction) { for (var s : m.getStateVars()) { @@ -1386,7 +1386,7 @@ public void checkMissingStateResetInMode(Reactor reactor) { if (!check.getStateVars().isEmpty()) { var hasResetReaction = check.getReactions().stream().anyMatch( r -> r.getTriggers().stream().anyMatch( - t -> (t instanceof BuiltinTriggerRef && + t -> (t instanceof BuiltinTriggerRef && ((BuiltinTriggerRef) t).getType() == BuiltinTrigger.RESET))); if (!hasResetReaction) { // Add state vars that are not self-resetting to the error @@ -1403,10 +1403,10 @@ public void checkMissingStateResetInMode(Reactor reactor) { } if (!error.isEmpty()) { error("This reactor contains state variables that are not reset upon mode entry: " - + error.stream().map(e -> e.getName() + " in " + + error.stream().map(e -> e.getName() + " in " + ASTUtils.getEnclosingReactor(e).getName()).collect(Collectors.joining(", ")) + ".\nThe state variables are neither marked for automatic reset nor have a dedicated reset reaction. " - + "It is usafe to instatiate this reactor inside a mode entered with reset.", + + "It is unsafe to instantiate this reactor inside a mode entered with reset.", m, Literals.MODE__INSTANTIATIONS, m.getInstantiations().indexOf(i)); } @@ -1429,12 +1429,12 @@ public void checkUnspecifiedTransitionType(Reaction reaction) { var variable = effect.getVariable(); if (variable instanceof Mode) { // The transition type is always set to default by Xtext. - // Hence, check if there is an explicit node for the transition type in the AST. + // Hence, check if there is an explicit node for the transition type in the AST. var transitionAssignment = NodeModelUtils.findNodesForFeature((EObject) effect, Literals.VAR_REF__TRANSITION); if (transitionAssignment.isEmpty()) { // Transition type not explicitly specified. var mode = (Mode) variable; // Check if reset or history transition would make a difference. - var makesDifference = !mode.getStateVars().isEmpty() + var makesDifference = !mode.getStateVars().isEmpty() || !mode.getTimers().isEmpty() || !mode.getActions().isEmpty() || mode.getConnections().stream().anyMatch(c -> c.getDelay() != null); @@ -1447,13 +1447,13 @@ public void checkUnspecifiedTransitionType(Reaction reaction) { while (!toCheck.isEmpty() && !makesDifference) { var check = toCheck.pop(); checked.add(check); - + makesDifference |= !check.getModes().isEmpty() - || !ASTUtils.allStateVars(check).isEmpty() + || !ASTUtils.allStateVars(check).isEmpty() || !ASTUtils.allTimers(check).isEmpty() || !ASTUtils.allActions(check).isEmpty() || ASTUtils.allConnections(check).stream().anyMatch(c -> c.getDelay() != null); - + // continue with inner for (var innerInstance : check.getInstantiations()) { var next = (Reactor) innerInstance.getReactorClass(); @@ -1849,5 +1849,5 @@ private boolean sameType(Type type1, Type type2) { + "state, reactor definitions, and reactor instantiation) may not start with \"__\": "; private static String USERNAME_REGEX = "^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\\$)$"; - + } From faa94086316d4de750633e312e5458bbe2b390cc Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Feb 2023 23:12:19 -0800 Subject: [PATCH 23/92] Factor reactor code out into separate files. --- .../compiler/LinguaFrancaValidationTest.java | 252 +++++++++--------- .../generator/c/CConstructorGenerator.java | 4 + .../org/lflang/generator/c/CGenerator.java | 89 ++++--- .../c/CReactorHeaderFileGenerator.java | 11 +- .../generator/python/PythonGenerator.java | 6 +- .../org/lflang/validation/LFValidator.java | 2 +- 6 files changed, 187 insertions(+), 177 deletions(-) diff --git a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java index 4c0d5dee08..1de537956d 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java @@ -13,15 +13,15 @@ this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************/ package org.lflang.tests.compiler; @@ -63,7 +63,7 @@ /** * Collection of unit tests to ensure validation is done correctly. - * + * * @author Edward A. Lee * @author Marten Lohstroh * @author Matt Weber @@ -71,7 +71,7 @@ * @author Alexander Schulz-Rosengarten */ public class LinguaFrancaValidationTest { - @Inject + @Inject ParseHelper parser; @Inject @@ -99,7 +99,7 @@ private Model parseWithError(String s) throws Exception { Assertions.assertNotNull(model); Assertions.assertFalse(model.eResource().getErrors().isEmpty()); return model; - } + } /** * Ensure that duplicate identifiers for actions reported. @@ -121,15 +121,15 @@ public void duplicateVariable() throws Exception { " logical action bar;", " physical action bar;", "}"); - validator.assertError(parseWithoutError(testCase), - LfPackage.eINSTANCE.getAction(), - null, + validator.assertError(parseWithoutError(testCase), + LfPackage.eINSTANCE.getAction(), + null, "Duplicate Variable 'bar' in Reactor 'Foo'"); } /** - * Check that reactors in C++ cannot be named preamble + * Check that reactors in C++ cannot be named preamble */ @Test public void disallowReactorCalledPreamble() throws Exception { @@ -142,11 +142,11 @@ public void disallowReactorCalledPreamble() throws Exception { // Java 11: Model model_no_errors = parser.parse(String.join( System.getProperty("line.separator"), - "target Cpp;", + "target Cpp;", "main reactor {", "}" )); - + // Java 17: // Model model_error_1 = """ // target Cpp; @@ -156,7 +156,7 @@ public void disallowReactorCalledPreamble() throws Exception { // Java 11: Model model_error_1 = parser.parse(String.join( System.getProperty("line.separator"), - "target Cpp;", + "target Cpp;", "main reactor Preamble {", "}" )); @@ -172,30 +172,30 @@ public void disallowReactorCalledPreamble() throws Exception { // Java 11: Model model_error_2 = parser.parse(String.join( System.getProperty("line.separator"), - "target Cpp;", + "target Cpp;", "reactor Preamble {", "}", "main reactor Main {", "}" )); - + Assertions.assertNotNull(model_no_errors); Assertions.assertNotNull(model_error_1); Assertions.assertNotNull(model_error_2); - Assertions.assertTrue(model_no_errors.eResource().getErrors().isEmpty(), + Assertions.assertTrue(model_no_errors.eResource().getErrors().isEmpty(), "Encountered unexpected error while parsing: " + model_no_errors.eResource().getErrors()); - Assertions.assertTrue(model_error_1.eResource().getErrors().isEmpty(), + Assertions.assertTrue(model_error_1.eResource().getErrors().isEmpty(), "Encountered unexpected error while parsing: " + model_error_1.eResource().getErrors()); - Assertions.assertTrue(model_error_2.eResource().getErrors().isEmpty(), + Assertions.assertTrue(model_error_2.eResource().getErrors().isEmpty(), "Encountered unexpected error while parsing: " + model_error_2.eResource().getErrors()); validator.assertNoIssues(model_no_errors); - validator.assertError(model_error_1, - LfPackage.eINSTANCE.getReactor(), + validator.assertError(model_error_1, + LfPackage.eINSTANCE.getReactor(), null, "Reactor cannot be named 'Preamble'"); - validator.assertError(model_error_2, - LfPackage.eINSTANCE.getReactor(), + validator.assertError(model_error_2, + LfPackage.eINSTANCE.getReactor(), null, "Reactor cannot be named 'Preamble'"); } @@ -222,7 +222,7 @@ public void disallowUnderscoreInputs() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getInput(), null, "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __bar"); } - + @Test public void disallowMainWithDifferentNameThanFile() throws Exception { // Java 17: @@ -239,7 +239,7 @@ public void disallowMainWithDifferentNameThanFile() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getReactor(), null, "Name of main reactor must match the file name (or be omitted)"); } - + /** * Ensure that "__" is not allowed at the start of an output name. @@ -283,9 +283,9 @@ public void disallowUnderscoreActions() throws Exception { " logical action __bar;", "}"); validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getAction(), null, - "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __bar"); + "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __bar"); } - + /** * Ensure that "__" is not allowed at the start of a timer name. */ @@ -305,9 +305,9 @@ public void disallowUnderscoreTimers() throws Exception { " timer __bar(0);", "}"); validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getTimer(), null, - "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __bar"); + "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __bar"); } - + /** * Ensure that "__" is not allowed at the start of a parameter name. */ @@ -327,7 +327,7 @@ public void disallowUnderscoreParameters() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getParameter(), null, "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __bar"); } - + /** * Ensure that "__" is not allowed at the start of an state name. */ @@ -349,7 +349,7 @@ public void disallowUnderscoreStates() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getStateVar(), null, "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __bar"); } - + /** * Ensure that "__" is not allowed at the start of a reactor definition name. */ @@ -369,7 +369,7 @@ public void disallowUnderscoreReactorDef() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getReactor(), null, "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __Foo"); } - + /** * Ensure that "__" is not allowed at the start of a reactor instantiation name. */ @@ -395,7 +395,7 @@ public void disallowUnderscoreReactorInstantiation() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getInstantiation(), null, "Names of objects (inputs, outputs, actions, timers, parameters, state, reactor definitions, and reactor instantiation) may not start with \"__\": __x"); } - + /** * Disallow connection to port that is effect of reaction. */ @@ -411,7 +411,7 @@ public void connectionToEffectPort() throws Exception { // output out:int; // x = new Foo(); // x.out -> out; -// reaction(startup) -> out {= +// reaction(startup) -> out {= // =} // } // """ @@ -431,7 +431,7 @@ public void connectionToEffectPort() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getConnection(), null, "Cannot connect: Port named 'out' is already effect of a reaction."); } - + /** * Disallow connection to port that is effect of reaction. */ @@ -450,7 +450,7 @@ public void connectionToEffectPort2() throws Exception { // y = new Foo(); // // y.out -> x.inp; -// reaction(startup) -> x.inp {= +// reaction(startup) -> x.inp {= // =} // } // """ @@ -467,13 +467,13 @@ public void connectionToEffectPort2() throws Exception { " y = new Foo();", "", " y.out -> x.inp;", - " reaction(startup) -> x.inp {=", + " reaction(startup) -> x.inp {=", " =}", "}"); validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getConnection(), null, "Cannot connect: Port named 'inp' is already effect of a reaction."); } - + /** * Allow connection to the port of a contained reactor if another port with same name is effect of a reaction. */ @@ -561,7 +561,7 @@ public void connectionToEffectPort4() throws Exception { // Java 17: // String testCase = """ // target C; - + // reactor Foo { // input in:int; // } @@ -654,8 +654,8 @@ public void detectInstantiationCycle() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getInstantiation(), null, "Instantiation is part of a cycle: Contained"); } - - + + /** * Detect cycles in the instantiation graph. */ @@ -675,7 +675,7 @@ public void detectInstantiationCycle2() throws Exception { // Java 11: Model model = parseWithoutError(String.join( System.getProperty("line.separator"), - "target C;", + "target C;", "reactor Intermediate {", " x = new Contained();", "}", @@ -689,7 +689,7 @@ public void detectInstantiationCycle2() throws Exception { validator.assertError(model, LfPackage.eINSTANCE.getInstantiation(), null, "Instantiation is part of a cycle: Intermediate, Contained."); } - + /** * Detect causality loop. */ @@ -716,7 +716,7 @@ public void detectCausalityLoop() throws Exception { // Java 11: Model model = parseWithoutError(String.join( System.getProperty("line.separator"), - "target C;", + "target C;", "", "reactor X {", " input x:int;", @@ -735,9 +735,9 @@ public void detectCausalityLoop() throws Exception { validator.assertError(model, LfPackage.eINSTANCE.getReaction(), null, "Reaction triggers involved in cyclic dependency in reactor X: x."); validator.assertError(model, LfPackage.eINSTANCE.getReaction(), - null, "Reaction effects involved in cyclic dependency in reactor X: y."); + null, "Reaction effects involved in cyclic dependency in reactor X: y."); } - + /** * Let cyclic dependencies be broken by "after" clauses. */ @@ -746,14 +746,14 @@ public void afterBreaksCycle() throws Exception { // Java 17: // String testCase = """ // target C -// +// // reactor X { // input x:int; // output y:int; // reaction(x) -> y {= // =} // } -// +// // main reactor { // a = new X() // b = new X() @@ -790,14 +790,14 @@ public void afterBreaksCycle2() throws Exception { // Java 17: // String testCase = """ // target C -// +// // reactor X { // input x:int; // output y:int; // reaction(x) -> y {= // =} // } -// +// // main reactor { // a = new X() // b = new X() @@ -835,14 +835,14 @@ public void afterBreaksCycle3() throws Exception { // Java 17: // String testCase = """ // target C -// +// // reactor X { // input x:int; // output y:int; // reaction(x) -> y {= // =} // } -// +// // main reactor { // a = new X() // b = new X() @@ -878,14 +878,14 @@ public void nonzeroAfterMustHaveUnits() throws Exception { // Java 17: // String testCase = """ // target C -// +// // reactor X { // input x:int; // output y:int; // reaction(x) -> y {= // =} // } -// +// // main reactor { // a = new X() // b = new X() @@ -913,7 +913,7 @@ public void nonzeroAfterMustHaveUnits() throws Exception { } - + /** * Report non-zero time value without units. */ @@ -939,8 +939,8 @@ public void nonZeroTimeValueWithoutUnits() throws Exception { " =}", "}"); validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getTimer(), null, "Missing time unit."); - } - + } + /** * Report reference to non-time parameter in time argument. */ @@ -968,7 +968,7 @@ public void parameterTypeMismatch() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getTimer(), null, "Referenced parameter is not of time type."); } - + /** * Report inappropriate literal in time argument. */ @@ -995,8 +995,8 @@ public void targetCodeInTimeArgument() throws Exception { "}"); validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getTimer(), null, "Invalid time value."); - } - + } + /** * Report overflowing deadline. @@ -1027,9 +1027,9 @@ public void overflowingDeadlineC() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getDeadline(), null, "Deadline exceeds the maximum of " + TimeValue.MAX_LONG_DEADLINE + " nanoseconds."); - } + } + - /** * Report overflowing parameter. */ @@ -1059,9 +1059,9 @@ public void overflowingParameterC() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getParameter(), null, "Time value used to specify a deadline exceeds the maximum of " + TimeValue.MAX_LONG_DEADLINE + " nanoseconds."); - } - - + } + + /** * Report overflowing assignment. */ @@ -1097,7 +1097,7 @@ public void overflowingAssignmentC() throws Exception { validator.assertError(parseWithoutError(testCase), LfPackage.eINSTANCE.getAssignment(), null, "Time value used to specify a deadline exceeds the maximum of " + TimeValue.MAX_LONG_DEADLINE + " nanoseconds."); - } + } /** * Report missing trigger. @@ -1124,9 +1124,9 @@ public void missingTrigger() throws Exception { validator.assertWarning(parseWithoutError(testCase), LfPackage.eINSTANCE.getReaction(), null, "Reaction has no trigger."); } - + /** - * Test warnings and errors for the target dependent preamble visibility qualifiers + * Test warnings and errors for the target dependent preamble visibility qualifiers */ @Test public void testPreambleVisibility() throws Exception { @@ -1171,15 +1171,15 @@ public void testPreambleVisibility() throws Exception { String.format("target %s;", target), "reactor Foo {", "}")); - + validator.assertNoIssues(model_no_preamble); - + if (target == Target.CPP) { if (visibility == Visibility.NONE) { validator.assertError(model_file_scope, LfPackage.eINSTANCE.getPreamble(), null, "Preambles for the C++ target need a visibility qualifier (private or public)!"); validator.assertError(model_reactor_scope, LfPackage.eINSTANCE.getPreamble(), null, - "Preambles for the C++ target need a visibility qualifier (private or public)!"); + "Preambles for the C++ target need a visibility qualifier (private or public)!"); } else { validator.assertNoIssues(model_file_scope); validator.assertNoIssues(model_reactor_scope); @@ -1198,8 +1198,8 @@ public void testPreambleVisibility() throws Exception { } } } - - + + /** * Tests for state and parameter declarations, including native lists. */ @@ -1212,7 +1212,7 @@ public void stateAndParameterDeclarationsInC() throws Exception { // b:int, // ERROR: uninitialized // t:time(42), // ERROR: units missing // x:int(0), -// h:time("bla"), // ERROR: not a type +// h:time("bla"), // ERROR: not a type // q:time(1 msec, 2 msec), // ERROR: not a list // y:int(t) // ERROR: init using parameter // ) { @@ -1261,9 +1261,9 @@ public void stateAndParameterDeclarationsInC() throws Exception { "Invalid time value."); validator.assertError(model, LfPackage.eINSTANCE.getTimer(), null, "Missing time unit."); - } - - + } + + /** * Recognize valid IPV4 addresses, report invalid ones. */ @@ -1280,7 +1280,7 @@ public void recognizeIPV4() throws Exception { // target C; // reactor Y {} // federated reactor X at foo@%s:4242 { -// y = new Y() at %s:2424; +// y = new Y() at %s:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1301,7 +1301,7 @@ public void recognizeIPV4() throws Exception { // target C; // reactor Y {} // federated reactor X at foo@%s:4242 { -// y = new Y() at %s:2424; +// y = new Y() at %s:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1322,7 +1322,7 @@ public void recognizeIPV4() throws Exception { // target C; // reactor Y {} // federated reactor X at foo@%s:4242 { -// y = new Y() at %s:2424; +// y = new Y() at %s:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1337,7 +1337,7 @@ public void recognizeIPV4() throws Exception { validator.assertWarning(model, LfPackage.eINSTANCE.getHost(), null, "Invalid IP address."); } } - + /** * Recognize valid IPV6 addresses, report invalid ones. */ @@ -1355,14 +1355,14 @@ public void recognizeIPV6() throws Exception { "::ffff:0.0.0.0", "::ffff:1.2.3.4", "::ffff:10.0.0.1", "1:2:3:4:5:6:77:88", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "2001:db8:3:4::192.0.2.33", "64:ff9b::192.0.2.33", "0:0:0:0:0:0:10.0.0.1"); - + List validationError = List.of("1:2:3:4:5:6:7:8:9", "1:2:3:4:5:6::7:8", "1:2:3:4:5:6:7:8:", "::1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7:8::", "1:2:3:4:5:6:7:88888", "2001:db8:3:4:5::192.0.2.33", "fe08::7:8interface", "fe08::7:8interface", "fe08::7:8i"); - + List parseError = List.of("fe08::7:8%", ":1:2:3:4:5:6:7:8"); - + // Correct IP addresses. for (String addr : correct) { // Java 17: @@ -1370,7 +1370,7 @@ public void recognizeIPV6() throws Exception { // target C; // reactor Y {} // federated reactor X at [foo@%s]:4242 { -// y = new Y() at [%s]:2424; +// y = new Y() at [%s]:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1385,7 +1385,7 @@ public void recognizeIPV6() throws Exception { validator.assertNoIssues(model); } - + // IP addresses that don't parse. for (String addr : parseError) { // Java 17: @@ -1393,7 +1393,7 @@ public void recognizeIPV6() throws Exception { // target C; // reactor Y {} // federated reactor X at [foo@%s]:4242 { -// y = new Y() at [%s]:2424; +// y = new Y() at [%s]:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1414,7 +1414,7 @@ public void recognizeIPV6() throws Exception { // target C; // reactor Y {} // federated reactor X at [foo@%s]:4242 { -// y = new Y() at [%s]:2424; +// y = new Y() at [%s]:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1429,17 +1429,17 @@ public void recognizeIPV6() throws Exception { validator.assertWarning(model, LfPackage.eINSTANCE.getHost(), null, "Invalid IP address."); } } - + /** * Recognize valid host names and fully qualified names, report invalid ones. */ @Test public void recognizeHostNames() throws Exception { - + List correct = List.of("localhost"); // FIXME: add more - + List validationError = List.of("x.y.z"); // FIXME: add more - + List parseError = List.of("..xyz"); // FIXME: add more @@ -1450,7 +1450,7 @@ public void recognizeHostNames() throws Exception { // target C; // reactor Y {} // federated reactor X at foo@%s:4242 { -// y = new Y() at %s:2424; +// y = new Y() at %s:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1463,7 +1463,7 @@ public void recognizeHostNames() throws Exception { "}") ); } - + // Names that don't parse. for (String addr : parseError) { // Java 17: @@ -1471,7 +1471,7 @@ public void recognizeHostNames() throws Exception { // target C; // reactor Y {} // federated reactor X at foo@%s:4242 { -// y = new Y() at %s:2424; +// y = new Y() at %s:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1484,7 +1484,7 @@ public void recognizeHostNames() throws Exception { "}") ); } - + // Names that parse but are invalid. for (String addr : validationError) { // Java 17: @@ -1492,7 +1492,7 @@ public void recognizeHostNames() throws Exception { // target C; // reactor Y {} // federated reactor X at foo@%s:4242 { -// y = new Y() at %s:2424; +// y = new Y() at %s:2424; // } // """.formatted(addr, addr); // Java 11: @@ -1504,11 +1504,11 @@ public void recognizeHostNames() throws Exception { String.format(" y = new Y() at %s:2424; ", addr), "}") ); - validator.assertWarning(model, LfPackage.eINSTANCE.getHost(), null, + validator.assertWarning(model, LfPackage.eINSTANCE.getHost(), null, "Invalid host name or fully qualified domain name."); } } - + /** * Maps a type to a list of known good values. */ @@ -1533,7 +1533,7 @@ public void recognizeHostNames() throws Exception { ); /** - * Maps a type to a list, each entry of which represents a list with + * Maps a type to a list, each entry of which represents a list with * three entries: a known wrong value, the suffix to add to the reported * name, and the type that it should be. */ @@ -1575,9 +1575,9 @@ public void recognizeHostNames() throws Exception { List.of("{trace-file-name: [1, 2, 3]}", ".trace-file-name", PrimitiveType.STRING) ) ); - + /** - * Given an array type, return a list of good or bad examples, + * Given an array type, return a list of good or bad examples, * depending on the value of the second parameter. */ private List synthesizeExamples(ArrayType type, boolean correct) { @@ -1592,9 +1592,9 @@ private List synthesizeExamples(ArrayType type, boolean correct) { } return examples; } - + /** - * Given an union type, return a list of good or bad examples, + * Given an union type, return a list of good or bad examples, * depending on the value of the second parameter. */ private List synthesizeExamples(UnionType type, boolean correct) { @@ -1616,14 +1616,14 @@ private List synthesizeExamples(UnionType type, boolean correct) { } return examples; } - + /** - * Given an union type, return a list of good or bad examples, + * Given an union type, return a list of good or bad examples, * depending on the value of the second parameter. */ private List synthesizeExamples(DictionaryType type, boolean correct) { List examples = new LinkedList<>(); - // Produce a set of singleton dictionaries. + // Produce a set of singleton dictionaries. // If incorrect examples are wanted, garble the key. for (DictionaryElement option : type.options) { synthesizeExamples(option.getType(), correct).forEach(it -> examples.add("{" + option + (!correct ? "iamwrong: " : ": ") + it + "}")); @@ -1649,17 +1649,17 @@ private List synthesizeExamples(StringDictionaryType type, boolean corre } return examples; } - + /** * Synthesize a list of values that either conform to the given type or * do not, depending on whether the second argument 'correct' is true. - * Return an empty set if it is too complicated to generate examples + * Return an empty set if it is too complicated to generate examples * (e.g., because the resulting errors are more sophisticated). - * + * * Not all cases are covered by this function. Currently, the only cases not * covered are known bad examples for composite types, which should be added * to the compositeTypeToKnownBad map. - * + * * @param correct True to synthesize correct examples automatically, otherwise * synthesize incorrect examples. */ @@ -1684,7 +1684,7 @@ private List synthesizeExamples(TargetPropertyType type, boolean correct } return new LinkedList<>(); } - + /** * Create an LF program with the given key and value as a target property, * parse it, and return the resulting model. @@ -1697,7 +1697,7 @@ private Model createModel(TargetProperty key, String value) throws Exception { // target %s {%s: %s}; // reactor Y {} // main reactor { -// y = new Y() +// y = new Y() // } // """.formatted(target, key, value); // Java 11: @@ -1723,7 +1723,7 @@ public void checkTargetProperties() throws Exception { System.out.println("===="); System.out.println("Known good assignments:"); List knownCorrect = synthesizeExamples(prop.type, true); - + for (String it : knownCorrect) { Model model = createModel(prop, it); validator.assertNoErrors(model); @@ -1733,7 +1733,7 @@ public void checkTargetProperties() throws Exception { null, String.format("Could not find file: '%s'.", StringUtil.removeQuotes(it))); } } - + // Extra checks for filenames. (This piece of code was commented out in the original xtend file) // Temporarily disabled because we need a more sophisticated check that looks for files in different places. // if (prop.type == prop.type == ArrayType.FILE_ARRAY || @@ -1746,7 +1746,7 @@ public void checkTargetProperties() throws Exception { // null, '''Could not find file: '«it.withoutQuotes»'.''') // ] // } - + System.out.println("Known bad assignments:"); List knownIncorrect = synthesizeExamples(prop.type, false); if (!(knownIncorrect == null || knownIncorrect.isEmpty())) { @@ -1774,7 +1774,7 @@ public void checkTargetProperties() throws Exception { String.format("Target property '%s%s' is required to be %s.", prop.toString(), it.get(1), it.get(2))); } } - } + } System.out.println("===="); } System.out.println("Done!"); @@ -1793,7 +1793,7 @@ public void checkCargoDependencyProperty() throws Exception { validator.assertError(createModel(prop, "{ dep: {/*empty*/} }"), LfPackage.eINSTANCE.getKeyValuePairs(), null, "Must specify one of 'version', 'path', or 'git'" ); - + // vvvvvvvvvvv validator.assertError(createModel(prop, "{ dep: { unknown_key: \"\"} }"), LfPackage.eINSTANCE.getKeyValuePair(), null, "Unknown key: 'unknown_key'" @@ -2238,7 +2238,7 @@ public void testMainReactorHasHost() throws Exception { ); // TODO: Uncomment and fix test // List issues = validator.validate(parseWithoutError(testCase)); - // Assertions.assertTrue(issues.size() == 1 && + // Assertions.assertTrue(issues.size() == 1 && // issues.get(0).getMessage().contains("Cannot assign a host to reactor '") && // issues.get(0).getMessage().contains("' because it is not federated.")); } @@ -2424,7 +2424,7 @@ public void testMissingModeStateResetInstance() throws Exception { "This reactor contains state variables that are not reset upon mode entry: " + "s in R" + ".\nThe state variables are neither marked for automatic reset nor have a dedicated reset reaction. " - + "It is usafe to instatiate this reactor inside a mode entered with reset."); + + "It is unsafe to instantiate this reactor inside a mode entered with reset."); } @Test @@ -2455,11 +2455,9 @@ public void testUnspecifiedTransitionType() throws Exception { } """; validator.assertWarning(parseWithoutError(testCase), LfPackage.eINSTANCE.getReaction(), null, - "You should specifiy a transition type! " + "You should specify a transition type! " + "Reset and history transitions have different effects on this target mode. " + "Currently, a reset type is implicitly assumed."); } } - - diff --git a/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java b/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java index 41172cabed..8944fd0796 100644 --- a/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java @@ -29,4 +29,8 @@ public static String generateConstructor( code.pr("}"); return code.toString(); } + + public static String generateConstructorPrototype(Reactor reactor) { + return CUtil.selfType(reactor)+"* new_"+CUtil.getName(reactor)+"();"; + } } diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 26dfe5200a..e5abcfab2f 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -82,6 +82,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import org.lflang.generator.TriggerInstance; import org.lflang.lf.Action; import org.lflang.lf.ActionOrigin; +import org.lflang.lf.Code; import org.lflang.lf.Input; import org.lflang.lf.Instantiation; import org.lflang.lf.Mode; @@ -456,14 +457,13 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { FileUtil.createDirectoryIfDoesNotExist(fileConfig.getIncludePath().toFile()); handleProtoFiles(); - var lfModuleName = fileConfig.name; - generateCodeFor(lfModuleName); - // Derive target filename from the .lf filename. + var lfModuleName = fileConfig.name; var cFilename = CCompiler.getTargetFileName(lfModuleName, this.CCppMode, targetConfig); var targetFile = fileConfig.getSrcGenPath() + File.separator + cFilename; - try { + generateCodeFor(lfModuleName); + String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; @@ -519,8 +519,10 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { // If cmake is requested, generate the CMakeLists.txt if (targetConfig.platformOptions.platform != Platform.ARDUINO) { var cmakeFile = fileConfig.getSrcGenPath() + File.separator + "CMakeLists.txt"; + var sources = reactors.stream().map(CUtil::getName).map(it -> it + ".c").collect(Collectors.toList()); + sources.add(cFilename); var cmakeCode = cmakeGenerator.generateCMakeCode( - List.of(cFilename), + sources, lfModuleName, errorReporter, CCppMode, @@ -651,7 +653,7 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { private void generateCodeFor( String lfModuleName - ) { + ) throws IOException { startTimeStepIsPresentCount = 0; code.pr(generateDirectives()); code.pr(generateTopLevelPreambles()); @@ -915,7 +917,7 @@ public void copyUserFiles(TargetConfig targetConfig, FileConfig fileConfig) { * of cmake-include files. * - If there are any preambles, add them to the preambles of the reactor. */ - private void generateReactorDefinitions() { + private void generateReactorDefinitions() throws IOException { var generatedReactors = new LinkedHashSet(); if (this.main != null) { generateReactorChildren(this.main, generatedReactors); @@ -969,7 +971,7 @@ private void generateHeaders() throws IOException { private void generateReactorChildren( ReactorInstance reactor, LinkedHashSet generatedReactors - ) { + ) throws IOException { for (ReactorInstance r : reactor.children) { if (r.reactorDeclaration != null && !generatedReactors.contains(r.reactorDefinition)) { @@ -1031,38 +1033,36 @@ protected void copyTargetFiles() throws IOException { * data to contained reactors that are not in the federate. * @param reactor The parsed reactor data structure. */ - private void generateReactorClass(Reactor reactor) { + private void generateReactorClass(Reactor reactor) throws IOException { // FIXME: Currently we're not reusing definitions for declarations that point to the same definition. - - Reactor defn = ASTUtils.toDefinition(reactor); - - if (reactor instanceof Reactor) { - code.pr("// =============== START reactor class " + reactor.getName()); - } else { - code.pr("// =============== START reactor class " + defn.getName() + " as " + reactor.getName()); - } + CodeBuilder header = new CodeBuilder(); + CodeBuilder src = new CodeBuilder(); + final String headerName = CUtil.getName(reactor) + ".h"; + header.pr("#include \"include/core/reactor.h\""); + src.pr("#include \"" + headerName + "\""); + src.pr("#include \"api.h\""); + src.pr("#include \"set.h\""); + generateIncludes(reactor); // Preamble code contains state declarations with static initializers. - generateUserPreamblesForReactor(defn); + generateUserPreamblesForReactor(reactor); // Some of the following methods create lines of code that need to // go into the constructor. Collect those lines of code here: var constructorCode = new CodeBuilder(); - generateIncludes(reactor); - generateSelfStruct(reactor, constructorCode); - generateMethods(reactor); - generateReactions(reactor); - generateConstructor(reactor, constructorCode); - - code.pr("// =============== END reactor class " + reactor.getName()); - code.pr(""); + generateSelfStruct(header, reactor, constructorCode); + generateMethods(src, reactor); + generateReactions(src, reactor); + generateConstructor(src, header, reactor, constructorCode); + FileUtil.writeToFile(header.toString(), fileConfig.getSrcGenPath().resolve(headerName), true); + FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + ".c"), true); } /** * Generate methods for {@code reactor}. */ - protected void generateMethods(ReactorDecl reactor) { - CMethodGenerator.generateMethods(reactor, code, types); + protected void generateMethods(CodeBuilder src, ReactorDecl reactor) { + CMethodGenerator.generateMethods(reactor, src, types); } /** @@ -1085,17 +1085,19 @@ protected void generateUserPreamblesForReactor(Reactor reactor) { * go into the constructor. */ protected void generateConstructor( - Reactor reactor, CodeBuilder constructorCode + CodeBuilder src, CodeBuilder header, Reactor reactor, CodeBuilder constructorCode ) { - code.pr(CConstructorGenerator.generateConstructor( + header.pr(CConstructorGenerator.generateConstructorPrototype(reactor)); + src.pr(CConstructorGenerator.generateConstructor( reactor, constructorCode.toString() )); } - protected void generateIncludes(ReactorDecl decl) { + protected void generateIncludes(Reactor r) { if (CCppMode) code.pr("extern \"C\" {"); - code.pr("#include \"include/" + CUtil.getName(ASTUtils.toDefinition(decl)) + ".h\""); + code.pr("#include \"" + CUtil.getName(r) + ".h\""); + code.pr("#include \"include/" + CReactorHeaderFileGenerator.outputPath(fileConfig, r) + "\""); if (CCppMode) code.pr("}"); } @@ -1152,7 +1154,7 @@ protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r) { * @param constructorCode Place to put lines of code that need to * go into the constructor. */ - private void generateSelfStruct(ReactorDecl decl, CodeBuilder constructorCode) { + private void generateSelfStruct(CodeBuilder builder, ReactorDecl decl, CodeBuilder constructorCode) { var reactor = toDefinition(decl); var selfType = CUtil.selfType(ASTUtils.toDefinition(decl)); @@ -1198,12 +1200,12 @@ private void generateSelfStruct(ReactorDecl decl, CodeBuilder constructorCode) { // The first field has to always be a pointer to the list of // of allocated memory that must be freed when the reactor is freed. // This means that the struct can be safely cast to self_base_t. - code.pr("typedef struct {"); - code.indent(); - code.pr("struct self_base_t base;"); - code.pr(body.toString()); - code.unindent(); - code.pr("} " + selfType + ";"); + builder.pr("typedef struct {"); + builder.indent(); + builder.pr("struct self_base_t base;"); + builder.pr(body.toString()); + builder.unindent(); + builder.pr("} " + selfType + ";"); } /** @@ -1363,11 +1365,11 @@ protected void generateSelfStructExtension( * actions (triggering or produced), and outputs. * @param r The reactor. */ - public void generateReactions(Reactor r) { + public void generateReactions(CodeBuilder src, Reactor r) { var reactionIndex = 0; var reactor = ASTUtils.toDefinition(r); for (Reaction reaction : allReactions(reactor)) { - generateReaction(reaction, r, reactionIndex); + generateReaction(src, reaction, r, reactionIndex); // Increment reaction index even if the reaction is not in the federate // so that across federates, the reaction indices are consistent. reactionIndex++; @@ -1382,9 +1384,8 @@ public void generateReactions(Reactor r) { * @param r The reactor. * @param reactionIndex The position of the reaction within the reactor. */ - protected void generateReaction(Reaction reaction, Reactor r, int reactionIndex) { - - code.pr(CReactionGenerator.generateReaction( + protected void generateReaction(CodeBuilder src, Reaction reaction, Reactor r, int reactionIndex) { + src.pr(CReactionGenerator.generateReaction( reaction, r, reactionIndex, diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index a0f5f96d43..b70ed0887e 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -1,6 +1,7 @@ package org.lflang.generator.c; import java.io.IOException; +import java.nio.file.Path; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -23,9 +24,15 @@ public interface GenerateAuxiliaryStructs { void generate(CodeBuilder b, Reactor r); } + public static Path outputPath(CFileConfig fileConfig, Reactor r) { + return Path.of(Path.of(r.eResource().getURI().toFileString()) + .getFileName().toString().replaceFirst("[.][^.]+$", "")) + .resolve(r.getName() + ".h"); + } + public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator) throws IOException { String contents = generateHeaderFile(types, r, generator); - FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(CUtil.getName(r) + ".h")); + FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(outputPath(fileConfig, r))); } private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator) { CodeBuilder builder = new CodeBuilder(); @@ -54,7 +61,7 @@ private static void appendPoundIncludes(CodeBuilder builder) { } private static String userFacingSelfType(Reactor r) { - return r.getName().toLowerCase() + r.hashCode() + "_self_t"; + return r.getName().toLowerCase() + "_self_t"; } private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor r) { diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 7f6c0412e8..cb079afcf1 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -461,12 +461,12 @@ protected PythonDockerGenerator getDockerGenerator(LFGeneratorContext context) { * @param reactionIndex The position of the reaction within the reactor. */ @Override - protected void generateReaction(Reaction reaction, Reactor r, int reactionIndex) { + protected void generateReaction(CodeBuilder src, Reaction reaction, Reactor r, int reactionIndex) { Reactor reactor = ASTUtils.toDefinition(r); // Reactions marked with a `@_c_body` attribute are generated in C if (AttributeUtils.hasCBody(reaction)) { - super.generateReaction(reaction, r, reactionIndex); + super.generateReaction(src, reaction, r, reactionIndex); return; } code.pr(PythonReactionGenerator.generateCReaction(reaction, reactor, reactionIndex, mainDef, errorReporter, types)); @@ -506,7 +506,7 @@ protected void generateParameterInitialization(ReactorInstance instance) { * @see PythonMethodGenerator */ @Override - protected void generateMethods(ReactorDecl reactor) { } + protected void generateMethods(CodeBuilder src, ReactorDecl reactor) { } /** * Generate C preambles defined by user for a given reactor diff --git a/org.lflang/src/org/lflang/validation/LFValidator.java b/org.lflang/src/org/lflang/validation/LFValidator.java index acb7b8fe00..394250d22c 100644 --- a/org.lflang/src/org/lflang/validation/LFValidator.java +++ b/org.lflang/src/org/lflang/validation/LFValidator.java @@ -1465,7 +1465,7 @@ public void checkUnspecifiedTransitionType(Reaction reaction) { } } if (makesDifference) { - warning("You should specifiy a transition type! " + warning("You should specify a transition type! " + "Reset and history transitions have different effects on this target mode. " + "Currently, a reset type is implicitly assumed.", reaction, Literals.REACTION__EFFECTS, reaction.getEffects().indexOf(effect)); From 0a6b5b3e3072188e038a0a97b1faf4a03c1101ab Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Feb 2023 23:35:08 -0800 Subject: [PATCH 24/92] Fix includes. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index e5abcfab2f..4e12ddf48f 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1040,8 +1040,8 @@ private void generateReactorClass(Reactor reactor) throws IOException { final String headerName = CUtil.getName(reactor) + ".h"; header.pr("#include \"include/core/reactor.h\""); src.pr("#include \"" + headerName + "\""); - src.pr("#include \"api.h\""); - src.pr("#include \"set.h\""); + src.pr("#include \"include/api.h\""); + src.pr("#include \"include/set.h\""); generateIncludes(reactor); // Preamble code contains state declarations with static initializers. From 1d561e8078396fd4ad054a78ae812a8a25ac6f7b Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Feb 2023 17:00:16 -0800 Subject: [PATCH 25/92] [C] Try again to fix namespacing issues. --- .../lflang/generator/c/CActionGenerator.java | 7 ++- .../org/lflang/generator/c/CGenerator.java | 56 ++++++++++++------- .../lflang/generator/c/CPortGenerator.java | 19 ++++--- .../generator/c/CReactionGenerator.java | 16 +++--- .../c/CReactorHeaderFileGenerator.java | 4 +- .../python/PythonActionGenerator.java | 2 +- .../generator/python/PythonGenerator.java | 2 +- .../generator/python/PythonPortGenerator.java | 2 +- 8 files changed, 63 insertions(+), 45 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CActionGenerator.java b/org.lflang/src/org/lflang/generator/c/CActionGenerator.java index 37867f9101..dee3576d03 100644 --- a/org.lflang/src/org/lflang/generator/c/CActionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CActionGenerator.java @@ -103,7 +103,7 @@ public static void generateDeclarations( ) { for (Action action : ASTUtils.allActions(reactor)) { var actionName = action.getName(); - body.pr(action, CGenerator.variableStructType(action, reactor)+" _lf_"+actionName+";"); + body.pr(action, CGenerator.variableStructType(action, reactor, false)+" _lf_"+actionName+";"); // Initialize the trigger pointer in the action. constructorCode.pr(action, "self->_lf_"+actionName+".trigger = &self->_lf__"+actionName+";"); } @@ -125,7 +125,8 @@ public static String generateAuxiliaryStruct( Action action, Target target, CTypes types, - CodeBuilder federatedExtension + CodeBuilder federatedExtension, + boolean userFacing ) { var code = new CodeBuilder(); code.pr("typedef struct {"); @@ -145,7 +146,7 @@ public static String generateAuxiliaryStruct( code.pr(valueDeclaration(action, target, types)); code.pr(federatedExtension.toString()); code.unindent(); - code.pr("} " + variableStructType(action, r) + ";"); + code.pr("} " + variableStructType(action, r, userFacing) + ";"); return code.toString(); } diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 4e12ddf48f..7c2f1dccaa 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -39,8 +39,10 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -1038,24 +1040,39 @@ private void generateReactorClass(Reactor reactor) throws IOException { CodeBuilder header = new CodeBuilder(); CodeBuilder src = new CodeBuilder(); final String headerName = CUtil.getName(reactor) + ".h"; + var guardMacro = headerName.toUpperCase().replace(".", "_"); + header.pr("#ifndef " + guardMacro); + header.pr("#define " + guardMacro); + generateReactorClassHeaders(reactor, headerName, header, src); + generateUserPreamblesForReactor(reactor); + generateReactorClassBody(reactor, header, src); + header.pr("#endif // " + guardMacro); + FileUtil.writeToFile(header.toString(), fileConfig.getSrcGenPath().resolve(headerName), true); + FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + ".c"), true); + } + + private void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { header.pr("#include \"include/core/reactor.h\""); src.pr("#include \"" + headerName + "\""); - src.pr("#include \"include/api.h\""); - src.pr("#include \"include/set.h\""); + src.pr("#include \"include/api/api.h\""); + src.pr("#include \"include/api/set.h\""); generateIncludes(reactor); + new HashSet<>(reactor.getInstantiations()).stream() + .map(Instantiation::getReactorClass) + .map(ASTUtils::toDefinition).map(CUtil::getName) + .map(name -> "#include \"" + name + ".h\"") + .forEach(header::pr); + } - // Preamble code contains state declarations with static initializers. - generateUserPreamblesForReactor(reactor); - + private void generateReactorClassBody(Reactor reactor, CodeBuilder header, CodeBuilder src) { // Some of the following methods create lines of code that need to // go into the constructor. Collect those lines of code here: var constructorCode = new CodeBuilder(); + generateAuxiliaryStructs(header, reactor, false); generateSelfStruct(header, reactor, constructorCode); generateMethods(src, reactor); generateReactions(src, reactor); generateConstructor(src, header, reactor, constructorCode); - FileUtil.writeToFile(header.toString(), fileConfig.getSrcGenPath().resolve(headerName), true); - FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + ".c"), true); } /** @@ -1105,7 +1122,7 @@ protected void generateIncludes(Reactor r) { * Generate the struct type definitions for inputs, outputs, and * actions of the specified reactor. */ - protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r) { + protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r, boolean userFacing) { // In the case where there are incoming // p2p logical connections in decentralized // federated execution, there will be an @@ -1130,7 +1147,8 @@ protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r) { getTarget(), errorReporter, types, - federatedExtension + federatedExtension, + userFacing )); } // The very first item on this struct needs to be @@ -1142,7 +1160,8 @@ protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r) { action, getTarget(), types, - federatedExtension + federatedExtension, + userFacing )); } } @@ -1262,12 +1281,12 @@ private void generateInteractingContainedReactors( // to be malloc'd at initialization. if (!ASTUtils.isMultiport(port)) { // Not a multiport. - body.pr(port, variableStructType(port, containedReactorType)+" "+port.getName()+";"); + body.pr(port, variableStructType(port, containedReactorType, false)+" "+port.getName()+";"); } else { // Is a multiport. // Memory will be malloc'd in initialization. body.pr(port, String.join("\n", - variableStructType(port, containedReactorType)+"** "+port.getName()+";", + variableStructType(port, containedReactorType, false)+"** "+port.getName()+";", "int "+port.getName()+"_width;" )); } @@ -1277,13 +1296,13 @@ private void generateInteractingContainedReactors( // self struct of the container. if (!ASTUtils.isMultiport(port)) { // Not a multiport. - body.pr(port, variableStructType(port, containedReactorType)+"* "+port.getName()+";"); + body.pr(port, variableStructType(port, containedReactorType, false)+"* "+port.getName()+";"); } else { // Is a multiport. // Here, we will use an array of pointers. // Memory will be malloc'd in initialization. body.pr(port, String.join("\n", - variableStructType(port, containedReactorType)+"** "+port.getName()+";", + variableStructType(port, containedReactorType, false)+"** "+port.getName()+";", "int "+port.getName()+"_width;" )); } @@ -1631,19 +1650,16 @@ public void processProtoFile(String filename) { * typed variable (port or action) of the specified reactor class. * This is required to be the same as the type name returned by * {@link #variableStructType(TriggerInstance)}. - * @param variable The variable. - * @param reactor The reactor class. - * @return The name of the self struct. */ - public static String variableStructType(Variable variable, Reactor reactor) { - return CUtil.getName(reactor)+"_"+variable.getName()+"_t"; + public static String variableStructType(Variable variable, Reactor reactor, boolean userFacing) { + return (userFacing ? reactor.getName() : CUtil.getName(reactor)) +"_"+variable.getName()+"_t"; } /** * Construct a unique type for the struct of the specified * instance (port or action). * This is required to be the same as the type name returned by - * {@link #variableStructType(Variable, Reactor)}. + * {@link #variableStructType(Variable, Reactor, boolean)}. * @param portOrAction The port or action instance. * @return The name of the self struct. */ diff --git a/org.lflang/src/org/lflang/generator/c/CPortGenerator.java b/org.lflang/src/org/lflang/generator/c/CPortGenerator.java index 543514ff71..cf6ea06b64 100644 --- a/org.lflang/src/org/lflang/generator/c/CPortGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CPortGenerator.java @@ -58,7 +58,8 @@ public static String generateAuxiliaryStruct( Target target, ErrorReporter errorReporter, CTypes types, - CodeBuilder federatedExtension + CodeBuilder federatedExtension, + boolean userFacing ) { var code = new CodeBuilder(); code.pr("typedef struct {"); @@ -79,7 +80,7 @@ public static String generateAuxiliaryStruct( code.pr(valueDeclaration(port, target, errorReporter, types)); code.pr(federatedExtension.toString()); code.unindent(); - code.pr("} "+variableStructType(port, decl)+";"); + code.pr("} "+variableStructType(port, decl, userFacing)+";"); return code.toString(); } @@ -210,21 +211,21 @@ private static void generateInputDeclarations( if (ASTUtils.isMultiport(input)) { body.pr(input, String.join("\n", "// Multiport input array will be malloc'd later.", - variableStructType(input, reactor)+"** _lf_"+inputName+";", + variableStructType(input, reactor, false)+"** _lf_"+inputName+";", "int _lf_"+inputName+"_width;", "// Default input (in case it does not get connected)", - variableStructType(input, reactor)+" _lf_default__"+inputName+";", + variableStructType(input, reactor, false)+" _lf_default__"+inputName+";", "// Struct to support efficiently reading sparse inputs.", "lf_sparse_io_record_t* _lf_"+inputName+"__sparse;" )); } else { // input is not a multiport. body.pr(input, String.join("\n", - variableStructType(input, reactor)+"* _lf_"+inputName+";", + variableStructType(input, reactor, false)+"* _lf_"+inputName+";", "// width of -2 indicates that it is not a multiport.", "int _lf_"+inputName+"_width;", "// Default input (in case it does not get connected)", - variableStructType(input, reactor)+" _lf_default__"+inputName+";" + variableStructType(input, reactor, false)+" _lf_default__"+inputName+";" )); constructorCode.pr(input, String.join("\n", @@ -256,7 +257,7 @@ private static void generateOutputDeclarations( if (ASTUtils.isMultiport(output)) { body.pr(output, String.join("\n", "// Array of output ports.", - variableStructType(output, reactor)+"* _lf_"+outputName+";", + variableStructType(output, reactor, false)+"* _lf_"+outputName+";", "int _lf_"+outputName+"_width;", "// An array of pointers to the individual ports. Useful", "// for the lf_set macros to work out-of-the-box for", @@ -264,11 +265,11 @@ private static void generateOutputDeclarations( "// value can be accessed via a -> operator (e.g.,foo[i]->value).", "// So we have to handle multiports specially here a construct that", "// array of pointers.", - variableStructType(output, reactor)+"** _lf_"+outputName+"_pointers;" + variableStructType(output, reactor, false)+"** _lf_"+outputName+"_pointers;" )); } else { body.pr(output, String.join("\n", - variableStructType(output, reactor)+" _lf_"+outputName+";", + variableStructType(output, reactor, false)+" _lf_"+outputName+";", "int _lf_"+outputName+"_width;" )); } diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index 8dc34fdde3..051540bbf6 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -39,7 +39,7 @@ public class CReactionGenerator { protected static String DISABLE_REACTION_INITIALIZATION_MARKER - = "// **** Do not include initialization code in this reaction."; + = "// **** Do not include initialization code in this reaction."; // FIXME: Such markers should not exist /** * Generate necessary initialization code inside the body of the reaction that belongs to reactor decl. @@ -160,7 +160,7 @@ public static String generateInitializationForReaction(String body, // It is an action, not an output. // If it has already appeared as trigger, do not redefine it. if (!actionsAsTriggers.contains(effect.getVariable())) { - reactionInitialization.pr(CGenerator.variableStructType(variable, decl)+"* "+variable.getName()+" = &self->_lf_"+variable.getName()+";"); + reactionInitialization.pr(CGenerator.variableStructType(variable, decl, false)+"* "+variable.getName()+" = &self->_lf_"+variable.getName()+";"); } } else if (effect.getVariable() instanceof Mode) { // Mode change effect @@ -355,7 +355,7 @@ private static void generateVariablesForSendingToContainedReactors( structBuilder = new CodeBuilder(); structs.put(definition, structBuilder); } - String inputStructType = CGenerator.variableStructType(input, ASTUtils.toDefinition(definition.getReactorClass())); + String inputStructType = CGenerator.variableStructType(input, ASTUtils.toDefinition(definition.getReactorClass()), false); String defName = definition.getName(); String defWidth = generateWidthVariable(defName); String inputName = input.getName(); @@ -422,7 +422,7 @@ private static void generatePortVariablesInReaction( } else { // port is an output of a contained reactor. Output output = (Output) port.getVariable(); - String portStructType = CGenerator.variableStructType(output, ASTUtils.toDefinition(port.getContainer().getReactorClass())); + String portStructType = CGenerator.variableStructType(output, ASTUtils.toDefinition(port.getContainer().getReactorClass()), false); CodeBuilder structBuilder = structs.get(port.getContainer()); if (structBuilder == null) { @@ -479,7 +479,7 @@ private static String generateActionVariablesInReaction( Reactor r, CTypes types ) { - String structType = CGenerator.variableStructType(action, r); + String structType = CGenerator.variableStructType(action, r, false); // If the action has a type, create variables for accessing the value. InferredType type = ASTUtils.getInferredType(action); // Pointer to the lf_token_t sent as the payload in the trigger. @@ -523,7 +523,7 @@ private static String generateInputVariablesInReaction( Reactor r, CTypes types ) { - String structType = CGenerator.variableStructType(input, r); + String structType = CGenerator.variableStructType(input, r, false); InferredType inputType = ASTUtils.getInferredType(input); CodeBuilder builder = new CodeBuilder(); String inputName = input.getName(); @@ -642,9 +642,9 @@ public static String generateOutputVariablesInReaction( // The container of the output may be a contained reactor or // the reactor containing the reaction. String outputStructType = (effect.getContainer() == null) ? - CGenerator.variableStructType(output, r) + CGenerator.variableStructType(output, r, false) : - CGenerator.variableStructType(output, ASTUtils.toDefinition(effect.getContainer().getReactorClass())); + CGenerator.variableStructType(output, ASTUtils.toDefinition(effect.getContainer().getReactorClass()), false); if (!ASTUtils.isMultiport(output)) { // Output port is not a multiport. return outputStructType+"* "+outputName+" = &self->_lf_"+outputName+";"; diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index b70ed0887e..e131560834 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -21,7 +21,7 @@ public class CReactorHeaderFileGenerator { public interface GenerateAuxiliaryStructs { - void generate(CodeBuilder b, Reactor r); + void generate(CodeBuilder b, Reactor r, boolean userFacing); } public static Path outputPath(CFileConfig fileConfig, Reactor r) { @@ -39,7 +39,7 @@ private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxili appendIncludeGuard(builder, r); appendPoundIncludes(builder); appendSelfStruct(builder, types, r); - generator.generate(builder, r); + generator.generate(builder, r, true); for (Reaction reaction : r.getReactions()) { appendSignature(builder, types, reaction, r); } diff --git a/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java index bcf202b98c..a2a149f522 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonActionGenerator.java @@ -8,6 +8,6 @@ public class PythonActionGenerator { public static String generateAliasTypeDef(Reactor r, Action action, String genericActionType) { - return "typedef "+genericActionType+" "+CGenerator.variableStructType(action, r)+";"; + return "typedef "+genericActionType+" "+CGenerator.variableStructType(action, r, false)+";"; } } diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index cb079afcf1..743a80bce1 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -358,7 +358,7 @@ public void processProtoFile(String filename) { */ @Override public void generateAuxiliaryStructs( - CodeBuilder builder, Reactor r + CodeBuilder builder, Reactor r, boolean userFacing ) { for (Input input : ASTUtils.allInputs(r)) { generateAuxiliaryStructsForPort(builder, r, input); diff --git a/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java index 4eb4ba54fa..9e0919b52c 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonPortGenerator.java @@ -196,7 +196,7 @@ public static String generatePythonListForContainedBank(String reactorName, Port } public static String generateAliasTypeDef(Reactor r, Port port, boolean isTokenType, String genericPortType) { - return "typedef "+genericPortType+" "+CGenerator.variableStructType(port, r)+";"; + return "typedef "+genericPortType+" "+CGenerator.variableStructType(port, r, false)+";"; } private static String generateConvertCPortToPy(String port) { From 8fd195519c3c8b3672618416b36677a586209f38 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Feb 2023 17:18:23 -0800 Subject: [PATCH 26/92] [C] Get a CCpp smoke test to pass. --- .../src/org/lflang/generator/c/CGenerator.java | 18 ++++++++++-------- .../generator/python/PythonGenerator.java | 3 ++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 7c2f1dccaa..2a3b1ef80f 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -521,7 +521,7 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { // If cmake is requested, generate the CMakeLists.txt if (targetConfig.platformOptions.platform != Platform.ARDUINO) { var cmakeFile = fileConfig.getSrcGenPath() + File.separator + "CMakeLists.txt"; - var sources = reactors.stream().map(CUtil::getName).map(it -> it + ".c").collect(Collectors.toList()); + var sources = reactors.stream().map(CUtil::getName).map(it -> it + (CCppMode ? ".cpp" : ".c")).collect(Collectors.toList()); sources.add(cFilename); var cmakeCode = cmakeGenerator.generateCMakeCode( sources, @@ -1044,14 +1044,15 @@ private void generateReactorClass(Reactor reactor) throws IOException { header.pr("#ifndef " + guardMacro); header.pr("#define " + guardMacro); generateReactorClassHeaders(reactor, headerName, header, src); - generateUserPreamblesForReactor(reactor); + generateUserPreamblesForReactor(reactor, src); generateReactorClassBody(reactor, header, src); header.pr("#endif // " + guardMacro); FileUtil.writeToFile(header.toString(), fileConfig.getSrcGenPath().resolve(headerName), true); - FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + ".c"), true); + FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + (CCppMode ? ".cpp" : ".c")), true); } private void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { + if (CCppMode) src.pr("extern \"C\" {"); header.pr("#include \"include/core/reactor.h\""); src.pr("#include \"" + headerName + "\""); src.pr("#include \"include/api/api.h\""); @@ -1062,6 +1063,7 @@ private void generateReactorClassHeaders(Reactor reactor, String headerName, Cod .map(ASTUtils::toDefinition).map(CUtil::getName) .map(name -> "#include \"" + name + ".h\"") .forEach(header::pr); + if (CCppMode) src.pr("}"); } private void generateReactorClassBody(Reactor reactor, CodeBuilder header, CodeBuilder src) { @@ -1086,12 +1088,12 @@ protected void generateMethods(CodeBuilder src, ReactorDecl reactor) { * Generates preambles defined by user for a given reactor * @param reactor The given reactor */ - protected void generateUserPreamblesForReactor(Reactor reactor) { + protected void generateUserPreamblesForReactor(Reactor reactor, CodeBuilder src) { for (Preamble p : convertToEmptyListIfNull(reactor.getPreambles())) { - code.pr("// *********** From the preamble, verbatim:"); - code.prSourceLineNumber(p.getCode()); - code.pr(toText(p.getCode())); - code.pr("\n// *********** End of preamble."); + src.pr("// *********** From the preamble, verbatim:"); + src.prSourceLineNumber(p.getCode()); + src.pr(toText(p.getCode())); + src.pr("\n// *********** End of preamble."); } } diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 743a80bce1..a613da68ce 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -55,6 +55,7 @@ import org.lflang.generator.c.CGenerator; import org.lflang.generator.c.CUtil; import org.lflang.lf.Action; +import org.lflang.lf.Code; import org.lflang.lf.Input; import org.lflang.lf.Model; import org.lflang.lf.Output; @@ -516,7 +517,7 @@ protected void generateMethods(CodeBuilder src, ReactorDecl reactor) { } * @param reactor The given reactor */ @Override - protected void generateUserPreamblesForReactor(Reactor reactor) { + protected void generateUserPreamblesForReactor(Reactor reactor, CodeBuilder src) { // Do nothing } From aacfbd70cb89ee245253f991e93d2130310fe24f Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Feb 2023 17:38:04 -0800 Subject: [PATCH 27/92] [C] Get some Python tests to pass. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 2 +- .../src/org/lflang/generator/python/PythonGenerator.java | 8 +++++++- .../lflang/generator/python/PythonPreambleGenerator.java | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 2a3b1ef80f..c0ca7d285d 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1051,7 +1051,7 @@ private void generateReactorClass(Reactor reactor) throws IOException { FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + (CCppMode ? ".cpp" : ".c")), true); } - private void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { + protected void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { if (CCppMode) src.pr("extern \"C\" {"); header.pr("#include \"include/core/reactor.h\""); src.pr("#include \"" + headerName + "\""); diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index a613da68ce..56440f2668 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -470,7 +470,7 @@ protected void generateReaction(CodeBuilder src, Reaction reaction, Reactor r, i super.generateReaction(src, reaction, r, reactionIndex); return; } - code.pr(PythonReactionGenerator.generateCReaction(reaction, reactor, reactionIndex, mainDef, errorReporter, types)); + src.pr(PythonReactionGenerator.generateCReaction(reaction, reactor, reactionIndex, mainDef, errorReporter, types)); } /** @@ -521,6 +521,12 @@ protected void generateUserPreamblesForReactor(Reactor reactor, CodeBuilder src) // Do nothing } + @Override + protected void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { + header.pr(PythonPreambleGenerator.generateCIncludeStatements(targetConfig, targetLanguageIsCpp(), hasModalReactors)); + super.generateReactorClassHeaders(reactor, headerName, header, src); + } + /** * Generate code that is executed while the reactor instance is being * initialized. diff --git a/org.lflang/src/org/lflang/generator/python/PythonPreambleGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonPreambleGenerator.java index 5fa8aff84f..e2fd7af86a 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonPreambleGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonPreambleGenerator.java @@ -55,7 +55,7 @@ public static String generateCIncludeStatements( code.pr(CPreambleGenerator.generateIncludeStatements(targetConfig, CCppMode)); code.pr("#include \"pythontarget.h\""); if (hasModalReactors) { - code.pr("#include \"modal_models/definitions.h\""); + code.pr("#include \"include/modal_models/definitions.h\""); } return code.toString(); } From 9277c963fa922ecf69568cae04cde7ae819458d0 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Feb 2023 18:11:27 -0800 Subject: [PATCH 28/92] Minor bugfixes for CCpp, Arduino. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 3 ++- test/C/src/concurrent/ScheduleAt.lf | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index c0ca7d285d..2da6107156 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1048,7 +1048,8 @@ private void generateReactorClass(Reactor reactor) throws IOException { generateReactorClassBody(reactor, header, src); header.pr("#endif // " + guardMacro); FileUtil.writeToFile(header.toString(), fileConfig.getSrcGenPath().resolve(headerName), true); - FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + (CCppMode ? ".cpp" : ".c")), true); + var extension = targetConfig.platformOptions.platform == Platform.ARDUINO ? ".ino" : (CCppMode ? ".cpp" : ".c"); + FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + extension), true); } protected void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { diff --git a/test/C/src/concurrent/ScheduleAt.lf b/test/C/src/concurrent/ScheduleAt.lf index 7e5e8318b1..2e438f328e 100644 --- a/test/C/src/concurrent/ScheduleAt.lf +++ b/test/C/src/concurrent/ScheduleAt.lf @@ -10,6 +10,9 @@ target C { } reactor Scheduler { + preamble {= + #include "include/core/reactor_common.h" + =} logical action act // List of microsteps. Size = 16 state microstep_delay_list: uint32_t[]( From bd3a820797a11c81d299b9c877c67fae1e4ab861 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Feb 2023 21:15:35 -0800 Subject: [PATCH 29/92] Resolve conflict in CPreambleGenerator. Tagging @arengarajan99 since he is working in this part of the code. --- org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java index 47bdb63caa..503ca0dff2 100644 --- a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java @@ -52,8 +52,8 @@ public static String generateIncludeStatements( code.pr("#include \"include/core/port.h\""); code.pr("int lf_reactor_c_main(int argc, const char* argv[]);"); if(targetConfig.fedSetupPreamble != null) { - code.pr("#include \"" + relPathHeader + "core/federated/federate.h\""); - code.pr("#include \"" + relPathHeader + "core/federated/net_common.h\""); + code.pr("#include \"include/core/federated/federate.h\""); + code.pr("#include \"include/core/federated/net_common.h\""); } if (cppMode || targetConfig.platformOptions.platform == Platform.ARDUINO) { code.pr("}"); From ea979eedca56f3d7c49784567c63c4ad5888bc12 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 09:22:52 -0800 Subject: [PATCH 30/92] Do not delete include directory. This avoids fed-gen race condition. It will lead to quadratically many file writes in CI. It also allows users to put their own files in the include directory if they like. I am not sure if this is a "feature" that we actually want. We can discuss later. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 2da6107156..f886705cba 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -946,7 +946,7 @@ private void generateReactorDefinitions() throws IOException { } private void generateHeaders() throws IOException { - FileUtil.deleteDirectory(fileConfig.getIncludePath()); + // Cannot delete existing header files directory because this would create a race condition in fed-gen FileUtil.copyDirectoryFromClassPath( fileConfig.getRuntimeIncludePath(), fileConfig.getIncludePath(), From dd24c55d8f222008c35a0036aaf9335b52b52a63 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 09:32:20 -0800 Subject: [PATCH 31/92] Copy file-level preamble to reactor-specific files See https://github.com/lf-lang/lingua-franca/pull/1599#issuecomment-1445004112 for discussion --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index f886705cba..0472999eb8 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -658,7 +658,6 @@ private void generateCodeFor( ) throws IOException { startTimeStepIsPresentCount = 0; code.pr(generateDirectives()); - code.pr(generateTopLevelPreambles()); code.pr(new CMainFunctionGenerator(targetConfig).generateCode()); // Generate code for each reactor. generateReactorDefinitions(); @@ -1044,6 +1043,7 @@ private void generateReactorClass(Reactor reactor) throws IOException { header.pr("#ifndef " + guardMacro); header.pr("#define " + guardMacro); generateReactorClassHeaders(reactor, headerName, header, src); + src.pr(generateTopLevelPreambles()); generateUserPreamblesForReactor(reactor, src); generateReactorClassBody(reactor, header, src); header.pr("#endif // " + guardMacro); From 9b28591c4f7f1b9ba54bd215cb9c33c1a75a6cf4 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 09:46:06 -0800 Subject: [PATCH 32/92] Make ScheduleAt compile. When we use `target: CCpp` on a program that was written for the C target, it is possible that we should not guarantee that the program will still compile since C++ is not quite a superset of C. What if the user `#include`s a header file with function prototypes, implementations for which are given in C? Then they should use `extern "C" {}` if they want their code to be interpreted as C++. Concretely, this would mean scaling back our integration tests so that we do not require everything to compile as C++. Instead, we could only have a few example programs compiled as C++. Not a serious proposal yet, just recording the problem here for later reference. --- test/C/src/concurrent/ScheduleAt.lf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/C/src/concurrent/ScheduleAt.lf b/test/C/src/concurrent/ScheduleAt.lf index 2e438f328e..9a4ee2bb62 100644 --- a/test/C/src/concurrent/ScheduleAt.lf +++ b/test/C/src/concurrent/ScheduleAt.lf @@ -11,7 +11,13 @@ target C { reactor Scheduler { preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include "include/core/reactor_common.h" + #ifdef __cplusplus + } + #endif =} logical action act // List of microsteps. Size = 16 From 848e8bfdc2180d865881a34a91f9497b865c3664 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 11:03:36 -0800 Subject: [PATCH 33/92] Fixes for CCpp. --- .github/workflows/ci.yml | 2 +- .../org/lflang/generator/c/CGenerator.java | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b795984dac..5d7632cb6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: # Run the C benchmark tests. c-benchmark-tests: - uses: lf-lang/benchmarks-lingua-franca/.github/workflows/benchmark-tests.yml@main + uses: lf-lang/benchmarks-lingua-franca/.github/workflows/benchmark-tests.yml@c-separate-gen-files with: target: 'C' needs: cancel diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 0472999eb8..5db56856e6 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1043,7 +1043,7 @@ private void generateReactorClass(Reactor reactor) throws IOException { header.pr("#ifndef " + guardMacro); header.pr("#define " + guardMacro); generateReactorClassHeaders(reactor, headerName, header, src); - src.pr(generateTopLevelPreambles()); + header.pr(generateTopLevelPreambles()); generateUserPreamblesForReactor(reactor, src); generateReactorClassBody(reactor, header, src); header.pr("#endif // " + guardMacro); @@ -1053,18 +1053,24 @@ private void generateReactorClass(Reactor reactor) throws IOException { } protected void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { - if (CCppMode) src.pr("extern \"C\" {"); + if (CCppMode) { + src.pr("extern \"C\" {"); + header.pr("extern \"C\" {"); + } header.pr("#include \"include/core/reactor.h\""); - src.pr("#include \"" + headerName + "\""); src.pr("#include \"include/api/api.h\""); src.pr("#include \"include/api/set.h\""); generateIncludes(reactor); + if (CCppMode) { + src.pr("}"); + header.pr("}"); + } + src.pr("#include \"" + headerName + "\""); new HashSet<>(reactor.getInstantiations()).stream() .map(Instantiation::getReactorClass) .map(ASTUtils::toDefinition).map(CUtil::getName) .map(name -> "#include \"" + name + ".h\"") .forEach(header::pr); - if (CCppMode) src.pr("}"); } private void generateReactorClassBody(Reactor reactor, CodeBuilder header, CodeBuilder src) { @@ -1115,8 +1121,8 @@ protected void generateConstructor( } protected void generateIncludes(Reactor r) { - if (CCppMode) code.pr("extern \"C\" {"); code.pr("#include \"" + CUtil.getName(r) + ".h\""); + if (CCppMode) code.pr("extern \"C\" {"); code.pr("#include \"include/" + CReactorHeaderFileGenerator.outputPath(fileConfig, r) + "\""); if (CCppMode) code.pr("}"); } @@ -2042,6 +2048,8 @@ public String generateDirectives() { */ protected String generateTopLevelPreambles() { CodeBuilder code = new CodeBuilder(); + code.pr("#ifndef TOP_LEVEL_PREAMBLE_H"); + code.pr("#define TOP_LEVEL_PREAMBLE_H"); // preamble for federated execution setup if (targetConfig.fedSetupPreamble != null) { @@ -2057,6 +2065,7 @@ protected String generateTopLevelPreambles() { code.pr(toText(p.getCode())); } } + code.pr("#endif"); return code.toString(); } From b145e518b2edce02691cdfd6a83a66dcaca5844f Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 13:25:47 -0800 Subject: [PATCH 34/92] Update tests according to preamble changes. --- test/C/src/DeadlineInherited.lf | 3 ++- test/C/src/include/hello.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/C/src/DeadlineInherited.lf b/test/C/src/DeadlineInherited.lf index eab2f56d9b..3d3c8ac96b 100644 --- a/test/C/src/DeadlineInherited.lf +++ b/test/C/src/DeadlineInherited.lf @@ -4,9 +4,10 @@ target C { threading: false } -preamble {= int global_cnt = 0; =} +preamble {= extern int global_cnt; =} reactor NoDeadline { + preamble {= int global_cnt = 0; =} timer t(0 msec, 100 msec) reaction(t) {= global_cnt++; =} diff --git a/test/C/src/include/hello.h b/test/C/src/include/hello.h index 6ee45b62a7..7b290fba89 100644 --- a/test/C/src/include/hello.h +++ b/test/C/src/include/hello.h @@ -18,14 +18,14 @@ typedef struct hello_t { typedef int* int_pointer; -hello_t* hello_constructor(char* name, int value) { +static hello_t* hello_constructor(char* name, int value) { hello_t* val = (hello_t*) malloc(sizeof(hello_t)); val->name = name; val->value = value; return val; } -hello_t* hello_copy_constructor(hello_t v) { +static hello_t* hello_copy_constructor(hello_t v) { hello_t* val = (hello_t*) malloc(sizeof(hello_t)); val->name = v.name; val->value = v.value; From 0d9215195ab98e96bdfd2db80cad8e2b3f5aeb85 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 13:26:11 -0800 Subject: [PATCH 35/92] Do not include user-facing headers in main .c file These includes were causing a name conflict in BanksModalStateReset. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 5db56856e6..559a3d02ba 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1122,9 +1122,6 @@ protected void generateConstructor( protected void generateIncludes(Reactor r) { code.pr("#include \"" + CUtil.getName(r) + ".h\""); - if (CCppMode) code.pr("extern \"C\" {"); - code.pr("#include \"include/" + CReactorHeaderFileGenerator.outputPath(fileConfig, r) + "\""); - if (CCppMode) code.pr("}"); } /** From a45fb133cce6c5e9490d38fe411b1926b2681378 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 14:13:45 -0800 Subject: [PATCH 36/92] Get a federated smoke test to pass. --- .../federated/extensions/CExtension.java | 26 ++++++++++++------- .../generator/FedPreambleEmitter.java | 9 +++++-- .../org/lflang/generator/c/CGenerator.java | 13 +++++----- .../generator/python/PythonGenerator.java | 8 +----- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/extensions/CExtension.java b/org.lflang/src/org/lflang/federated/extensions/CExtension.java index d9ed222920..54961058d8 100644 --- a/org.lflang/src/org/lflang/federated/extensions/CExtension.java +++ b/org.lflang/src/org/lflang/federated/extensions/CExtension.java @@ -59,7 +59,6 @@ import org.lflang.lf.Output; import org.lflang.lf.Port; import org.lflang.lf.VarRef; -import org.lflang.util.FileUtil; /** * An extension class to the CGenerator that enables certain federated @@ -499,8 +498,15 @@ public String generatePreamble( try (var writer = Files.newBufferedWriter(fedPreamblePath)) { writer.write(cPreamble); } - - return ""; + var includes = new CodeBuilder(); + includes.pr("#include \"core/federated/federate.h\""); + includes.pr("#include \"core/federated/net_common.h\""); + includes.pr("#include \"core/federated/net_util.h\""); + includes.pr("#include \"core/threaded/reactor_threaded.h\""); + includes.pr("#include \"core/utils/util.h\""); + includes.pr("extern federate_instance_t _fed;"); + + return includes.toString(); } /** @@ -514,12 +520,12 @@ protected String makePreamble( var code = new CodeBuilder(); - code.pr("#include \"core/federated/federate.h\""); - code.pr("#include \"core/federated/net_common.h\""); - code.pr("#include \"core/federated/net_util.h\""); - code.pr("#include \"core/threaded/reactor_threaded.h\""); - code.pr("#include \"core/utils/util.h\""); - code.pr("extern federate_instance_t _fed;"); +// code.pr("#include \"core/federated/federate.h\""); +// code.pr("#include \"core/federated/net_common.h\""); +// code.pr("#include \"core/federated/net_util.h\""); +// code.pr("#include \"core/threaded/reactor_threaded.h\""); +// code.pr("#include \"core/utils/util.h\""); +// code.pr("extern federate_instance_t _fed;"); // Generate function to return a pointer to the action trigger_t // that handles incoming network messages destined to the specified @@ -568,7 +574,7 @@ private String generateInitializeTriggers(FederateInstance federate, ErrorReport code.pr(CExtensionUtils.initializeTriggersForNetworkActions(federate, main)); code.pr(CExtensionUtils.initializeTriggerForControlReactions(main, main, federate)); federatedReactor.setName(oldFederatedReactorName); - + return """ #define initialize_triggers_for_federate() \\ do { \\ diff --git a/org.lflang/src/org/lflang/federated/generator/FedPreambleEmitter.java b/org.lflang/src/org/lflang/federated/generator/FedPreambleEmitter.java index 827a31fe33..ac270613b6 100644 --- a/org.lflang/src/org/lflang/federated/generator/FedPreambleEmitter.java +++ b/org.lflang/src/org/lflang/federated/generator/FedPreambleEmitter.java @@ -38,8 +38,13 @@ String generatePreamble(FederateInstance federate, FedFileConfig fileConfig, Lin )); } - preambleCode.pr(FedTargetExtensionFactory.getExtension(federate.target).generatePreamble( - federate, fileConfig, federationRTIProperties, errorReporter)); + preambleCode.pr(""" + preamble {= + %s + =}""".formatted(FedTargetExtensionFactory.getExtension(federate.target).generatePreamble( + federate, fileConfig, federationRTIProperties, errorReporter + )) + ); return preambleCode.getCode(); } diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 559a3d02ba..e36fbcb08d 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -689,6 +689,12 @@ private void generateCodeFor( generateSelfStructs(main); generateReactorInstance(main); + if (targetConfig.fedSetupPreamble != null) { + if (targetLanguageIsCpp()) code.pr("extern \"C\" {"); + code.pr("#include \"" + targetConfig.fedSetupPreamble + "\""); + if (targetLanguageIsCpp()) code.pr("}"); + } + // If there are timers, create a table of timers to be initialized. code.pr(CTimerGenerator.generateDeclarations(timerCount)); @@ -2048,13 +2054,6 @@ protected String generateTopLevelPreambles() { code.pr("#ifndef TOP_LEVEL_PREAMBLE_H"); code.pr("#define TOP_LEVEL_PREAMBLE_H"); - // preamble for federated execution setup - if (targetConfig.fedSetupPreamble != null) { - if (targetLanguageIsCpp()) code.pr("extern \"C\" {"); - code.pr("#include \"" + targetConfig.fedSetupPreamble + "\""); - if (targetLanguageIsCpp()) code.pr("}"); - } - // user preambles if (this.mainDef != null) { var mainModel = (Model) toDefinition(mainDef.getReactorClass()).eContainer(); diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 56440f2668..9474be1358 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -305,13 +305,7 @@ protected String generateTopLevelPreambles() { for (Model m : models) { pythonPreamble.pr(PythonPreambleGenerator.generatePythonPreambles(m.getPreambles())); } - - // C preamble for federated execution setup - String ret = ""; - if (targetConfig.fedSetupPreamble != null) { - ret = "#include \"" + targetConfig.fedSetupPreamble + "\""; - } - return ret; + return ""; } @Override From 880ae35bd625125f1b284497e19b5490afb9ba35 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 16:06:22 -0800 Subject: [PATCH 37/92] Fix issue with modal models. It is bad that I had to do this. We should have an intermediate representation that is more useful than what is generated by the framework. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index e36fbcb08d..3a7f18029b 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1072,7 +1072,11 @@ protected void generateReactorClassHeaders(Reactor reactor, String headerName, C header.pr("}"); } src.pr("#include \"" + headerName + "\""); - new HashSet<>(reactor.getInstantiations()).stream() + Stream.concat( + reactor.getInstantiations().stream(), + reactor.getModes().stream().flatMap(it -> it.getInstantiations().stream()) + ) + .collect(Collectors.toSet()).stream() .map(Instantiation::getReactorClass) .map(ASTUtils::toDefinition).map(CUtil::getName) .map(name -> "#include \"" + name + ".h\"") From 59b686c8e84a9d7a97efadeaf11075ef94c87ec2 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 16:52:23 -0800 Subject: [PATCH 38/92] Do not generate code for uninstantiated reactors. --- org.lflang/src/org/lflang/ASTUtils.java | 10 ++++++++++ .../src/org/lflang/generator/c/CGenerator.java | 4 +++- test/C/src/DeadlinePriority.lf | 3 ++- test/C/src/ParameterHierarchy.lf | 2 +- test/C/src/StructAsState.lf | 13 +++++++------ 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/org.lflang/src/org/lflang/ASTUtils.java b/org.lflang/src/org/lflang/ASTUtils.java index 1384b3c852..7ed73c82ec 100644 --- a/org.lflang/src/org/lflang/ASTUtils.java +++ b/org.lflang/src/org/lflang/ASTUtils.java @@ -58,6 +58,7 @@ import org.lflang.ast.ToText; import org.lflang.generator.CodeMap; import org.lflang.generator.InvalidSourceException; +import org.lflang.generator.ReactorInstance; import org.lflang.lf.Action; import org.lflang.lf.Assignment; import org.lflang.lf.AttrParm; @@ -447,6 +448,15 @@ public static List allModes(Reactor definition) { return ASTUtils.collectElements(definition, featurePackage.getReactor_Modes()); } + public static List recursiveChildren(ReactorInstance r) { + List ret = new ArrayList<>(); + ret.add(r.reactorDefinition); + for (var child: r.children) { + ret.addAll(recursiveChildren(child)); + } + return ret; + } + /** * Return all the superclasses of the specified reactor * in deepest-first order. For example, if A extends B and C, and diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 3a7f18029b..6eddec32a4 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -521,7 +521,9 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { // If cmake is requested, generate the CMakeLists.txt if (targetConfig.platformOptions.platform != Platform.ARDUINO) { var cmakeFile = fileConfig.getSrcGenPath() + File.separator + "CMakeLists.txt"; - var sources = reactors.stream().map(CUtil::getName).map(it -> it + (CCppMode ? ".cpp" : ".c")).collect(Collectors.toList()); + var sources = new HashSet<>(ASTUtils.recursiveChildren(main)).stream() + .map(CUtil::getName).map(it -> it + (CCppMode ? ".cpp" : ".c")) + .collect(Collectors.toList()); sources.add(cFilename); var cmakeCode = cmakeGenerator.generateCMakeCode( sources, diff --git a/test/C/src/DeadlinePriority.lf b/test/C/src/DeadlinePriority.lf index 723a29b754..2aa5c8136f 100644 --- a/test/C/src/DeadlinePriority.lf +++ b/test/C/src/DeadlinePriority.lf @@ -4,9 +4,10 @@ target C { threading: false } -preamble {= int global_cnt = 0; =} +preamble {= extern int global_cnt; =} reactor NoDeadline { + preamble {= int global_cnt = 0; =} timer t(0 msec, 100 msec) reaction(t) {= global_cnt++; =} diff --git a/test/C/src/ParameterHierarchy.lf b/test/C/src/ParameterHierarchy.lf index 433948bd2b..9be39a13a4 100644 --- a/test/C/src/ParameterHierarchy.lf +++ b/test/C/src/ParameterHierarchy.lf @@ -4,7 +4,7 @@ target C reactor Deep(p: int(0)) { reaction(startup) {= if (self->p != 42) { - lf_print_error_and_exit("Parameter value is %d. Should have been 42."); + lf_print_error_and_exit("Parameter value is %d. Should have been 42.", self->p); } else { lf_print("Success."); } diff --git a/test/C/src/StructAsState.lf b/test/C/src/StructAsState.lf index b57b15d07b..8e89854cb6 100644 --- a/test/C/src/StructAsState.lf +++ b/test/C/src/StructAsState.lf @@ -2,13 +2,14 @@ // value. target C +preamble {= + typedef struct hello_t { + char* name; + int value; + } hello_t; +=} + main reactor StructAsState { - preamble {= - typedef struct hello_t { - char* name; - int value; - } hello_t; - =} // Notice that target code delimiters are no longer necessary. state s: hello_t("Earth", 42) From e5389159db9b7c56208ff0d9655cdd5ed6781e38 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 3 Mar 2023 16:52:58 -0800 Subject: [PATCH 39/92] Repair user-facing generated header files. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 3 ++- .../org/lflang/generator/c/CReactorHeaderFileGenerator.java | 2 +- test/C/c/count.c | 2 +- test/C/c/sendreceive.c | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 6eddec32a4..f4fc5cb975 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1073,6 +1073,7 @@ protected void generateReactorClassHeaders(Reactor reactor, String headerName, C src.pr("}"); header.pr("}"); } + src.pr("#include \"include/" + CReactorHeaderFileGenerator.outputPath(fileConfig, reactor) + "\""); src.pr("#include \"" + headerName + "\""); Stream.concat( reactor.getInstantiations().stream(), @@ -1670,7 +1671,7 @@ public void processProtoFile(String filename) { * {@link #variableStructType(TriggerInstance)}. */ public static String variableStructType(Variable variable, Reactor reactor, boolean userFacing) { - return (userFacing ? reactor.getName() : CUtil.getName(reactor)) +"_"+variable.getName()+"_t"; + return (userFacing ? reactor.getName().toLowerCase() : CUtil.getName(reactor)) +"_"+variable.getName()+"_t"; } /** diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index e131560834..9aa6f7b7ee 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -88,7 +88,7 @@ private static String reactionParameters(CTypes types, Reaction r, Reactor react public static String reactionArguments(CTypes types, Reaction r, Reactor reactor) { return Stream.concat(Stream.of(getApiSelfStruct(reactor)), ioTypedVariableStream(r) - .map(TypedVariable::getName)) + .map(it -> String.format("((%s*) %s)", CGenerator.variableStructType(it, reactor, true), it.getName()))) .collect(Collectors.joining(", ")); } diff --git a/test/C/c/count.c b/test/C/c/count.c index 80f7a1e2a1..2bc5378b7d 100644 --- a/test/C/c/count.c +++ b/test/C/c/count.c @@ -1,5 +1,5 @@ #include -#include "../include/Count.h" +#include "../include/Count/Count.h" void increment(count_self_t* self) { printf("in increment, count=%d\n", self->count); diff --git a/test/C/c/sendreceive.c b/test/C/c/sendreceive.c index 603146d473..5f4c19f896 100644 --- a/test/C/c/sendreceive.c +++ b/test/C/c/sendreceive.c @@ -1,5 +1,5 @@ -#include "../include/Print.h" -#include "../include/Check.h" +#include "../include/IntPrint/Print.h" +#include "../include/IntPrint/Check.h" #include "../include/api/set.h" void send(print_self_t* self, print_out_t* out) { From 78a45713aeff21e1f303b45a05bb965c3cae5cd6 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 4 Mar 2023 01:00:31 -0800 Subject: [PATCH 40/92] Attempt to pass test with imported preamble. --- .../lflang/generator/c/CCmakeGenerator.java | 1 + .../org/lflang/generator/c/CGenerator.java | 20 +++++++------------ .../c/CReactorHeaderFileGenerator.java | 10 +++++++--- .../generator/python/PythonGenerator.java | 3 ++- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CCmakeGenerator.java b/org.lflang/src/org/lflang/generator/c/CCmakeGenerator.java index f5e7187233..c8ee78ecf6 100644 --- a/org.lflang/src/org/lflang/generator/c/CCmakeGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CCmakeGenerator.java @@ -212,6 +212,7 @@ CodeBuilder generateCMakeCode( cMakeCode.pr("target_link_libraries(${LF_MAIN_TARGET} PRIVATE core)"); + cMakeCode.pr("target_include_directories(${LF_MAIN_TARGET} PUBLIC .)"); cMakeCode.pr("target_include_directories(${LF_MAIN_TARGET} PUBLIC include/)"); cMakeCode.pr("target_include_directories(${LF_MAIN_TARGET} PUBLIC include/api)"); cMakeCode.pr("target_include_directories(${LF_MAIN_TARGET} PUBLIC include/core)"); diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index f4fc5cb975..943ba0a4bf 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -47,6 +47,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.xbase.lib.Exceptions; import org.eclipse.xtext.xbase.lib.IterableExtensions; @@ -843,11 +844,6 @@ private void inspectReactorEResource(ReactorDecl reactor) { if (lfResource != null) { copyUserFiles(lfResource.getTargetConfig(), lfResource.getFileConfig()); } - // Extract the contents of the imported file for the preambles - var contents = toDefinition(reactor).eResource().getContents(); - var model = (Model) contents.get(0); - // Add the preambles from the imported .lf file - toDefinition(reactor).getPreambles().addAll(model.getPreambles()); } } @@ -960,7 +956,7 @@ private void generateHeaders() throws IOException { false ); for (Reactor r : reactors) { - CReactorHeaderFileGenerator.doGenerate(types, r, fileConfig, this::generateAuxiliaryStructs); + CReactorHeaderFileGenerator.doGenerate(types, r, fileConfig, this::generateAuxiliaryStructs, this::generateTopLevelPreambles); } FileUtil.copyDirectory(fileConfig.getIncludePath(), fileConfig.getSrcGenPath().resolve("include"), false); } @@ -1051,7 +1047,7 @@ private void generateReactorClass(Reactor reactor) throws IOException { header.pr("#ifndef " + guardMacro); header.pr("#define " + guardMacro); generateReactorClassHeaders(reactor, headerName, header, src); - header.pr(generateTopLevelPreambles()); + header.pr(generateTopLevelPreambles(reactor)); generateUserPreamblesForReactor(reactor, src); generateReactorClassBody(reactor, header, src); header.pr("#endif // " + guardMacro); @@ -2056,17 +2052,15 @@ public String generateDirectives() { /** * Generate top-level preamble code. */ - protected String generateTopLevelPreambles() { + protected String generateTopLevelPreambles(EObject reactor) { CodeBuilder code = new CodeBuilder(); code.pr("#ifndef TOP_LEVEL_PREAMBLE_H"); code.pr("#define TOP_LEVEL_PREAMBLE_H"); // user preambles - if (this.mainDef != null) { - var mainModel = (Model) toDefinition(mainDef.getReactorClass()).eContainer(); - for (Preamble p : mainModel.getPreambles()) { - code.pr(toText(p.getCode())); - } + var mainModel = (Model) reactor.eContainer(); + for (Preamble p : mainModel.getPreambles()) { + code.pr(toText(p.getCode())); } code.pr("#endif"); return code.toString(); diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 9aa6f7b7ee..80bea1ca43 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -3,9 +3,12 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Objects; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.emf.ecore.EObject; + import org.lflang.generator.CodeBuilder; import org.lflang.lf.Parameter; import org.lflang.lf.Port; @@ -30,13 +33,14 @@ public static Path outputPath(CFileConfig fileConfig, Reactor r) { .resolve(r.getName() + ".h"); } - public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator) throws IOException { - String contents = generateHeaderFile(types, r, generator); + public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator, Function topLevelPreamble) throws IOException { + String contents = generateHeaderFile(types, r, generator, topLevelPreamble.apply(r)); FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(outputPath(fileConfig, r))); } - private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator) { + private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator, String topLevelPreamble) { CodeBuilder builder = new CodeBuilder(); appendIncludeGuard(builder, r); + builder.pr(topLevelPreamble); appendPoundIncludes(builder); appendSelfStruct(builder, types, r); generator.generate(builder, r, true); diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 9474be1358..7a23b79b21 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -35,6 +35,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.xbase.lib.Exceptions; @@ -289,7 +290,7 @@ public String generateDirectives() { * execution setup preamble specified in the target config. */ @Override - protected String generateTopLevelPreambles() { + protected String generateTopLevelPreambles(EObject ignored) { // user preambles Set models = new LinkedHashSet<>(); for (Reactor r : ASTUtils.convertToEmptyListIfNull(reactors)) { From 6eb0f04b89ee12f65b62c813c49ac9fcdf8f1cd3 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 8 Mar 2023 12:36:54 -0800 Subject: [PATCH 41/92] Get federated smoke test to pass again. --- .../federated/extensions/CExtension.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/extensions/CExtension.java b/org.lflang/src/org/lflang/federated/extensions/CExtension.java index 54961058d8..ed28b0b174 100644 --- a/org.lflang/src/org/lflang/federated/extensions/CExtension.java +++ b/org.lflang/src/org/lflang/federated/extensions/CExtension.java @@ -108,7 +108,7 @@ public void initializeTargetConfig( federate.targetConfig.setByUser.add(TargetProperty.THREADING); // Include the fed setup file for this federate in the target property - String relPath = "include" + File.separator + "_" + federate.name + "_preamble.h"; + String relPath = getPreamblePath(federate); federate.targetConfig.fedSetupPreamble = relPath; federate.targetConfig.setByUser.add(TargetProperty.FED_SETUP); } @@ -480,7 +480,7 @@ public String getNetworkBufferType() { } /** - * Add preamble to a separate file `include/_federateName_preamble.h` to set up federated execution. + * Add preamble to a separate file to set up federated execution. * Return an empty string since no code generated needs to go in the source. */ @Override @@ -490,9 +490,8 @@ public String generatePreamble( LinkedHashMap federationRTIProperties, ErrorReporter errorReporter ) throws IOException { - // Put the C preamble in a `include/_federate.name + _preamble.h` file String cPreamble = makePreamble(federate, fileConfig, federationRTIProperties, errorReporter); - String relPath = "include" + File.separator + "_" + federate.name + "_preamble.h"; + String relPath = getPreamblePath(federate); Path fedPreamblePath = fileConfig.getSrcPath().resolve(relPath); Files.createDirectories(fedPreamblePath.getParent()); try (var writer = Files.newBufferedWriter(fedPreamblePath)) { @@ -520,12 +519,12 @@ protected String makePreamble( var code = new CodeBuilder(); -// code.pr("#include \"core/federated/federate.h\""); -// code.pr("#include \"core/federated/net_common.h\""); -// code.pr("#include \"core/federated/net_util.h\""); -// code.pr("#include \"core/threaded/reactor_threaded.h\""); -// code.pr("#include \"core/utils/util.h\""); -// code.pr("extern federate_instance_t _fed;"); + code.pr("#include \"core/federated/federate.h\""); + code.pr("#include \"core/federated/net_common.h\""); + code.pr("#include \"core/federated/net_util.h\""); + code.pr("#include \"core/threaded/reactor_threaded.h\""); + code.pr("#include \"core/utils/util.h\""); + code.pr("extern federate_instance_t _fed;"); // Generate function to return a pointer to the action trigger_t // that handles incoming network messages destined to the specified @@ -760,5 +759,7 @@ private String generateCodeForPhysicalActions(FederateInstance federate, ErrorRe } return code.getCode(); } - + private String getPreamblePath(FederateInstance f) { + return "include" + File.separator + "_" + f.name + "_preamble.h"; + } } From a857373b0e5839f6d85c1f29aca81b79cae5a642 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 8 Mar 2023 13:17:26 -0800 Subject: [PATCH 42/92] Get CCPP smoke test to pass again. --- .../generator/c/CReactorHeaderFileGenerator.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 80bea1ca43..b947f3ca67 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -58,10 +58,16 @@ private static void appendIncludeGuard(CodeBuilder builder, Reactor r) { } private static void appendPoundIncludes(CodeBuilder builder) { builder.pr(""" - #include "../include/api/api.h" - #include "../include/api/set.h" - #include "../include/core/reactor.h" - """); + #ifdef __cplusplus + extern "C" { + #endif + #include "../include/api/api.h" + #include "../include/api/set.h" + #include "../include/core/reactor.h" + #ifdef __cplusplus + } + #endif + """); } private static String userFacingSelfType(Reactor r) { From 1657031dfa8b6264f1e9af4deea3d39d930374d7 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 8 Mar 2023 13:43:40 -0800 Subject: [PATCH 43/92] Address failing serialization test. --- .../org/lflang/generator/c/CGenerator.java | 71 ++++--------------- 1 file changed, 15 insertions(+), 56 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 943ba0a4bf..ce1ed29dde 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1974,58 +1974,10 @@ protected void setUpGeneralParameters() { pickCompilePlatform(); } - -// // Perform set up that does not generate code -// protected void setUpFederateSpecificParameters(FederateInstance federate, CodeBuilder commonCode) { -// currentFederate = federate; -// if (isFederated) { -// // Reset the cmake-includes and files, to be repopulated for each federate individually. -// // This is done to enable support for separately -// // adding cmake-includes/files for different federates to prevent linking and mixing -// // all federates' supporting libraries/files together. -// targetConfig.cmakeIncludes.clear(); -// targetConfig.cmakeIncludesWithoutPath.clear(); -// targetConfig.fileNames.clear(); -// targetConfig.filesNamesWithoutPath.clear(); -// -// // Re-apply the cmake-include target property of the main .lf file. -// var target = GeneratorUtils.findTarget(mainDef.getReactorClass().eResource()); -// if (target.getConfig() != null) { -// // Update the cmake-include -// TargetProperty.updateOne( -// this.targetConfig, -// TargetProperty.CMAKE_INCLUDE, -// convertToEmptyListIfNull(target.getConfig().getPairs()), -// errorReporter -// ); -// // Update the files -// TargetProperty.updateOne( -// this.targetConfig, -// TargetProperty.FILES, -// convertToEmptyListIfNull(target.getConfig().getPairs()), -// errorReporter -// ); -// } -// // Clear out previously generated code. -// code = new CodeBuilder(commonCode); -// initializeTriggerObjects = new CodeBuilder(); -// // Enable clock synchronization if the federate -// // is not local and clock-sync is enabled -// initializeClockSynchronization(); -// startTimeStep = new CodeBuilder(); -// } -// } - protected void handleProtoFiles() { // Handle .proto files. for (String file : targetConfig.protoFiles) { this.processProtoFile(file); - var dotIndex = file.lastIndexOf("."); - var rootFilename = file; - if (dotIndex > 0) { - rootFilename = file.substring(0, dotIndex); - } - code.pr("#include " + addDoubleQuotes(rootFilename + ".pb-c.h")); } } @@ -2053,17 +2005,24 @@ public String generateDirectives() { * Generate top-level preamble code. */ protected String generateTopLevelPreambles(EObject reactor) { - CodeBuilder code = new CodeBuilder(); - code.pr("#ifndef TOP_LEVEL_PREAMBLE_H"); - code.pr("#define TOP_LEVEL_PREAMBLE_H"); - - // user preambles + CodeBuilder builder = new CodeBuilder(); + builder.pr("#ifndef TOP_LEVEL_PREAMBLE_H"); + builder.pr("#define TOP_LEVEL_PREAMBLE_H"); var mainModel = (Model) reactor.eContainer(); for (Preamble p : mainModel.getPreambles()) { - code.pr(toText(p.getCode())); + builder.pr(toText(p.getCode())); } - code.pr("#endif"); - return code.toString(); + for (String file : targetConfig.protoFiles) { + var dotIndex = file.lastIndexOf("."); + var rootFilename = file; + if (dotIndex > 0) { + rootFilename = file.substring(0, dotIndex); + } + code.pr("#include " + addDoubleQuotes(rootFilename + ".pb-c.h")); + builder.pr("#include " + addDoubleQuotes(rootFilename + ".pb-c.h")); + } + builder.pr("#endif"); + return builder.toString(); } protected boolean targetLanguageIsCpp() { From ee90c33edb8374e423dae69fcfb11f8b52a2cc07 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 8 Mar 2023 14:15:12 -0800 Subject: [PATCH 44/92] Address failing benchmark test. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index ce1ed29dde..b45779b7a7 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -2006,9 +2006,10 @@ public String generateDirectives() { */ protected String generateTopLevelPreambles(EObject reactor) { CodeBuilder builder = new CodeBuilder(); - builder.pr("#ifndef TOP_LEVEL_PREAMBLE_H"); - builder.pr("#define TOP_LEVEL_PREAMBLE_H"); var mainModel = (Model) reactor.eContainer(); + var guard = "TOP_LEVEL_PREAMBLE_" + mainModel.hashCode() + "_H"; + builder.pr("#ifndef " + guard); + builder.pr("#define " + guard); for (Preamble p : mainModel.getPreambles()) { builder.pr(toText(p.getCode())); } From 398ff8334a362e5a9cfde44c24a566630bfea583 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 8 Mar 2023 14:38:47 -0800 Subject: [PATCH 45/92] Address failing Python federated test. --- .../org/lflang/tests/lsp/MockReportProgress.java | 2 +- .../lflang/federated/extensions/CExtension.java | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/org.lflang.tests/src/org/lflang/tests/lsp/MockReportProgress.java b/org.lflang.tests/src/org/lflang/tests/lsp/MockReportProgress.java index 901f0e6154..014fcc7276 100644 --- a/org.lflang.tests/src/org/lflang/tests/lsp/MockReportProgress.java +++ b/org.lflang.tests/src/org/lflang/tests/lsp/MockReportProgress.java @@ -17,7 +17,7 @@ public MockReportProgress() { @Override public void apply(String message, Integer percentage) { - System.out.printf("%s [%d -> %d]%n", message, previousPercentProgress, percentage); + System.out.printf("MockReportProgress: %s [%d -> %d]%n", message, previousPercentProgress, percentage); if (percentage == null) return; if (percentage < previousPercentProgress || percentage < 0 || percentage > 100) failed = true; previousPercentProgress = percentage; diff --git a/org.lflang/src/org/lflang/federated/extensions/CExtension.java b/org.lflang/src/org/lflang/federated/extensions/CExtension.java index ed28b0b174..87d14d2fa3 100644 --- a/org.lflang/src/org/lflang/federated/extensions/CExtension.java +++ b/org.lflang/src/org/lflang/federated/extensions/CExtension.java @@ -38,6 +38,7 @@ import org.lflang.ASTUtils; import org.lflang.ErrorReporter; import org.lflang.InferredType; +import org.lflang.Target; import org.lflang.TargetProperty; import org.lflang.TargetProperty.CoordinationType; import org.lflang.TimeValue; @@ -498,12 +499,14 @@ public String generatePreamble( writer.write(cPreamble); } var includes = new CodeBuilder(); - includes.pr("#include \"core/federated/federate.h\""); - includes.pr("#include \"core/federated/net_common.h\""); - includes.pr("#include \"core/federated/net_util.h\""); - includes.pr("#include \"core/threaded/reactor_threaded.h\""); - includes.pr("#include \"core/utils/util.h\""); - includes.pr("extern federate_instance_t _fed;"); + if (federate.targetConfig.target == Target.C) { + includes.pr("#include \"core/federated/federate.h\""); + includes.pr("#include \"core/federated/net_common.h\""); + includes.pr("#include \"core/federated/net_util.h\""); + includes.pr("#include \"core/threaded/reactor_threaded.h\""); + includes.pr("#include \"core/utils/util.h\""); + includes.pr("extern federate_instance_t _fed;"); + } return includes.toString(); } From abd1ffebede647428e029bbcd6494d45dd270471 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 8 Mar 2023 14:56:23 -0800 Subject: [PATCH 46/92] Address misc failing C tests. Mostly these tests are failing due to my changes to how preambles are handled. --- test/C/src/DeadlineWithAfterDelay.lf | 4 ++- test/C/src/DeadlineWithBanks.lf | 4 ++- .../DistributedPhysicalActionUpstream.lf | 32 +++++++++++-------- .../DistributedPhysicalActionUpstreamLong.lf | 32 +++++++++++-------- ...oopDistributedCentralizedPhysicalAction.lf | 24 ++++++++------ .../federated/LoopDistributedDecentralized.lf | 24 ++++++++------ test/C/src/federated/LoopDistributedDouble.lf | 25 ++++++++------- test/C/src/multiport/BankIndexInitializer.lf | 4 ++- test/C/src/token/include/array.h | 6 ++-- 9 files changed, 91 insertions(+), 64 deletions(-) diff --git a/test/C/src/DeadlineWithAfterDelay.lf b/test/C/src/DeadlineWithAfterDelay.lf index d1b87860ac..5e33e129e6 100644 --- a/test/C/src/DeadlineWithAfterDelay.lf +++ b/test/C/src/DeadlineWithAfterDelay.lf @@ -4,9 +4,11 @@ target C { threading: false } -preamble {= int global_cnt = 0; =} +preamble {= extern int global_cnt; =} reactor Source { + preamble {= int global_cnt = 0; =} + output out: int timer t(0 msec, 100 msec) diff --git a/test/C/src/DeadlineWithBanks.lf b/test/C/src/DeadlineWithBanks.lf index 266208cdac..b503ba0269 100644 --- a/test/C/src/DeadlineWithBanks.lf +++ b/test/C/src/DeadlineWithBanks.lf @@ -9,9 +9,11 @@ target C { build-type: Debug } -preamble {= volatile int global_cnt = 0; =} +preamble {= extern volatile int global_cnt; =} reactor Bank(bank_index: int(0)) { + preamble {= volatile int global_cnt = 0; =} + timer t(0, 100 msec) output out: int diff --git a/test/C/src/federated/DistributedPhysicalActionUpstream.lf b/test/C/src/federated/DistributedPhysicalActionUpstream.lf index 2cc6735884..f4cfc461b7 100644 --- a/test/C/src/federated/DistributedPhysicalActionUpstream.lf +++ b/test/C/src/federated/DistributedPhysicalActionUpstream.lf @@ -13,22 +13,28 @@ import PassThrough from "../lib/PassThrough.lf" import TestCount from "../lib/TestCount.lf" preamble {= - int _counter = 1; - void callback(void *a) { - lf_schedule_int(a, 0, _counter++); - } - // Simulate time passing before a callback occurs. - void* take_time(void* a) { - while (_counter < 15) { - instant_t sleep_time = MSEC(10); - lf_sleep(sleep_time); - callback(a); - } - return NULL; - } + extern int _counter; + void callback(void *a); + void* take_time(void* a); =} reactor WithPhysicalAction { + preamble {= + int _counter = 1; + void callback(void *a) { + lf_schedule_int(a, 0, _counter++); + } + // Simulate time passing before a callback occurs. + void* take_time(void* a) { + while (_counter < 15) { + instant_t sleep_time = MSEC(10); + lf_sleep(sleep_time); + callback(a); + } + return NULL; + } + =} + output out: int state thread_id: lf_thread_t(0) physical action act(0): int diff --git a/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf b/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf index 0a6ee31e62..56dc37126e 100644 --- a/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf +++ b/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf @@ -11,24 +11,28 @@ target C { import PassThrough from "../lib/PassThrough.lf" import TestCount from "../lib/TestCount.lf" - preamble {= - int _counter = 1; - void callback(void *a) { - lf_schedule_int(a, 0, _counter++); - } - // Simulate time passing before a callback occurs. - void* take_time(void* a) { - while (_counter < 20) { - instant_t sleep_time = USEC(50); - lf_sleep(sleep_time); - callback(a); - } - return NULL; - } + extern int _counter; + void callback(void *a); + void* take_time(void* a); =} reactor WithPhysicalAction { + preamble {= + int _counter = 1; + void callback(void *a) { + lf_schedule_int(a, 0, _counter++); + } + // Simulate time passing before a callback occurs. + void* take_time(void* a) { + while (_counter < 20) { + instant_t sleep_time = USEC(50); + lf_sleep(sleep_time); + callback(a); + } + return NULL; + } + =} output out: int state thread_id: lf_thread_t(0) physical action act(0): int diff --git a/test/C/src/federated/LoopDistributedCentralizedPhysicalAction.lf b/test/C/src/federated/LoopDistributedCentralizedPhysicalAction.lf index e622e31979..9b8abc955d 100644 --- a/test/C/src/federated/LoopDistributedCentralizedPhysicalAction.lf +++ b/test/C/src/federated/LoopDistributedCentralizedPhysicalAction.lf @@ -15,19 +15,23 @@ target C { preamble {= #include // Defines sleep() - bool stop = false; - // Thread to trigger an action once every second. - void* ping(void* actionref) { - while(!stop) { - lf_print("Scheduling action."); - lf_schedule(actionref, 0); - sleep(1); - } - return NULL; - } + extern bool stop; + void* ping(void* actionref); =} reactor Looper(incr: int(1), delay: time(0 msec)) { + preamble {= + bool stop = false; + // Thread to trigger an action once every second. + void* ping(void* actionref) { + while(!stop) { + lf_print("Scheduling action."); + lf_schedule(actionref, 0); + sleep(1); + } + return NULL; + } + =} input in: int output out: int physical action a(delay) diff --git a/test/C/src/federated/LoopDistributedDecentralized.lf b/test/C/src/federated/LoopDistributedDecentralized.lf index c2d4bcb297..1e134a2ed1 100644 --- a/test/C/src/federated/LoopDistributedDecentralized.lf +++ b/test/C/src/federated/LoopDistributedDecentralized.lf @@ -11,19 +11,23 @@ target C { preamble {= #include // Defines sleep() - bool stop = false; - // Thread to trigger an action once every second. - void* ping(void* actionref) { - while(!stop) { - lf_print("Scheduling action."); - lf_schedule(actionref, 0); - sleep(1); - } - return NULL; - } + extern bool stop; + void* ping(void* actionref); =} reactor Looper(incr: int(1), delay: time(0 msec), stp_offset: time(0)) { + preamble {= + bool stop = false; + // Thread to trigger an action once every second. + void* ping(void* actionref) { + while(!stop) { + lf_print("Scheduling action."); + lf_schedule(actionref, 0); + sleep(1); + } + return NULL; + } + =} input in: int output out: int physical action a(stp_offset) diff --git a/test/C/src/federated/LoopDistributedDouble.lf b/test/C/src/federated/LoopDistributedDouble.lf index bba7c7ffaa..4389a661fc 100644 --- a/test/C/src/federated/LoopDistributedDouble.lf +++ b/test/C/src/federated/LoopDistributedDouble.lf @@ -12,22 +12,25 @@ target C { }, timeout: 5 sec } - preamble {= #include // Defines sleep() - bool stop = false; - // Thread to trigger an action once every second. - void* ping(void* actionref) { - while(!stop) { - lf_print("Scheduling action."); - lf_schedule(actionref, 0); - sleep(1); - } - return NULL; - } + extern bool stop; + void* ping(void* actionref); =} reactor Looper(incr: int(1), delay: time(0 msec)) { + preamble {= + bool stop = false; + // Thread to trigger an action once every second. + void* ping(void* actionref) { + while(!stop) { + lf_print("Scheduling action."); + lf_schedule(actionref, 0); + sleep(1); + } + return NULL; + } + =} input in: int input in2: int output out: int diff --git a/test/C/src/multiport/BankIndexInitializer.lf b/test/C/src/multiport/BankIndexInitializer.lf index b9b8803943..a5a30330e1 100644 --- a/test/C/src/multiport/BankIndexInitializer.lf +++ b/test/C/src/multiport/BankIndexInitializer.lf @@ -1,9 +1,11 @@ // Test bank of reactors to multiport input with id parameter in the bank. target C -preamble {= int table[] = {4, 3, 2, 1}; =} +preamble {= extern int table[4]; =} reactor Source(bank_index: int(0), value: int(0)) { + preamble {= int table[] = {4, 3, 2, 1}; =} + output out: int reaction(startup) -> out {= lf_set(out, self->value); =} diff --git a/test/C/src/token/include/array.h b/test/C/src/token/include/array.h index c1fd1b4991..5ea8d5230b 100644 --- a/test/C/src/token/include/array.h +++ b/test/C/src/token/include/array.h @@ -21,7 +21,7 @@ typedef struct int_array_t { * @param length The length. * @return A pointer to the array struct. */ -int_array_t* int_array_constructor(size_t length) { +static inline int_array_t* int_array_constructor(size_t length) { int_array_t* result = (int_array_t*) malloc(sizeof(int_array_t)); result->data = (int*) calloc(length, sizeof(int)); result->length = length; @@ -36,7 +36,7 @@ int_array_t* int_array_constructor(size_t length) { * @param array The array to copy. * @return void* */ -void* int_array_copy_constructor(void* array) { +static inline void* int_array_copy_constructor(void* array) { int_array_t* source = (int_array_t*) array; int_array_t* copy = (int_array_t*) malloc(sizeof(int_array_t)); copy->data = (int*) calloc(source->length, sizeof(int)); @@ -54,7 +54,7 @@ void* int_array_copy_constructor(void* array) { * when their reference count decrements to zero. * @param array The array to free. */ -void int_array_destructor(void* array) { +static inline void int_array_destructor(void* array) { free(((int_array_t*) array)->data); free(array); } From d3cfb00551713a3e000540cf33bfb4b2d9a741b4 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 8 Mar 2023 15:38:06 -0800 Subject: [PATCH 47/92] Format C tests. --- .../DistributedPhysicalActionUpstreamLong.lf | 1 + test/C/src/federated/LoopDistributedDouble.lf | 1 + ...ributedDecentralizedPrecedenceHierarchy.lf | 38 ++++++++++--------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf b/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf index 56dc37126e..fee8f3f014 100644 --- a/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf +++ b/test/C/src/federated/DistributedPhysicalActionUpstreamLong.lf @@ -11,6 +11,7 @@ target C { import PassThrough from "../lib/PassThrough.lf" import TestCount from "../lib/TestCount.lf" + preamble {= extern int _counter; void callback(void *a); diff --git a/test/C/src/federated/LoopDistributedDouble.lf b/test/C/src/federated/LoopDistributedDouble.lf index 4389a661fc..c92fed5d1e 100644 --- a/test/C/src/federated/LoopDistributedDouble.lf +++ b/test/C/src/federated/LoopDistributedDouble.lf @@ -12,6 +12,7 @@ target C { }, timeout: 5 sec } + preamble {= #include // Defines sleep() extern bool stop; diff --git a/test/C/src/federated/failing/LoopDistributedDecentralizedPrecedenceHierarchy.lf b/test/C/src/federated/failing/LoopDistributedDecentralizedPrecedenceHierarchy.lf index 6cf9236901..2bc0fdfd0d 100644 --- a/test/C/src/federated/failing/LoopDistributedDecentralizedPrecedenceHierarchy.lf +++ b/test/C/src/federated/failing/LoopDistributedDecentralizedPrecedenceHierarchy.lf @@ -1,6 +1,7 @@ /** - * This tests that the precedence order of reaction invocation is kept - * in the hierarchy of reactors when a feedback loop is present in decentralized coordination. + * This tests that the precedence order of reaction invocation is kept in the + * hierarchy of reactors when a feedback loop is present in decentralized + * coordination. * * @author Edward A. Lee * @author Soroush Bateni @@ -11,37 +12,39 @@ target C { timeout: 4900 msec } -import Contained from "../LoopDistributedCentralizedPrecedenceHierarchy.lf"; +import Contained from "../LoopDistributedCentralizedPrecedenceHierarchy.lf" -reactor Looper(incr:int(1), delay:time(0 msec), stp_offset:time(0)) { - input in:int; - output out:int; - state count:int(0); - timer t(0, 1 sec); +reactor Looper(incr: int(1), delay: time(0 msec), stp_offset: time(0)) { + input in: int + output out: int + state count: int(0) + timer t(0, 1 sec) - c = new Contained(incr = incr); + c = new Contained(incr = incr) + in -> c.in reaction(t) -> out {= lf_set(out, self->count); self->count += self->incr; =} + reaction(in) {= instant_t time_lag = lf_time_physical() - lf_time_logical(); char time_buffer[28]; // 28 bytes is enough for the largest 64 bit number: 9,223,372,036,854,775,807 lf_readable_time(time_buffer, time_lag); lf_print("Received %d. Logical time is behind physical time by %s nsec.", in->value, time_buffer); - =} STP (stp_offset) {= + =} STP(stp_offset) {= instant_t time_lag = lf_time_physical() - lf_time_logical(); char time_buffer[28]; // 28 bytes is enough for the largest 64 bit number: 9,223,372,036,854,775,807 lf_readable_time(time_buffer, time_lag); lf_print("STP offset was violated. Received %d. Logical time is behind physical time by %s nsec.", in->value, time_buffer); - =} deadline (10 msec) {= + =} deadline(10 msec) {= instant_t time_lag = lf_time_physical() - lf_time_logical(); char time_buffer[28]; // 28 bytes is enough for the largest 64 bit number: 9,223,372,036,854,775,807 lf_readable_time(time_buffer, time_lag); lf_print("Deadline miss. Received %d. Logical time is behind physical time by %s nsec.", in->value, time_buffer); =} - in->c.in; + reaction(shutdown) {= lf_print("******* Shutdown invoked."); if (self->count != 5 * self->incr) { @@ -49,9 +52,10 @@ reactor Looper(incr:int(1), delay:time(0 msec), stp_offset:time(0)) { } =} } -federated reactor (delay:time(0)) { - left = new Looper(stp_offset = 5 msec); - right = new Looper(incr = -1, stp_offset = 5 msec); - left.out -> right.in; - right.out -> left.in; + +federated reactor(delay: time(0)) { + left = new Looper(stp_offset = 5 msec) + right = new Looper(incr = -1, stp_offset = 5 msec) + left.out -> right.in + right.out -> left.in } From 2f02042ba818f321e3477c3a8553574c18b4c61b Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 9 Mar 2023 12:15:48 -0800 Subject: [PATCH 48/92] Do not run no_inlining tests as CCpp. --- .github/workflows/ci.yml | 3 +- .../src/org/lflang/tests/TestRegistry.java | 70 +++++++++---------- .../org/lflang/tests/runtime/CCppTest.java | 1 + .../Count.lf | 0 .../IntPrint.lf | 0 5 files changed, 38 insertions(+), 36 deletions(-) rename test/C/src/{bodyless-reactions => no_inlining}/Count.lf (100%) rename test/C/src/{bodyless-reactions => no_inlining}/IntPrint.lf (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d7632cb6b..947ddb704a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,9 +48,10 @@ jobs: # Run the C benchmark tests. c-benchmark-tests: - uses: lf-lang/benchmarks-lingua-franca/.github/workflows/benchmark-tests.yml@c-separate-gen-files + uses: lf-lang/benchmarks-lingua-franca/.github/workflows/benchmark-tests.yml@master with: target: 'C' + benchmarks-ref: 'c-separate-gen-files' needs: cancel # Run language server tests. diff --git a/org.lflang.tests/src/org/lflang/tests/TestRegistry.java b/org.lflang.tests/src/org/lflang/tests/TestRegistry.java index 232e735641..10fa68acaf 100644 --- a/org.lflang.tests/src/org/lflang/tests/TestRegistry.java +++ b/org.lflang.tests/src/org/lflang/tests/TestRegistry.java @@ -32,14 +32,14 @@ /** * A registry to retrieve tests from, organized by target and category. - * + * * @author Marten Lohstroh */ public class TestRegistry { - + static class TestMap { /** - * Registry that maps targets to maps from categories to sets of tests. + * Registry that maps targets to maps from categories to sets of tests. */ protected final Map>> map = new HashMap<>(); @@ -57,7 +57,7 @@ public TestMap() { map.put(target, categories); } } - + /** * Return a set of tests given a target and test category. * @param t The target. @@ -68,26 +68,26 @@ public Set getTests(Target t, TestCategory c) { return this.map.get(t).get(c); } } - + /** * List of directories that should be skipped when indexing test files. Any * test file that has a directory in its path that matches an entry in this * array will not be discovered. */ public static final String[] IGNORED_DIRECTORIES = {"failing", "knownfailed", "failed", "fed-gen"}; - + /** * Path to the root of the repository. */ public static final Path LF_REPO_PATH = Paths.get("").toAbsolutePath(); - + /** * Path to the test directory in the repository. */ public static final Path LF_TEST_PATH = LF_REPO_PATH.resolve("test"); /** - * Internal data structure that stores registered tests. + * Internal data structure that stores registered tests. */ protected static final TestMap registered = new TestMap(); @@ -96,31 +96,31 @@ public Set getTests(Target t, TestCategory c) { * source files with no main reactor are indexed here. */ protected static final TestMap ignored = new TestMap(); - + /** * A map from each test category to a set of tests that is the union of * all registered tests in that category across all targets. */ protected static final Map> allTargets = new HashMap<>(); - + /** * Enumeration of test categories, used to map tests to categories. The * nearest containing directory that matches any of the categories will * determine the category that the test is mapped to. Matching is case * insensitive. - * + * * For example, the following files will all map to THREADED: * - C/threaded/Foo.lf - * - C/THREADED/Foo.lf + * - C/THREADED/Foo.lf * - C/Threaded/Foo.lf - * - C/foo/threaded/Bar.lf - * - C/foo/bar/threaded/Threaded.lf + * - C/foo/threaded/Bar.lf + * - C/foo/bar/threaded/Threaded.lf * - C/federated/threaded/bar.lf - * but the following will not: + * but the following will not: * - C/Foo.lf (maps to COMMON) * - C/Threaded.lf (maps to COMMON) * - C/threaded/federated/foo.lf (maps to FEDERATED) - * + * * @author Marten Lohstroh */ public enum TestCategory { @@ -140,7 +140,7 @@ public enum TestCategory { PROPERTIES(true), /** Tests concerning modal reactors */ MODAL_MODELS(true), - + NO_INLINING(false), // non-shared tests DOCKER(true), DOCKER_FEDERATED(true, "docker" + File.separator + "federated"), @@ -155,7 +155,7 @@ public enum TestCategory { public final boolean isCommon; public final String path; public final TestLevel level ; - + /** * Create a new test category. */ @@ -189,14 +189,14 @@ public String getPath() { /** * Return a header associated with the category. - * + * * @return A header to print in the test report. */ public String getHeader() { return TestBase.THICK_LINE + "Category: " + this.name(); } } - + // Static code that performs the file system traversal and discovers // all .lf files to be included in the registry. static { @@ -220,7 +220,7 @@ public String getHeader() { } else { System.out.println("WARNING: No test directory for target " + target + "\n"); } - + } catch (IOException e) { System.err.println( "ERROR: Caught exception while indexing tests for target " + target); @@ -231,7 +231,7 @@ public String getHeader() { c -> allTargets.get(c).addAll(getRegisteredTests(target, c, false))); } } - + /** * Calling this function forces the lazy initialization of the static code * that indexes all files. It is advisable to do this prior to executing @@ -239,10 +239,10 @@ public String getHeader() { * printed while indexing are printed first. */ public static void initialize() {} - + /** * Return the tests that were indexed for a given target and category. - * + * * @param target The target to get indexed tests for. * @param category The category of tests to include in the returned tests. * @param copy Whether to return copies of the indexed tests instead of the indexed tests themselves. @@ -260,7 +260,7 @@ public static Set getRegisteredTests(Target target, return registered.getTests(target, category); } } - + /** * Return the test that were found but not indexed because they did not * have a main reactor. @@ -275,11 +275,11 @@ public static String getCoverageReport(Target target, TestCategory category) { s.append(TestBase.THIN_LINE); s.append("Ignored: ").append(ignored.size()).append("\n"); s.append(TestBase.THIN_LINE); - + for (LFTest test : ignored) { s.append("No main reactor in: ").append(test).append("\n"); } - + Set own = getRegisteredTests(target, category, false); if (category.isCommon) { Set all = allTargets.get(category); @@ -301,17 +301,17 @@ public static String getCoverageReport(Target target, TestCategory category) { /** * FileVisitor implementation that maintains a stack to map found tests to - * the appropriate category and excludes directories that are listed as + * the appropriate category and excludes directories that are listed as * "ignored" from walks. - * + * * Specifically, when a directory is encountered that matches a category, * this category is pushed onto the stack. Similarly, when the DFS leaves * such a directory, its corresponding category is popped from the stack. * Any test (*.lf) file that is encountered will be mapped to the category - * that is on top of the stack. Initially, the stack has one element that + * that is on top of the stack. Initially, the stack has one element that * is TestCategory.COMMON, meaning that test files in the top-level test * directory for a given target will be mapped to that category. - * + * * @author Marten Lohstroh */ public static class TestDirVisitor extends SimpleFileVisitor { @@ -325,7 +325,7 @@ public static class TestDirVisitor extends SimpleFileVisitor { * The target that all encountered tests belong to. */ protected Target target; - + protected ResourceSet rs; protected Path srcBasePath; @@ -342,7 +342,7 @@ public TestDirVisitor(ResourceSet rs, Target target, Path srcBasePath) { this.target = target; this.srcBasePath = srcBasePath; } - + /** * Push categories onto the stack as appropriate and skip directories * that should be ignored. @@ -363,7 +363,7 @@ public FileVisitResult preVisitDirectory(Path dir, } return CONTINUE; } - + /** * Pop categories from the stack as appropriate. */ @@ -377,7 +377,7 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) { } return CONTINUE; } - + /** * Add test files to the registry if they end with ".lf", but only if they have a main reactor. */ diff --git a/org.lflang.tests/src/org/lflang/tests/runtime/CCppTest.java b/org.lflang.tests/src/org/lflang/tests/runtime/CCppTest.java index d70615c7fd..bd2756a1cb 100644 --- a/org.lflang.tests/src/org/lflang/tests/runtime/CCppTest.java +++ b/org.lflang.tests/src/org/lflang/tests/runtime/CCppTest.java @@ -45,6 +45,7 @@ private static boolean isExcludedFromCCpp(TestCategory category) { excluded |= isMac() && (category == TestCategory.DOCKER_FEDERATED || category == TestCategory.DOCKER); excluded |= category == TestCategory.ZEPHYR; excluded |= category == TestCategory.ARDUINO; + excluded |= category == TestCategory.NO_INLINING; return !excluded; } } diff --git a/test/C/src/bodyless-reactions/Count.lf b/test/C/src/no_inlining/Count.lf similarity index 100% rename from test/C/src/bodyless-reactions/Count.lf rename to test/C/src/no_inlining/Count.lf diff --git a/test/C/src/bodyless-reactions/IntPrint.lf b/test/C/src/no_inlining/IntPrint.lf similarity index 100% rename from test/C/src/bodyless-reactions/IntPrint.lf rename to test/C/src/no_inlining/IntPrint.lf From 4349db5966d32e0bf210c3ff5b7bbdf10906a0c0 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 11 Mar 2023 23:44:02 -0800 Subject: [PATCH 49/92] Update ci.yml. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 947ddb704a..0027212ead 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: # Run the C benchmark tests. c-benchmark-tests: - uses: lf-lang/benchmarks-lingua-franca/.github/workflows/benchmark-tests.yml@master + uses: lf-lang/benchmarks-lingua-franca/.github/workflows/benchmark-tests.yml@main with: target: 'C' benchmarks-ref: 'c-separate-gen-files' From a7e4e42863166693ff8248bf516717a5e03a9b8d Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 20 Mar 2023 23:20:13 -0700 Subject: [PATCH 50/92] Update ci.yml. It is not good that the benchmark tests were not being run against the current branch. We should find a long-term fix for that. --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0027212ead..2e182bae77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,7 @@ jobs: with: target: 'C' benchmarks-ref: 'c-separate-gen-files' + compiler-ref: bodyless-reactions needs: cancel # Run language server tests. From 3cf6b8f33e9835994c9bc8700b8adbeae4475f73 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 21 Mar 2023 09:30:21 -0700 Subject: [PATCH 51/92] Attempt to fix failing C++ federated tests. --- .../src/org/lflang/federated/extensions/CExtension.java | 8 +++++++- org.lflang/src/org/lflang/generator/c/CGenerator.java | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/extensions/CExtension.java b/org.lflang/src/org/lflang/federated/extensions/CExtension.java index 9a0ace9a3e..58b0c1a8a0 100644 --- a/org.lflang/src/org/lflang/federated/extensions/CExtension.java +++ b/org.lflang/src/org/lflang/federated/extensions/CExtension.java @@ -493,13 +493,19 @@ public String generatePreamble( writer.write(cPreamble); } var includes = new CodeBuilder(); - if (federate.targetConfig.target == Target.C) { + if (federate.targetConfig.target != Target.Python) { + includes.pr("#ifdef __cplusplus\n" + + "extern \"C\" {\n" + + "#endif"); includes.pr("#include \"core/federated/federate.h\""); includes.pr("#include \"core/federated/net_common.h\""); includes.pr("#include \"core/federated/net_util.h\""); includes.pr("#include \"core/threaded/reactor_threaded.h\""); includes.pr("#include \"core/utils/util.h\""); includes.pr("extern federate_instance_t _fed;"); + includes.pr("#ifdef __cplusplus\n" + + "}\n" + + "#endif"); } return includes.toString(); diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index b45779b7a7..0d74c9ec60 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1052,7 +1052,8 @@ private void generateReactorClass(Reactor reactor) throws IOException { generateReactorClassBody(reactor, header, src); header.pr("#endif // " + guardMacro); FileUtil.writeToFile(header.toString(), fileConfig.getSrcGenPath().resolve(headerName), true); - var extension = targetConfig.platformOptions.platform == Platform.ARDUINO ? ".ino" : (CCppMode ? ".cpp" : ".c"); + var extension = targetConfig.platformOptions.platform == Platform.ARDUINO ? ".ino" : + CCppMode ? ".cpp" : ".c"; FileUtil.writeToFile(src.toString(), fileConfig.getSrcGenPath().resolve(CUtil.getName(reactor) + extension), true); } From 36c8088655eed5fc5af31ebc8881672fcb92c1df Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Mar 2023 16:17:13 -0700 Subject: [PATCH 52/92] Address failing Python tests. --- .../org/lflang/generator/python/PythonGenerator.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 7a23b79b21..077f848a94 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -279,8 +279,6 @@ public String generateDirectives() { code.prComment("file:/" + FileUtil.toUnixString(fileConfig.srcFile)); code.pr(PythonPreambleGenerator.generateCDefineDirectives( targetConfig, fileConfig.getSrcGenPath(), hasModalReactors)); - code.pr(PythonPreambleGenerator.generateCIncludeStatements( - targetConfig, targetLanguageIsCpp(), hasModalReactors)); return code.toString(); } @@ -306,7 +304,7 @@ protected String generateTopLevelPreambles(EObject ignored) { for (Model m : models) { pythonPreamble.pr(PythonPreambleGenerator.generatePythonPreambles(m.getPreambles())); } - return ""; + return PythonPreambleGenerator.generateCIncludeStatements(targetConfig, targetLanguageIsCpp(), hasModalReactors); } @Override @@ -516,12 +514,6 @@ protected void generateUserPreamblesForReactor(Reactor reactor, CodeBuilder src) // Do nothing } - @Override - protected void generateReactorClassHeaders(Reactor reactor, String headerName, CodeBuilder header, CodeBuilder src) { - header.pr(PythonPreambleGenerator.generateCIncludeStatements(targetConfig, targetLanguageIsCpp(), hasModalReactors)); - super.generateReactorClassHeaders(reactor, headerName, header, src); - } - /** * Generate code that is executed while the reactor instance is being * initialized. From 04da8d2e915b3decc9c4333bc97b920b7f851a82 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Mar 2023 16:56:55 -0700 Subject: [PATCH 53/92] Attempt to fix the file system races in fed-gen. --- .../src/org/lflang/federated/generator/FedGenerator.java | 2 +- org.lflang/src/org/lflang/generator/c/CFileConfig.java | 5 ++++- org.lflang/src/org/lflang/generator/c/CGenerator.java | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/generator/FedGenerator.java b/org.lflang/src/org/lflang/federated/generator/FedGenerator.java index 18d5770165..cd9c2e95d0 100644 --- a/org.lflang/src/org/lflang/federated/generator/FedGenerator.java +++ b/org.lflang/src/org/lflang/federated/generator/FedGenerator.java @@ -288,7 +288,7 @@ private Map compileFederates( Resource res = rs.getResource(URI.createFileURI( fileConfig.getSrcPath().resolve(fed.name + ".lf").toAbsolutePath().toString() ), true); - FileConfig subFileConfig = LFGenerator.createFileConfig(res, fileConfig.getSrcGenPath(), false); + FileConfig subFileConfig = LFGenerator.createFileConfig(res, fileConfig.getSrcGenPath(), true); ErrorReporter subContextErrorReporter = new LineAdjustingErrorReporter(threadSafeErrorReporter, lf2lfCodeMapMap); var props = new Properties(); diff --git a/org.lflang/src/org/lflang/generator/c/CFileConfig.java b/org.lflang/src/org/lflang/generator/c/CFileConfig.java index 37826d585f..362b8645b5 100644 --- a/org.lflang/src/org/lflang/generator/c/CFileConfig.java +++ b/org.lflang/src/org/lflang/generator/c/CFileConfig.java @@ -8,12 +8,15 @@ import org.lflang.FileConfig; public class CFileConfig extends FileConfig { + private final Path includePath; public CFileConfig(Resource resource, Path srcGenBasePath, boolean useHierarchicalBin) throws IOException { super(resource, srcGenBasePath, useHierarchicalBin); + var includeDir = getOutPath().resolve("include"); + includePath = !useHierarchicalBin ? includeDir : includeDir.resolve(getOutPath().relativize(srcPath)).resolve(srcFile.getFileName().toString().split("\\.")[0]); } public Path getIncludePath() { - return getOutPath().resolve("include"); + return includePath; } public String getRuntimeIncludePath() { diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 0d74c9ec60..fcd1cc3c78 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -949,7 +949,7 @@ private void generateReactorDefinitions() throws IOException { } private void generateHeaders() throws IOException { - // Cannot delete existing header files directory because this would create a race condition in fed-gen + FileUtil.deleteDirectory(fileConfig.getIncludePath()); FileUtil.copyDirectoryFromClassPath( fileConfig.getRuntimeIncludePath(), fileConfig.getIncludePath(), From f67cc8fa1060ac07919d39d719d069ef11a7e3b2 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Mar 2023 19:09:05 -0700 Subject: [PATCH 54/92] Hacky (?) fix for Python compilation issues. --- org.lflang/src/org/lflang/generator/python/PythonGenerator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 077f848a94..bc240f6bd5 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -403,6 +403,7 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { targetConfig.threading = false; } int cGeneratedPercentProgress = (IntegratedBuilder.VALIDATED_PERCENT_PROGRESS + 100) / 2; + code.pr(PythonPreambleGenerator.generateCIncludeStatements(targetConfig, targetLanguageIsCpp(), hasModalReactors)); super.doGenerate(resource, new SubContext( context, IntegratedBuilder.VALIDATED_PERCENT_PROGRESS, From ca3f167ea2ebdb7303dffdbb8351248371fe01fd Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 23 Mar 2023 23:05:12 -0700 Subject: [PATCH 55/92] Address failing TS federated tests. --- .../federated/extensions/TSExtension.java | 31 +++++++++---------- .../src/org/lflang/generator/Validator.java | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/extensions/TSExtension.java b/org.lflang/src/org/lflang/federated/extensions/TSExtension.java index ca8ce4dd9c..94ae95ff60 100644 --- a/org.lflang/src/org/lflang/federated/extensions/TSExtension.java +++ b/org.lflang/src/org/lflang/federated/extensions/TSExtension.java @@ -97,22 +97,21 @@ public String generatePreamble(FederateInstance federate, FedFileConfig fileConf var upstreamConnectionDelays = getUpstreamConnectionDelays(federate); return """ - preamble {= - const defaultFederateConfig: __FederateConfig = { - dependsOn: [%s], - executionTimeout: undefined, - fast: false, - federateID: %d, - federationID: "Unidentified Federation", - keepAlive: false, - minOutputDelay: %s, - networkMessageActions: [%s], - rtiHost: "%s", - rtiPort: %d, - sendsTo: [%s], - upstreamConnectionDelays: [%s] - } - =}""".formatted( + const defaultFederateConfig: __FederateConfig = { + dependsOn: [%s], + executionTimeout: undefined, + fast: false, + federateID: %d, + federationID: "Unidentified Federation", + keepAlive: false, + minOutputDelay: %s, + networkMessageActions: [%s], + rtiHost: "%s", + rtiPort: %d, + sendsTo: [%s], + upstreamConnectionDelays: [%s] + } + """.formatted( federate.dependsOn.keySet().stream() .map(e->String.valueOf(e.id)) .collect(Collectors.joining(",")), diff --git a/org.lflang/src/org/lflang/generator/Validator.java b/org.lflang/src/org/lflang/generator/Validator.java index bc11061f0d..7a9b85c453 100644 --- a/org.lflang/src/org/lflang/generator/Validator.java +++ b/org.lflang/src/org/lflang/generator/Validator.java @@ -161,7 +161,7 @@ private List> getValidationStrategies() { */ private Pair getValidationStrategy(Path generatedFile) { List sorted = getPossibleStrategies().stream() - .sorted(Comparator.comparingInt(vs -> -vs.getPriority())).collect(Collectors.toList()); + .sorted(Comparator.comparingInt(vs -> -vs.getPriority())).toList(); for (ValidationStrategy strategy : sorted) { LFCommand validateCommand = strategy.getCommand(generatedFile); if (validateCommand != null) { From a23fd478778db02a31711588101626ff575afe44 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 12:32:46 -0700 Subject: [PATCH 56/92] Delete some #includes from reactor.h. --- org.lflang/src/lib/c/reactor-c | 2 +- test/C/src/ActionDelay.lf | 4 ++++ test/C/src/ActionIsPresent.lf | 4 ++++ test/C/src/ActionWithNoReaction.lf | 4 ++++ test/C/src/After.lf | 4 ++++ test/C/src/AfterCycles.lf | 4 ++++ test/C/src/AfterOverlapped.lf | 4 ++++ test/C/src/AfterZero.lf | 4 ++++ test/C/src/ArrayAsParameter.lf | 4 ++++ test/C/src/ArrayAsType.lf | 4 ++++ test/C/src/ArrayPrint.lf | 4 ++++ test/C/src/Composition.lf | 4 ++++ test/C/src/CompositionAfter.lf | 4 ++++ test/C/src/CompositionGain.lf | 4 ++++ test/C/src/CompositionInheritance.lf | 4 ++++ test/C/src/DanglingOutput.lf | 4 ++++ test/C/src/Deadline.lf | 4 ++++ test/C/src/DeadlineAnytime.lf | 4 ++++ test/C/src/DeadlineHandledAbove.lf | 4 ++++ test/C/src/DeadlineZero.lf | 4 ++++ test/C/src/DelayArray.lf | 4 ++++ test/C/src/DelayArrayWithAfter.lf | 4 ++++ test/C/src/DelayInt.lf | 4 ++++ test/C/src/DelayPointer.lf | 4 ++++ test/C/src/DelayString.lf | 4 ++++ test/C/src/DelayStruct.lf | 1 + test/C/src/DelayStructWithAfter.lf | 1 + test/C/src/DelayStructWithAfterOverlapped.lf | 1 + test/C/src/DelayedAction.lf | 4 ++++ test/C/src/DelayedReaction.lf | 4 ++++ test/C/src/Determinism.lf | 4 ++++ test/C/src/DoubleInvocation.lf | 4 ++++ test/C/src/DoublePort.lf | 4 ++++ test/C/src/DoubleReaction.lf | 4 ++++ test/C/src/DoubleTrigger.lf | 4 ++++ test/C/src/Gain.lf | 4 ++++ test/C/src/GetTime.lf | 4 ++++ test/C/src/Hello.lf | 4 ++++ test/C/src/HelloWorld.lf | 4 ++++ test/C/src/Hierarchy.lf | 4 ++++ test/C/src/Hierarchy2.lf | 4 ++++ test/C/src/IdentifierLength.lf | 4 ++++ test/C/src/ImportComposition.lf | 4 ++++ test/C/src/InheritanceAction.lf | 4 ++++ test/C/src/ManualDelayedReaction.lf | 4 ++++ test/C/src/Microsteps.lf | 4 ++++ test/C/src/Minimal.lf | 4 ++++ test/C/src/MultipleContained.lf | 4 ++++ test/C/src/ParameterizedState.lf | 4 ++++ test/C/src/PeriodicDesugared.lf | 4 ++++ test/C/src/PhysicalConnection.lf | 4 ++++ test/C/src/PingPong.lf | 4 ++++ test/C/src/Preamble.lf | 4 ++++ test/C/src/ReadOutputOfContainedReactor.lf | 4 ++++ test/C/src/Schedule.lf | 4 ++++ test/C/src/ScheduleLogicalAction.lf | 4 ++++ test/C/src/ScheduleValue.lf | 4 ++++ test/C/src/SelfLoop.lf | 4 ++++ test/C/src/SendingInside.lf | 4 ++++ test/C/src/SendingInside2.lf | 4 ++++ test/C/src/SendsPointerTest.lf | 5 ++++- test/C/src/SetArray.lf | 4 ++++ test/C/src/SetToken.lf | 4 ++++ test/C/src/SimpleDeadline.lf | 4 ++++ test/C/src/SlowingClock.lf | 4 ++++ test/C/src/SlowingClockPhysical.lf | 4 ++++ test/C/src/StartupOutFromInside.lf | 4 ++++ test/C/src/Starvation.lf | 4 ++++ test/C/src/Stop.lf | 4 ++++ test/C/src/StopZero.lf | 4 ++++ test/C/src/Stride.lf | 4 ++++ test/C/src/StructAsState.lf | 2 ++ test/C/src/StructAsType.lf | 1 + test/C/src/StructAsTypeDirect.lf | 1 + test/C/src/StructParallel.lf | 1 + test/C/src/StructPrint.lf | 1 + test/C/src/StructScale.lf | 1 + test/C/src/SubclassesAndStartup.lf | 4 ++++ test/C/src/TestForPreviousOutput.lf | 4 ++++ test/C/src/TimeLimit.lf | 4 ++++ test/C/src/TimeState.lf | 4 ++++ test/C/src/Timeout.lf | 4 ++++ test/C/src/TimeoutZero.lf | 4 ++++ test/C/src/UnconnectedInput.lf | 4 ++++ test/C/src/Wcet.lf | 4 ++++ test/C/src/concurrent/AsyncCallback.lf | 4 ++++ test/C/src/concurrent/AsyncCallbackDrop.lf | 4 ++++ test/C/src/concurrent/AsyncCallbackReplace.lf | 4 ++++ test/C/src/concurrent/CompositionThreaded.lf | 4 ++++ test/C/src/concurrent/DeadlineHandledAboveThreaded.lf | 4 ++++ test/C/src/concurrent/DeadlineThreaded.lf | 4 ++++ test/C/src/concurrent/DelayIntThreaded.lf | 4 ++++ test/C/src/concurrent/DeterminismThreaded.lf | 4 ++++ test/C/src/concurrent/DoubleReactionThreaded.lf | 4 ++++ test/C/src/concurrent/GainThreaded.lf | 4 ++++ test/C/src/concurrent/HelloThreaded.lf | 4 ++++ test/C/src/concurrent/MinimalThreaded.lf | 4 ++++ test/C/src/concurrent/PingPongThreaded.lf | 4 ++++ test/C/src/concurrent/ScheduleAt.lf | 4 ++++ test/C/src/concurrent/ScheduleTwice.lf | 4 ++++ test/C/src/concurrent/ScheduleTwiceThreaded.lf | 4 ++++ test/C/src/concurrent/SendingInsideThreaded.lf | 4 ++++ test/C/src/concurrent/StarvationThreaded.lf | 4 ++++ test/C/src/concurrent/StopZeroThreaded.lf | 4 ++++ test/C/src/concurrent/Threaded.lf | 4 ++++ test/C/src/concurrent/ThreadedMultiport.lf | 4 ++++ test/C/src/concurrent/ThreadedThreaded.lf | 4 ++++ test/C/src/concurrent/TimeLimitThreaded.lf | 4 ++++ test/C/src/concurrent/TimeoutThreaded.lf | 4 ++++ test/C/src/concurrent/TimeoutZeroThreaded.lf | 4 ++++ test/C/src/concurrent/Tracing.lf | 4 ++++ test/C/src/docker/FilesPropertyContainerized.lf | 1 + test/C/src/federated/DistributedCountDecentralized.lf | 4 ++++ test/C/src/federated/DistributedCountDecentralizedLate.lf | 4 ++++ .../federated/DistributedCountDecentralizedLateHierarchy.lf | 4 ++++ test/C/src/federated/DistributedCountPhysical.lf | 4 ++++ test/C/src/federated/DistributedCountPhysicalAfterDelay.lf | 4 ++++ .../C/src/federated/DistributedCountPhysicalDecentralized.lf | 4 ++++ test/C/src/federated/DistributedLoopedAction.lf | 4 ++++ test/C/src/federated/DistributedNetworkOrder.lf | 4 ++++ test/C/src/federated/DistributedStopZero.lf | 4 ++++ test/C/src/federated/DistributedToken.lf | 4 ++++ test/C/src/federated/PingPongDistributedPhysical.lf | 4 ++++ .../failing/DistributedNetworkOrderDecentralized.lf | 4 ++++ test/C/src/lib/ImportedAgain.lf | 4 ++++ test/C/src/lib/Test.lf | 4 ++++ test/C/src/modal_models/ConvertCaseTest.lf | 4 ++++ test/C/src/modal_models/Count3Modes.lf | 4 ++++ test/C/src/modal_models/MixedReactions.lf | 4 ++++ test/C/src/modal_models/ModalActions.lf | 4 ++++ test/C/src/modal_models/ModalAfter.lf | 4 ++++ test/C/src/modal_models/ModalCycleBreaker.lf | 4 ++++ test/C/src/modal_models/ModalNestedReactions.lf | 4 ++++ test/C/src/modal_models/ModalStartupShutdown.lf | 4 ++++ test/C/src/modal_models/ModalStateReset.lf | 4 ++++ test/C/src/modal_models/ModalStateResetAuto.lf | 4 ++++ test/C/src/modal_models/ModalTimers.lf | 4 ++++ test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf | 4 ++++ .../modal_models/MultipleOutputFeeder_ReactionConnections.lf | 4 ++++ test/C/src/multiport/BankIndexInitializer.lf | 5 ++++- test/C/src/multiport/BankToBank.lf | 4 ++++ test/C/src/multiport/BankToBankMultiport.lf | 4 ++++ test/C/src/multiport/BankToBankMultiportAfter.lf | 4 ++++ test/C/src/multiport/BankToMultiport.lf | 4 ++++ test/C/src/multiport/Broadcast.lf | 4 ++++ test/C/src/multiport/BroadcastAfter.lf | 4 ++++ test/C/src/multiport/BroadcastMultipleAfter.lf | 4 ++++ test/C/src/multiport/DualBanks.lf | 4 ++++ test/C/src/multiport/DualBanksMultiport.lf | 4 ++++ test/C/src/multiport/FullyConnected.lf | 4 ++++ test/C/src/multiport/FullyConnectedAddressable.lf | 4 ++++ test/C/src/multiport/MultiportFromBank.lf | 4 ++++ test/C/src/multiport/MultiportFromHierarchy.lf | 4 ++++ test/C/src/multiport/MultiportFromReaction.lf | 4 ++++ test/C/src/multiport/MultiportIn.lf | 4 ++++ test/C/src/multiport/MultiportInParameterized.lf | 4 ++++ test/C/src/multiport/MultiportMutableInputArray.lf | 4 ++++ test/C/src/multiport/MultiportOut.lf | 4 ++++ test/C/src/multiport/MultiportToBank.lf | 4 ++++ test/C/src/multiport/MultiportToBankAfter.lf | 4 ++++ test/C/src/multiport/MultiportToBankDouble.lf | 4 ++++ test/C/src/multiport/MultiportToBankHierarchy.lf | 4 ++++ test/C/src/multiport/MultiportToHierarchy.lf | 4 ++++ test/C/src/multiport/MultiportToMultiport.lf | 4 ++++ test/C/src/multiport/MultiportToMultiport2.lf | 4 ++++ test/C/src/multiport/MultiportToMultiport2After.lf | 4 ++++ test/C/src/multiport/MultiportToMultiportArray.lf | 4 ++++ test/C/src/multiport/MultiportToMultiportParameter.lf | 4 ++++ test/C/src/multiport/MultiportToPort.lf | 4 ++++ test/C/src/multiport/MultiportToReaction.lf | 4 ++++ test/C/src/multiport/PipelineAfter.lf | 4 ++++ test/C/src/no_inlining/Count.lf | 4 ++++ test/C/src/serialization/PersonProtocolBuffers.lf | 4 ++++ test/C/src/serialization/ProtoNoPacking.lf | 4 ++++ test/C/src/target/HelloWorldCCPP.lf | 4 ++++ test/C/src/token/TokenContainedSource.lf | 4 ++++ test/C/src/token/TokenContainedSourceBank.lf | 4 ++++ test/C/src/token/lib/Token.lf | 1 + test/C/src/zephyr/HelloZephyr.lf | 4 ++++ test/C/src/zephyr/Timer.lf | 4 ++++ test/C/src/zephyr/lib/Led.lf | 4 ++++ 181 files changed, 689 insertions(+), 3 deletions(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index d43e973780..d71b259c29 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit d43e9737804f2d984d52a99cac20d8e57adad543 +Subproject commit d71b259c299bbd52d98a3f38be2f28db899190c7 diff --git a/test/C/src/ActionDelay.lf b/test/C/src/ActionDelay.lf index 6a4deddda6..664fda3588 100644 --- a/test/C/src/ActionDelay.lf +++ b/test/C/src/ActionDelay.lf @@ -1,6 +1,10 @@ // Test logical action with delay. target C +preamble {= + #include +=} + reactor GeneratedDelay { input y_in: int output y_out: int diff --git a/test/C/src/ActionIsPresent.lf b/test/C/src/ActionIsPresent.lf index 4f8164bea8..23cd3b4bb5 100644 --- a/test/C/src/ActionIsPresent.lf +++ b/test/C/src/ActionIsPresent.lf @@ -1,6 +1,10 @@ // Tests the is_present variable for actions. target C +preamble {= + #include +=} + main reactor ActionIsPresent(offset: time(1 nsec), period: time(500 msec)) { logical action a state success: bool(false) diff --git a/test/C/src/ActionWithNoReaction.lf b/test/C/src/ActionWithNoReaction.lf index 8ac720167d..cb4eb18b36 100644 --- a/test/C/src/ActionWithNoReaction.lf +++ b/test/C/src/ActionWithNoReaction.lf @@ -6,6 +6,10 @@ target C { timeout: 3 sec } +preamble {= + #include +=} + reactor foo { input x: int output y: int diff --git a/test/C/src/After.lf b/test/C/src/After.lf index f354d9d7c8..bbb0f98127 100644 --- a/test/C/src/After.lf +++ b/test/C/src/After.lf @@ -5,6 +5,10 @@ target C { timeout: 3 sec } +preamble {= + #include +=} + reactor foo { input x: int output y: int diff --git a/test/C/src/AfterCycles.lf b/test/C/src/AfterCycles.lf index 3bc9622944..a396a3c28e 100644 --- a/test/C/src/AfterCycles.lf +++ b/test/C/src/AfterCycles.lf @@ -2,6 +2,10 @@ // running without detected a cycle. target C +preamble {= + #include +=} + reactor Source { output out: unsigned diff --git a/test/C/src/AfterOverlapped.lf b/test/C/src/AfterOverlapped.lf index 49d2c22bd2..a661860ab8 100644 --- a/test/C/src/AfterOverlapped.lf +++ b/test/C/src/AfterOverlapped.lf @@ -6,6 +6,10 @@ target C { import Count from "lib/Count.lf" +preamble {= + #include +=} + reactor Test { input c: int state i: int(0) diff --git a/test/C/src/AfterZero.lf b/test/C/src/AfterZero.lf index 85e1d2e000..53c69b2f14 100644 --- a/test/C/src/AfterZero.lf +++ b/test/C/src/AfterZero.lf @@ -5,6 +5,10 @@ target C { timeout: 3 sec } +preamble {= + #include +=} + reactor foo { input x: int output y: int diff --git a/test/C/src/ArrayAsParameter.lf b/test/C/src/ArrayAsParameter.lf index d51778980e..a7af6683d0 100644 --- a/test/C/src/ArrayAsParameter.lf +++ b/test/C/src/ArrayAsParameter.lf @@ -3,6 +3,10 @@ // encode their own length. target C +preamble {= + #include +=} + reactor Source(sequence: int[](0, 1, 2), n_sequence: int(3)) { output out: int state count: int(0) diff --git a/test/C/src/ArrayAsType.lf b/test/C/src/ArrayAsType.lf index ad326c9288..7665b401d5 100644 --- a/test/C/src/ArrayAsType.lf +++ b/test/C/src/ArrayAsType.lf @@ -2,6 +2,10 @@ // destination references the array directly. target C +preamble {= + #include +=} + reactor Source { output out: int[3] diff --git a/test/C/src/ArrayPrint.lf b/test/C/src/ArrayPrint.lf index 33d75c6455..3c20a6c779 100644 --- a/test/C/src/ArrayPrint.lf +++ b/test/C/src/ArrayPrint.lf @@ -6,6 +6,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(size: int(3)) { output out: int[] state count: int(0) diff --git a/test/C/src/Composition.lf b/test/C/src/Composition.lf index c450bc0a64..67fdc584c4 100644 --- a/test/C/src/Composition.lf +++ b/test/C/src/Composition.lf @@ -5,6 +5,10 @@ target C { timeout: 10 sec } +preamble {= + #include +=} + reactor Source(period: time(2 sec)) { output y: int timer t(1 sec, period) diff --git a/test/C/src/CompositionAfter.lf b/test/C/src/CompositionAfter.lf index 43f604de06..764e228db3 100644 --- a/test/C/src/CompositionAfter.lf +++ b/test/C/src/CompositionAfter.lf @@ -5,6 +5,10 @@ target C { timeout: 10 sec } +preamble {= + #include +=} + reactor Source(period: time(2 sec)) { output y: int timer t(1 sec, period) diff --git a/test/C/src/CompositionGain.lf b/test/C/src/CompositionGain.lf index 31cd7e5123..b574c7ca1c 100644 --- a/test/C/src/CompositionGain.lf +++ b/test/C/src/CompositionGain.lf @@ -1,6 +1,10 @@ // This tests send data through a contained reactor. target C +preamble {= + #include +=} + reactor Gain { input gainin: int output y: int diff --git a/test/C/src/CompositionInheritance.lf b/test/C/src/CompositionInheritance.lf index f57c1a688e..e4fdb7d2ab 100644 --- a/test/C/src/CompositionInheritance.lf +++ b/test/C/src/CompositionInheritance.lf @@ -5,6 +5,10 @@ target C { timeout: 10 sec } +preamble {= + #include +=} + reactor Source(period: time(2 sec)) { input foo: int output y: int diff --git a/test/C/src/DanglingOutput.lf b/test/C/src/DanglingOutput.lf index 6305f17644..e68c66f9be 100644 --- a/test/C/src/DanglingOutput.lf +++ b/test/C/src/DanglingOutput.lf @@ -2,6 +2,10 @@ // in a compilation error. Passing the test is just compiling and running. target C +preamble {= + #include +=} + reactor Source { output out: int timer t diff --git a/test/C/src/Deadline.lf b/test/C/src/Deadline.lf index 62116353a5..6964d8f90f 100644 --- a/test/C/src/Deadline.lf +++ b/test/C/src/Deadline.lf @@ -5,6 +5,10 @@ target C { timeout: 6 sec } +preamble {= + #include +=} + reactor Source(period: time(3 sec)) { output y: int timer t(0, period) diff --git a/test/C/src/DeadlineAnytime.lf b/test/C/src/DeadlineAnytime.lf index 37540fd10b..ec63f9f13e 100644 --- a/test/C/src/DeadlineAnytime.lf +++ b/test/C/src/DeadlineAnytime.lf @@ -1,6 +1,10 @@ // Test whether the lf_check_deadline function works. target C +preamble {= + #include +=} + reactor A { state i: int logical action a diff --git a/test/C/src/DeadlineHandledAbove.lf b/test/C/src/DeadlineHandledAbove.lf index d186bf9016..5557469462 100644 --- a/test/C/src/DeadlineHandledAbove.lf +++ b/test/C/src/DeadlineHandledAbove.lf @@ -2,6 +2,10 @@ // container reacts to that output. target C +preamble {= + #include +=} + reactor Deadline(threshold: time(100 msec)) { input x: int output deadline_violation: bool diff --git a/test/C/src/DeadlineZero.lf b/test/C/src/DeadlineZero.lf index 4e946bb63d..a1b8f3c86b 100644 --- a/test/C/src/DeadlineZero.lf +++ b/test/C/src/DeadlineZero.lf @@ -3,6 +3,10 @@ target C { timeout: 1 sec } +preamble {= + #include +=} + reactor Detector { input trigger: int state cnt: int(0) diff --git a/test/C/src/DelayArray.lf b/test/C/src/DelayArray.lf index 19e49e2464..77374136ca 100644 --- a/test/C/src/DelayArray.lf +++ b/test/C/src/DelayArray.lf @@ -4,6 +4,10 @@ target C { build-type: RelWithDebInfo } +preamble {= + #include +=} + reactor DelayPointer(delay: time(100 msec)) { input in: int[] output out: int[] diff --git a/test/C/src/DelayArrayWithAfter.lf b/test/C/src/DelayArrayWithAfter.lf index 42d7ff5275..8193c0e9f8 100644 --- a/test/C/src/DelayArrayWithAfter.lf +++ b/test/C/src/DelayArrayWithAfter.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output out: int[] state iteration: int(1) diff --git a/test/C/src/DelayInt.lf b/test/C/src/DelayInt.lf index c7c27132bc..134c1c9bb3 100644 --- a/test/C/src/DelayInt.lf +++ b/test/C/src/DelayInt.lf @@ -1,6 +1,10 @@ // This tests actions with payloads by delaying an input by a fixed amount. target C +preamble {= + #include +=} + reactor Delay(delay: time(100 msec)) { input in: int output out: int diff --git a/test/C/src/DelayPointer.lf b/test/C/src/DelayPointer.lf index 87455d32ec..2e8474f9cf 100644 --- a/test/C/src/DelayPointer.lf +++ b/test/C/src/DelayPointer.lf @@ -1,6 +1,10 @@ // Test delaying a pointer type. target C +preamble {= + #include +=} + reactor DelayPointer2(delay: time(100 msec)) { input in: int* output out: int* diff --git a/test/C/src/DelayString.lf b/test/C/src/DelayString.lf index 1c77190581..c30f19f321 100644 --- a/test/C/src/DelayString.lf +++ b/test/C/src/DelayString.lf @@ -2,6 +2,10 @@ // freed. target C +preamble {= + #include +=} + reactor DelayString2(delay: time(100 msec)) { input in: string output out: string diff --git a/test/C/src/DelayStruct.lf b/test/C/src/DelayStruct.lf index a92acdc483..5cd3cb948e 100644 --- a/test/C/src/DelayStruct.lf +++ b/test/C/src/DelayStruct.lf @@ -5,6 +5,7 @@ target C { preamble {= #include "hello.h" + #include =} reactor DelayPointer(delay: time(100 msec)) { diff --git a/test/C/src/DelayStructWithAfter.lf b/test/C/src/DelayStructWithAfter.lf index 14f24aaf88..97d8a3811e 100644 --- a/test/C/src/DelayStructWithAfter.lf +++ b/test/C/src/DelayStructWithAfter.lf @@ -5,6 +5,7 @@ target C { preamble {= #include "hello.h" + #include =} reactor Source { diff --git a/test/C/src/DelayStructWithAfterOverlapped.lf b/test/C/src/DelayStructWithAfterOverlapped.lf index 671b1ca4b3..e55900ab92 100644 --- a/test/C/src/DelayStructWithAfterOverlapped.lf +++ b/test/C/src/DelayStructWithAfterOverlapped.lf @@ -7,6 +7,7 @@ target C { preamble {= #include "hello.h" + #include =} reactor Source { diff --git a/test/C/src/DelayedAction.lf b/test/C/src/DelayedAction.lf index b37f6b9710..735c7e8a6d 100644 --- a/test/C/src/DelayedAction.lf +++ b/test/C/src/DelayedAction.lf @@ -3,6 +3,10 @@ target C { timeout: 5 sec } +preamble {= + #include +=} + main reactor DelayedAction { timer t(0, 1 sec) logical action a diff --git a/test/C/src/DelayedReaction.lf b/test/C/src/DelayedReaction.lf index 2dcf80f106..289d8c9040 100644 --- a/test/C/src/DelayedReaction.lf +++ b/test/C/src/DelayedReaction.lf @@ -1,6 +1,10 @@ // Test delay made on a connection. target C +preamble {= + #include +=} + reactor Source { output out: int timer t diff --git a/test/C/src/Determinism.lf b/test/C/src/Determinism.lf index fea5290373..2bb5e8498b 100644 --- a/test/C/src/Determinism.lf +++ b/test/C/src/Determinism.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Source { output y: int timer t diff --git a/test/C/src/DoubleInvocation.lf b/test/C/src/DoubleInvocation.lf index 4b60f26fa8..4c75234429 100644 --- a/test/C/src/DoubleInvocation.lf +++ b/test/C/src/DoubleInvocation.lf @@ -10,6 +10,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Ball { output position: int output velocity: int diff --git a/test/C/src/DoublePort.lf b/test/C/src/DoublePort.lf index 97d18f1761..c87b49d93e 100644 --- a/test/C/src/DoublePort.lf +++ b/test/C/src/DoublePort.lf @@ -12,6 +12,10 @@ target C { import Count from "lib/Count.lf" +preamble {= + #include +=} + reactor CountMicrostep { state count: int(1) output out: int diff --git a/test/C/src/DoubleReaction.lf b/test/C/src/DoubleReaction.lf index fb6aaaabaa..7c2f2f3c45 100644 --- a/test/C/src/DoubleReaction.lf +++ b/test/C/src/DoubleReaction.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Clock(offset: time(0), period: time(1 sec)) { output y: int timer t(offset, period) diff --git a/test/C/src/DoubleTrigger.lf b/test/C/src/DoubleTrigger.lf index 201ac35d7c..8872ea73dc 100644 --- a/test/C/src/DoubleTrigger.lf +++ b/test/C/src/DoubleTrigger.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + main reactor DoubleTrigger { timer t1 timer t2 diff --git a/test/C/src/Gain.lf b/test/C/src/Gain.lf index 4096ec5973..87eb9ac39a 100644 --- a/test/C/src/Gain.lf +++ b/test/C/src/Gain.lf @@ -1,6 +1,10 @@ // Example in the Wiki. target C +preamble {= + #include +=} + reactor Scale(scale: int(2)) { input x: int output y: int diff --git a/test/C/src/GetTime.lf b/test/C/src/GetTime.lf index 18e70ebf79..7f6e98c173 100644 --- a/test/C/src/GetTime.lf +++ b/test/C/src/GetTime.lf @@ -5,6 +5,10 @@ target C { fast: false } +preamble {= + #include +=} + main reactor GetTime { timer t(0, 1 sec) diff --git a/test/C/src/Hello.lf b/test/C/src/Hello.lf index f47b66ecc4..ac52790967 100644 --- a/test/C/src/Hello.lf +++ b/test/C/src/Hello.lf @@ -8,6 +8,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Reschedule(period: time(2 sec), message: string("Hello C")) { state count: int(0) state previous_time: time(0) diff --git a/test/C/src/HelloWorld.lf b/test/C/src/HelloWorld.lf index dc17cc0626..2576587c4c 100644 --- a/test/C/src/HelloWorld.lf +++ b/test/C/src/HelloWorld.lf @@ -6,6 +6,10 @@ target C { build-type: Debug } +preamble {= + #include +=} + reactor HelloWorld2 { state success: bool(false) diff --git a/test/C/src/Hierarchy.lf b/test/C/src/Hierarchy.lf index ea14165e24..463c6af403 100644 --- a/test/C/src/Hierarchy.lf +++ b/test/C/src/Hierarchy.lf @@ -1,6 +1,10 @@ // Test data transport across hierarchy. target C +preamble {= + #include +=} + reactor Source { output out: int timer t diff --git a/test/C/src/Hierarchy2.lf b/test/C/src/Hierarchy2.lf index 07fa4c73a0..67390c181a 100644 --- a/test/C/src/Hierarchy2.lf +++ b/test/C/src/Hierarchy2.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output out: int timer t(0, 1 sec) diff --git a/test/C/src/IdentifierLength.lf b/test/C/src/IdentifierLength.lf index 69f1fcfd75..822ab37399 100644 --- a/test/C/src/IdentifierLength.lf +++ b/test/C/src/IdentifierLength.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor A_Really_Long_Name_For_A_Source(period: time(2 sec)) { output y: int timer t(1 sec, period) diff --git a/test/C/src/ImportComposition.lf b/test/C/src/ImportComposition.lf index 023c9736b2..6384370380 100644 --- a/test/C/src/ImportComposition.lf +++ b/test/C/src/ImportComposition.lf @@ -4,6 +4,10 @@ target C import ImportedComposition from "lib/ImportedComposition.lf" +preamble {= + #include +=} + main reactor ImportComposition { a = new ImportedComposition() state received: bool(false) diff --git a/test/C/src/InheritanceAction.lf b/test/C/src/InheritanceAction.lf index 3941882f2c..f0823b52f5 100644 --- a/test/C/src/InheritanceAction.lf +++ b/test/C/src/InheritanceAction.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { logical action foo: int output y: int diff --git a/test/C/src/ManualDelayedReaction.lf b/test/C/src/ManualDelayedReaction.lf index 1402e00c62..31c8f6540a 100644 --- a/test/C/src/ManualDelayedReaction.lf +++ b/test/C/src/ManualDelayedReaction.lf @@ -5,6 +5,10 @@ target C { keepalive: false } +preamble {= + #include +=} + // That's the stuff that shall be generated for the after reactor GeneratedDelay { input y_in: int diff --git a/test/C/src/Microsteps.lf b/test/C/src/Microsteps.lf index 795a4801a7..60babbfa8c 100644 --- a/test/C/src/Microsteps.lf +++ b/test/C/src/Microsteps.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Destination { input x: int input y: int diff --git a/test/C/src/Minimal.lf b/test/C/src/Minimal.lf index 350f92a795..5999d0c660 100644 --- a/test/C/src/Minimal.lf +++ b/test/C/src/Minimal.lf @@ -1,6 +1,10 @@ // This is a smoke test of a minimal reactor. target C +preamble {= + #include +=} + main reactor Minimal { reaction(startup) {= printf("Hello World.\n"); =} } diff --git a/test/C/src/MultipleContained.lf b/test/C/src/MultipleContained.lf index f3058c9dd4..c575476c14 100644 --- a/test/C/src/MultipleContained.lf +++ b/test/C/src/MultipleContained.lf @@ -2,6 +2,10 @@ // reactor. target C +preamble {= + #include +=} + reactor Contained { output trigger: int input in1: int diff --git a/test/C/src/ParameterizedState.lf b/test/C/src/ParameterizedState.lf index 1965fa1929..b8cae94d66 100644 --- a/test/C/src/ParameterizedState.lf +++ b/test/C/src/ParameterizedState.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Foo(bar: int(42)) { state baz(bar) diff --git a/test/C/src/PeriodicDesugared.lf b/test/C/src/PeriodicDesugared.lf index 6d9f8a8ab4..3144a0d54d 100644 --- a/test/C/src/PeriodicDesugared.lf +++ b/test/C/src/PeriodicDesugared.lf @@ -3,6 +3,10 @@ target C { timeout: 1 sec } +preamble {= + #include +=} + main reactor(offset: time(0), period: time(500 msec)) { logical action init(offset) logical action recur(period) diff --git a/test/C/src/PhysicalConnection.lf b/test/C/src/PhysicalConnection.lf index 2cac10c240..4aeb2d85fb 100644 --- a/test/C/src/PhysicalConnection.lf +++ b/test/C/src/PhysicalConnection.lf @@ -1,6 +1,10 @@ /** Test physical connections. */ target C +preamble {= + #include +=} + reactor Source { output out: int diff --git a/test/C/src/PingPong.lf b/test/C/src/PingPong.lf index 5ce6caaaaa..141687a334 100644 --- a/test/C/src/PingPong.lf +++ b/test/C/src/PingPong.lf @@ -25,6 +25,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Ping(count: int(10)) { input receive: int output send: int diff --git a/test/C/src/Preamble.lf b/test/C/src/Preamble.lf index 01b4b371b6..76091241f4 100644 --- a/test/C/src/Preamble.lf +++ b/test/C/src/Preamble.lf @@ -3,6 +3,10 @@ target C { fast: true } +preamble {= + #include +=} + main reactor Preamble { preamble {= #include diff --git a/test/C/src/ReadOutputOfContainedReactor.lf b/test/C/src/ReadOutputOfContainedReactor.lf index 6b94d4a44b..3302b7dc4f 100644 --- a/test/C/src/ReadOutputOfContainedReactor.lf +++ b/test/C/src/ReadOutputOfContainedReactor.lf @@ -2,6 +2,10 @@ // permutations. target C +preamble {= + #include +=} + reactor Contained { output out: int diff --git a/test/C/src/Schedule.lf b/test/C/src/Schedule.lf index 91d3e2db2b..56d51539e7 100644 --- a/test/C/src/Schedule.lf +++ b/test/C/src/Schedule.lf @@ -1,6 +1,10 @@ // Example from Schedule section of the C Reactor Target wiki page. target C +preamble {= + #include +=} + reactor Schedule2 { input x: int logical action a diff --git a/test/C/src/ScheduleLogicalAction.lf b/test/C/src/ScheduleLogicalAction.lf index e3c898ebb5..45c7f4eae3 100644 --- a/test/C/src/ScheduleLogicalAction.lf +++ b/test/C/src/ScheduleLogicalAction.lf @@ -5,6 +5,10 @@ target C { timeout: 3 sec } +preamble {= + #include +=} + reactor foo { input x: int output y: int diff --git a/test/C/src/ScheduleValue.lf b/test/C/src/ScheduleValue.lf index 65e36fbd06..985380cbc4 100644 --- a/test/C/src/ScheduleValue.lf +++ b/test/C/src/ScheduleValue.lf @@ -3,6 +3,10 @@ target C { timeout: 3 sec } +preamble {= + #include +=} + main reactor ScheduleValue { logical action a: char* diff --git a/test/C/src/SelfLoop.lf b/test/C/src/SelfLoop.lf index 68ca61278e..5f50b02c3c 100644 --- a/test/C/src/SelfLoop.lf +++ b/test/C/src/SelfLoop.lf @@ -3,6 +3,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Self { input x: int output y: int diff --git a/test/C/src/SendingInside.lf b/test/C/src/SendingInside.lf index fcb495305a..5fac466762 100644 --- a/test/C/src/SendingInside.lf +++ b/test/C/src/SendingInside.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Printer { input x: int state count: int(1) diff --git a/test/C/src/SendingInside2.lf b/test/C/src/SendingInside2.lf index f65342de52..2ae20771f2 100644 --- a/test/C/src/SendingInside2.lf +++ b/test/C/src/SendingInside2.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Printer { input x: int diff --git a/test/C/src/SendsPointerTest.lf b/test/C/src/SendsPointerTest.lf index c7336ff91f..b29abd6eb9 100644 --- a/test/C/src/SendsPointerTest.lf +++ b/test/C/src/SendsPointerTest.lf @@ -2,7 +2,10 @@ // Reference counting ensures that the struct is freed. target C -preamble {= typedef int* int_pointer; =} +preamble {= + #include + typedef int* int_pointer; +=} reactor SendsPointer { output out: int_pointer diff --git a/test/C/src/SetArray.lf b/test/C/src/SetArray.lf index 605eed4081..4b70303798 100644 --- a/test/C/src/SetArray.lf +++ b/test/C/src/SetArray.lf @@ -2,6 +2,10 @@ // on a struct. It delays by a logical time any pointer datatype. target C +preamble {= + #include +=} + reactor Source { output out: int[] diff --git a/test/C/src/SetToken.lf b/test/C/src/SetToken.lf index c2295dbaa0..f2a128ac06 100644 --- a/test/C/src/SetToken.lf +++ b/test/C/src/SetToken.lf @@ -1,6 +1,10 @@ // Illustration of lf_set_token() in the wiki. target C +preamble {= + #include +=} + reactor Source { output out: int* logical action a: int diff --git a/test/C/src/SimpleDeadline.lf b/test/C/src/SimpleDeadline.lf index a59a6728e9..a890ad124f 100644 --- a/test/C/src/SimpleDeadline.lf +++ b/test/C/src/SimpleDeadline.lf @@ -3,6 +3,10 @@ // violation. target C +preamble {= + #include +=} + reactor Deadline(threshold: time(100 msec)) { input x: int output deadlineViolation: bool diff --git a/test/C/src/SlowingClock.lf b/test/C/src/SlowingClock.lf index 6655e87014..1bde93f2fc 100644 --- a/test/C/src/SlowingClock.lf +++ b/test/C/src/SlowingClock.lf @@ -9,6 +9,10 @@ target C { fast: true } +preamble {= + #include +=} + main reactor SlowingClock { logical action a(100 msec) state interval: time(100 msec) diff --git a/test/C/src/SlowingClockPhysical.lf b/test/C/src/SlowingClockPhysical.lf index b3255428c2..77bec1d897 100644 --- a/test/C/src/SlowingClockPhysical.lf +++ b/test/C/src/SlowingClockPhysical.lf @@ -9,6 +9,10 @@ target C { timeout: 1500 msec } +preamble {= + #include +=} + main reactor SlowingClockPhysical { physical action a(100 msec) state interval: time(100 msec) diff --git a/test/C/src/StartupOutFromInside.lf b/test/C/src/StartupOutFromInside.lf index cad2d282bf..f316ab3cdc 100644 --- a/test/C/src/StartupOutFromInside.lf +++ b/test/C/src/StartupOutFromInside.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Bar { output out: int diff --git a/test/C/src/Starvation.lf b/test/C/src/Starvation.lf index 38f2a247b6..4d8aefef1f 100644 --- a/test/C/src/Starvation.lf +++ b/test/C/src/Starvation.lf @@ -6,6 +6,10 @@ */ target C +preamble {= + #include +=} + reactor SuperDenseSender(number_of_iterations: int(10)) { logical action loop output out: int diff --git a/test/C/src/Stop.lf b/test/C/src/Stop.lf index fcfa407d35..fd9d59d527 100644 --- a/test/C/src/Stop.lf +++ b/test/C/src/Stop.lf @@ -9,6 +9,10 @@ target C { import Sender from "lib/LoopedActionSender.lf" +preamble {= + #include +=} + reactor Consumer { input in: int state reaction_invoked_correctly: bool(false) diff --git a/test/C/src/StopZero.lf b/test/C/src/StopZero.lf index 316cce5c6c..e447ccbc56 100644 --- a/test/C/src/StopZero.lf +++ b/test/C/src/StopZero.lf @@ -6,6 +6,10 @@ */ target C +preamble {= + #include +=} + reactor Sender { output out: int state reaction_invoked_correctly: bool(false) diff --git a/test/C/src/Stride.lf b/test/C/src/Stride.lf index 137855990d..0bf2001ace 100644 --- a/test/C/src/Stride.lf +++ b/test/C/src/Stride.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Count(stride: int(1)) { state count: int(1) output y: int diff --git a/test/C/src/StructAsState.lf b/test/C/src/StructAsState.lf index 8e89854cb6..0f095fe76e 100644 --- a/test/C/src/StructAsState.lf +++ b/test/C/src/StructAsState.lf @@ -3,6 +3,8 @@ target C preamble {= + #include + typedef struct hello_t { char* name; int value; diff --git a/test/C/src/StructAsType.lf b/test/C/src/StructAsType.lf index 9e43173110..9b27415066 100644 --- a/test/C/src/StructAsType.lf +++ b/test/C/src/StructAsType.lf @@ -4,6 +4,7 @@ target C { } preamble {= + #include #include "hello.h" =} diff --git a/test/C/src/StructAsTypeDirect.lf b/test/C/src/StructAsTypeDirect.lf index f9d85799e9..07c5eb4403 100644 --- a/test/C/src/StructAsTypeDirect.lf +++ b/test/C/src/StructAsTypeDirect.lf @@ -4,6 +4,7 @@ target C { } preamble {= + #include #include "hello.h" =} diff --git a/test/C/src/StructParallel.lf b/test/C/src/StructParallel.lf index 0d3e78cc3e..9fbe814896 100644 --- a/test/C/src/StructParallel.lf +++ b/test/C/src/StructParallel.lf @@ -8,6 +8,7 @@ target C { import Source from "StructScale.lf" preamble {= + #include #include "hello.h" =} diff --git a/test/C/src/StructPrint.lf b/test/C/src/StructPrint.lf index adaf7fbf24..59a8fd06db 100644 --- a/test/C/src/StructPrint.lf +++ b/test/C/src/StructPrint.lf @@ -5,6 +5,7 @@ target C { } preamble {= + #include #include "hello.h" =} diff --git a/test/C/src/StructScale.lf b/test/C/src/StructScale.lf index 076d0e7f3f..f8a46b79d1 100644 --- a/test/C/src/StructScale.lf +++ b/test/C/src/StructScale.lf @@ -7,6 +7,7 @@ target C { } preamble {= + #include #include "hello.h" =} diff --git a/test/C/src/SubclassesAndStartup.lf b/test/C/src/SubclassesAndStartup.lf index a8001a907d..499d4e8c46 100644 --- a/test/C/src/SubclassesAndStartup.lf +++ b/test/C/src/SubclassesAndStartup.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Super { state count: int(0) diff --git a/test/C/src/TestForPreviousOutput.lf b/test/C/src/TestForPreviousOutput.lf index fec3bc54da..6a5757d02c 100644 --- a/test/C/src/TestForPreviousOutput.lf +++ b/test/C/src/TestForPreviousOutput.lf @@ -2,6 +2,10 @@ // a given output. The output should always be 42. target C +preamble {= + #include +=} + reactor Source { output out: int diff --git a/test/C/src/TimeLimit.lf b/test/C/src/TimeLimit.lf index 2497296efd..8b6e6b90e0 100644 --- a/test/C/src/TimeLimit.lf +++ b/test/C/src/TimeLimit.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Clock(offset: time(0), period: time(1 sec)) { output y: int timer t(offset, period) diff --git a/test/C/src/TimeState.lf b/test/C/src/TimeState.lf index 790679ccda..735aa10a47 100644 --- a/test/C/src/TimeState.lf +++ b/test/C/src/TimeState.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Foo(bar: int(42)) { state baz: time(500 msec) diff --git a/test/C/src/Timeout.lf b/test/C/src/Timeout.lf index e0bb841b3e..f169f62da5 100644 --- a/test/C/src/Timeout.lf +++ b/test/C/src/Timeout.lf @@ -9,6 +9,10 @@ target C { import Sender from "lib/LoopedActionSender.lf" +preamble {= + #include +=} + reactor Consumer { input in: int state success: bool(false) diff --git a/test/C/src/TimeoutZero.lf b/test/C/src/TimeoutZero.lf index 36a65d6031..f9753f47c0 100644 --- a/test/C/src/TimeoutZero.lf +++ b/test/C/src/TimeoutZero.lf @@ -10,6 +10,10 @@ target C { import Sender from "lib/LoopedActionSender.lf" +preamble {= + #include +=} + reactor Consumer { input in: int state success: bool(false) diff --git a/test/C/src/UnconnectedInput.lf b/test/C/src/UnconnectedInput.lf index f41524fa01..f6d30225be 100644 --- a/test/C/src/UnconnectedInput.lf +++ b/test/C/src/UnconnectedInput.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output out: int timer t(0, 1 sec) diff --git a/test/C/src/Wcet.lf b/test/C/src/Wcet.lf index d21268ea79..56d9659343 100644 --- a/test/C/src/Wcet.lf +++ b/test/C/src/Wcet.lf @@ -1,6 +1,10 @@ // Setup for WCET analysis of Worker target C +preamble {= + #include +=} + reactor Source { output out1: int output out2: int diff --git a/test/C/src/concurrent/AsyncCallback.lf b/test/C/src/concurrent/AsyncCallback.lf index 90c300a8b2..817cc60457 100644 --- a/test/C/src/concurrent/AsyncCallback.lf +++ b/test/C/src/concurrent/AsyncCallback.lf @@ -12,6 +12,10 @@ target C { timeout: 2 sec } +preamble {= + #include +=} + main reactor AsyncCallback { preamble {= void callback(void* a) { diff --git a/test/C/src/concurrent/AsyncCallbackDrop.lf b/test/C/src/concurrent/AsyncCallbackDrop.lf index 17cb113a99..055e13fb66 100644 --- a/test/C/src/concurrent/AsyncCallbackDrop.lf +++ b/test/C/src/concurrent/AsyncCallbackDrop.lf @@ -7,6 +7,10 @@ target C { timeout: 2 sec } +preamble {= + #include +=} + main reactor { preamble {= void callback(void* a) { diff --git a/test/C/src/concurrent/AsyncCallbackReplace.lf b/test/C/src/concurrent/AsyncCallbackReplace.lf index 49dc3e75e9..287dceb9ab 100644 --- a/test/C/src/concurrent/AsyncCallbackReplace.lf +++ b/test/C/src/concurrent/AsyncCallbackReplace.lf @@ -7,6 +7,10 @@ target C { timeout: 2 sec } +preamble {= + #include +=} + main reactor { preamble {= void callback(void* a) { diff --git a/test/C/src/concurrent/CompositionThreaded.lf b/test/C/src/concurrent/CompositionThreaded.lf index decf56d687..4f980aed5d 100644 --- a/test/C/src/concurrent/CompositionThreaded.lf +++ b/test/C/src/concurrent/CompositionThreaded.lf @@ -5,6 +5,10 @@ target C { timeout: 10 sec } +preamble {= + #include +=} + reactor Source(period: time(2 sec)) { output y: int timer t(1 sec, period) diff --git a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf index 87359286ed..9886ef5630 100644 --- a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf +++ b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf @@ -2,6 +2,10 @@ // container reacts to that output. target C +preamble {= + #include +=} + reactor Deadline(threshold: time(100 msec)) { input x: int output deadline_violation: bool diff --git a/test/C/src/concurrent/DeadlineThreaded.lf b/test/C/src/concurrent/DeadlineThreaded.lf index fccb60001b..914e7efee6 100644 --- a/test/C/src/concurrent/DeadlineThreaded.lf +++ b/test/C/src/concurrent/DeadlineThreaded.lf @@ -5,6 +5,10 @@ target C { timeout: 6 sec } +preamble {= + #include +=} + reactor Source(period: time(3000 msec)) { output y: int timer t(0, period) diff --git a/test/C/src/concurrent/DelayIntThreaded.lf b/test/C/src/concurrent/DelayIntThreaded.lf index 5c2c983508..7400bb9bf9 100644 --- a/test/C/src/concurrent/DelayIntThreaded.lf +++ b/test/C/src/concurrent/DelayIntThreaded.lf @@ -1,6 +1,10 @@ // This tests actions with payloads by delaying an input by a fixed amount. target C +preamble {= + #include +=} + reactor Delay(delay: time(100 msec)) { input in: int output out: int diff --git a/test/C/src/concurrent/DeterminismThreaded.lf b/test/C/src/concurrent/DeterminismThreaded.lf index c141f36330..b9d92245c2 100644 --- a/test/C/src/concurrent/DeterminismThreaded.lf +++ b/test/C/src/concurrent/DeterminismThreaded.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Source { output y: int timer t diff --git a/test/C/src/concurrent/DoubleReactionThreaded.lf b/test/C/src/concurrent/DoubleReactionThreaded.lf index 66885ab7a0..7aa2a5555f 100644 --- a/test/C/src/concurrent/DoubleReactionThreaded.lf +++ b/test/C/src/concurrent/DoubleReactionThreaded.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Clock(offset: time(0), period: time(1 sec)) { output y: int timer t(offset, period) diff --git a/test/C/src/concurrent/GainThreaded.lf b/test/C/src/concurrent/GainThreaded.lf index b59d2b00fb..4e1dac4284 100644 --- a/test/C/src/concurrent/GainThreaded.lf +++ b/test/C/src/concurrent/GainThreaded.lf @@ -1,6 +1,10 @@ // Example in the Wiki. target C +preamble {= + #include +=} + reactor Scale(scale: int(2)) { input x: int output y: int diff --git a/test/C/src/concurrent/HelloThreaded.lf b/test/C/src/concurrent/HelloThreaded.lf index 72c7560ede..ef5cdae997 100644 --- a/test/C/src/concurrent/HelloThreaded.lf +++ b/test/C/src/concurrent/HelloThreaded.lf @@ -8,6 +8,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Reschedule(period: time(2 sec), message: string("Hello C")) { state count: int(0) state previous_time: time(0) diff --git a/test/C/src/concurrent/MinimalThreaded.lf b/test/C/src/concurrent/MinimalThreaded.lf index 5252d0465f..47ef3d8766 100644 --- a/test/C/src/concurrent/MinimalThreaded.lf +++ b/test/C/src/concurrent/MinimalThreaded.lf @@ -1,6 +1,10 @@ // This is a smoke test of a minimal reactor. target C +preamble {= + #include +=} + main reactor MinimalThreaded { timer t diff --git a/test/C/src/concurrent/PingPongThreaded.lf b/test/C/src/concurrent/PingPongThreaded.lf index 0f2e60f065..f785e5af25 100644 --- a/test/C/src/concurrent/PingPongThreaded.lf +++ b/test/C/src/concurrent/PingPongThreaded.lf @@ -25,6 +25,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Ping(count: int(10)) { input receive: int output send: int diff --git a/test/C/src/concurrent/ScheduleAt.lf b/test/C/src/concurrent/ScheduleAt.lf index 9a4ee2bb62..4fd6f4b8b4 100644 --- a/test/C/src/concurrent/ScheduleAt.lf +++ b/test/C/src/concurrent/ScheduleAt.lf @@ -9,6 +9,10 @@ target C { keepalive: true } +preamble {= + #include +=} + reactor Scheduler { preamble {= #ifdef __cplusplus diff --git a/test/C/src/concurrent/ScheduleTwice.lf b/test/C/src/concurrent/ScheduleTwice.lf index 41512f3c7d..81e37f9525 100644 --- a/test/C/src/concurrent/ScheduleTwice.lf +++ b/test/C/src/concurrent/ScheduleTwice.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + main reactor ScheduleTwice { logical action a: int state rc_count: int(0) diff --git a/test/C/src/concurrent/ScheduleTwiceThreaded.lf b/test/C/src/concurrent/ScheduleTwiceThreaded.lf index a368bec1ec..32a5753b41 100644 --- a/test/C/src/concurrent/ScheduleTwiceThreaded.lf +++ b/test/C/src/concurrent/ScheduleTwiceThreaded.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + main reactor { logical action a: int state rc_count: int(0) diff --git a/test/C/src/concurrent/SendingInsideThreaded.lf b/test/C/src/concurrent/SendingInsideThreaded.lf index e08a5dffb5..e566035679 100644 --- a/test/C/src/concurrent/SendingInsideThreaded.lf +++ b/test/C/src/concurrent/SendingInsideThreaded.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Printer { input x: int state count: int(1) diff --git a/test/C/src/concurrent/StarvationThreaded.lf b/test/C/src/concurrent/StarvationThreaded.lf index 58d063647d..248f45a942 100644 --- a/test/C/src/concurrent/StarvationThreaded.lf +++ b/test/C/src/concurrent/StarvationThreaded.lf @@ -7,6 +7,10 @@ */ target C +preamble {= + #include +=} + reactor SuperDenseSender(number_of_iterations: int(10)) { logical action loop output out: int diff --git a/test/C/src/concurrent/StopZeroThreaded.lf b/test/C/src/concurrent/StopZeroThreaded.lf index 051c615566..460cdcfddf 100644 --- a/test/C/src/concurrent/StopZeroThreaded.lf +++ b/test/C/src/concurrent/StopZeroThreaded.lf @@ -6,6 +6,10 @@ */ target C +preamble {= + #include +=} + reactor Sender { output out: int state reaction_invoked_correctly: bool(false) diff --git a/test/C/src/concurrent/Threaded.lf b/test/C/src/concurrent/Threaded.lf index abfcff2c1b..ba8ee162b0 100644 --- a/test/C/src/concurrent/Threaded.lf +++ b/test/C/src/concurrent/Threaded.lf @@ -13,6 +13,10 @@ target C { flags: "" } +preamble {= + #include +=} + reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/concurrent/ThreadedMultiport.lf b/test/C/src/concurrent/ThreadedMultiport.lf index b24ead7cd9..c015078680 100644 --- a/test/C/src/concurrent/ThreadedMultiport.lf +++ b/test/C/src/concurrent/ThreadedMultiport.lf @@ -5,6 +5,10 @@ target C { flags: "" } +preamble {= + #include +=} + reactor Source(width: int(4)) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/concurrent/ThreadedThreaded.lf b/test/C/src/concurrent/ThreadedThreaded.lf index 9db95faaf0..88df0becee 100644 --- a/test/C/src/concurrent/ThreadedThreaded.lf +++ b/test/C/src/concurrent/ThreadedThreaded.lf @@ -12,6 +12,10 @@ target C { flags: "" } +preamble {= + #include +=} + reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/concurrent/TimeLimitThreaded.lf b/test/C/src/concurrent/TimeLimitThreaded.lf index 97bb9cfec6..b7e0b6161d 100644 --- a/test/C/src/concurrent/TimeLimitThreaded.lf +++ b/test/C/src/concurrent/TimeLimitThreaded.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Clock(offset: time(0), period: time(1 sec)) { output y: int timer t(offset, period) diff --git a/test/C/src/concurrent/TimeoutThreaded.lf b/test/C/src/concurrent/TimeoutThreaded.lf index 993366a2c0..d9770e8da2 100644 --- a/test/C/src/concurrent/TimeoutThreaded.lf +++ b/test/C/src/concurrent/TimeoutThreaded.lf @@ -10,6 +10,10 @@ target C { import Sender from "../lib/LoopedActionSender.lf" +preamble {= + #include +=} + reactor Consumer { input in: int state success: bool(false) diff --git a/test/C/src/concurrent/TimeoutZeroThreaded.lf b/test/C/src/concurrent/TimeoutZeroThreaded.lf index 4a0bdd62a3..f42a5b3ad8 100644 --- a/test/C/src/concurrent/TimeoutZeroThreaded.lf +++ b/test/C/src/concurrent/TimeoutZeroThreaded.lf @@ -10,6 +10,10 @@ target C { import Sender from "../lib/LoopedActionSender.lf" +preamble {= + #include +=} + reactor Consumer { input in: int state success: bool(false) diff --git a/test/C/src/concurrent/Tracing.lf b/test/C/src/concurrent/Tracing.lf index ff2f436e85..1e4d478cda 100644 --- a/test/C/src/concurrent/Tracing.lf +++ b/test/C/src/concurrent/Tracing.lf @@ -7,6 +7,10 @@ target C { logging: DEBUG } +preamble {= + #include +=} + reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/docker/FilesPropertyContainerized.lf b/test/C/src/docker/FilesPropertyContainerized.lf index f9a1a240f3..f88c986311 100644 --- a/test/C/src/docker/FilesPropertyContainerized.lf +++ b/test/C/src/docker/FilesPropertyContainerized.lf @@ -4,6 +4,7 @@ target C { } preamble {= + #include #include "hello.h" =} diff --git a/test/C/src/federated/DistributedCountDecentralized.lf b/test/C/src/federated/DistributedCountDecentralized.lf index e7ee0a7d77..9e7c09914b 100644 --- a/test/C/src/federated/DistributedCountDecentralized.lf +++ b/test/C/src/federated/DistributedCountDecentralized.lf @@ -12,6 +12,10 @@ target C { import Count from "../lib/Count.lf" +preamble {= + #include +=} + reactor Print { input in: int state c: int(1) diff --git a/test/C/src/federated/DistributedCountDecentralizedLate.lf b/test/C/src/federated/DistributedCountDecentralizedLate.lf index fa85987e87..bf791f473c 100644 --- a/test/C/src/federated/DistributedCountDecentralizedLate.lf +++ b/test/C/src/federated/DistributedCountDecentralizedLate.lf @@ -13,6 +13,10 @@ target C { import Count from "../lib/Count.lf" +preamble {= + #include +=} + reactor Print { input in: int // STP () state success: int(0) // STP(in, 30 msec); diff --git a/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf b/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf index 26c20521e3..d5c331bd2f 100644 --- a/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf +++ b/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf @@ -15,6 +15,10 @@ target C { import Count from "../lib/Count.lf" +preamble {= + #include +=} + reactor ImportantActuator { input in: int state success: int(0) diff --git a/test/C/src/federated/DistributedCountPhysical.lf b/test/C/src/federated/DistributedCountPhysical.lf index 67d90ec4c1..20df3dc08c 100644 --- a/test/C/src/federated/DistributedCountPhysical.lf +++ b/test/C/src/federated/DistributedCountPhysical.lf @@ -11,6 +11,10 @@ target C { timeout: 1 sec } +preamble {= + #include +=} + reactor Count { timer t(200 msec, 1 sec) state s: int(0) diff --git a/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf b/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf index 2d13891bae..a250123ca2 100644 --- a/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf +++ b/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf @@ -10,6 +10,10 @@ target C import Count from "../lib/Count.lf" +preamble {= + #include +=} + reactor Print { input in: int state c: int(1) diff --git a/test/C/src/federated/DistributedCountPhysicalDecentralized.lf b/test/C/src/federated/DistributedCountPhysicalDecentralized.lf index 6bc50fce88..d1d39b775d 100644 --- a/test/C/src/federated/DistributedCountPhysicalDecentralized.lf +++ b/test/C/src/federated/DistributedCountPhysicalDecentralized.lf @@ -12,6 +12,10 @@ target C { coordination: decentralized } +preamble {= + #include +=} + reactor Count { timer t(200 msec, 1 sec) state s: int(0) diff --git a/test/C/src/federated/DistributedLoopedAction.lf b/test/C/src/federated/DistributedLoopedAction.lf index 1a70412696..4132667471 100644 --- a/test/C/src/federated/DistributedLoopedAction.lf +++ b/test/C/src/federated/DistributedLoopedAction.lf @@ -10,6 +10,10 @@ target C { import Sender from "../lib/LoopedActionSender.lf" +preamble {= + #include +=} + reactor Receiver(take_a_break_after: int(10), break_interval: time(400 msec)) { input in: int state received_messages: int(0) diff --git a/test/C/src/federated/DistributedNetworkOrder.lf b/test/C/src/federated/DistributedNetworkOrder.lf index 0b9ca0cd17..a41b7853a7 100644 --- a/test/C/src/federated/DistributedNetworkOrder.lf +++ b/test/C/src/federated/DistributedNetworkOrder.lf @@ -13,6 +13,10 @@ target C { build-type: RelWithDebInfo // Release with debug info } +preamble {= + #include +=} + reactor Sender { output out: int timer t(0, 1 msec) diff --git a/test/C/src/federated/DistributedStopZero.lf b/test/C/src/federated/DistributedStopZero.lf index 67141bc624..c50be29cf9 100644 --- a/test/C/src/federated/DistributedStopZero.lf +++ b/test/C/src/federated/DistributedStopZero.lf @@ -6,6 +6,10 @@ */ target C +preamble {= + #include +=} + reactor Sender { output out: int timer t(0, 1 usec) diff --git a/test/C/src/federated/DistributedToken.lf b/test/C/src/federated/DistributedToken.lf index c408af6ad2..a8561fbc1c 100644 --- a/test/C/src/federated/DistributedToken.lf +++ b/test/C/src/federated/DistributedToken.lf @@ -20,6 +20,10 @@ target C { coordination: decentralized } +preamble {= + #include +=} + /** * Reactor that generates a sequence of messages, one per second. The message * will be a string consisting of a root string followed by a count. diff --git a/test/C/src/federated/PingPongDistributedPhysical.lf b/test/C/src/federated/PingPongDistributedPhysical.lf index 95427c2a29..6fe6583cc6 100644 --- a/test/C/src/federated/PingPongDistributedPhysical.lf +++ b/test/C/src/federated/PingPongDistributedPhysical.lf @@ -26,6 +26,10 @@ */ target C +preamble {= + #include +=} + reactor Ping(count: int(10)) { input receive: int output send: int diff --git a/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf b/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf index 19779de3d2..5e9ad0cb09 100644 --- a/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf +++ b/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf @@ -12,6 +12,10 @@ target C { coordination: decentralized } +preamble {= + #include +=} + reactor Sender { output out: int timer t(0, 1 msec) diff --git a/test/C/src/lib/ImportedAgain.lf b/test/C/src/lib/ImportedAgain.lf index 07f2cc9faa..a2c6def138 100644 --- a/test/C/src/lib/ImportedAgain.lf +++ b/test/C/src/lib/ImportedAgain.lf @@ -2,6 +2,10 @@ // itself imports a reactor definition. target C +preamble {= + #include +=} + reactor ImportedAgain { input x: int diff --git a/test/C/src/lib/Test.lf b/test/C/src/lib/Test.lf index ea341ae772..8c78e85252 100644 --- a/test/C/src/lib/Test.lf +++ b/test/C/src/lib/Test.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor TestDouble(expected: double[](1.0, 1.0, 1.0, 1.0)) { input in: double state count: int(0) diff --git a/test/C/src/modal_models/ConvertCaseTest.lf b/test/C/src/modal_models/ConvertCaseTest.lf index 494a3c273c..bb62db6046 100644 --- a/test/C/src/modal_models/ConvertCaseTest.lf +++ b/test/C/src/modal_models/ConvertCaseTest.lf @@ -6,6 +6,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor ResetProcessor { input discard: bool input character: char diff --git a/test/C/src/modal_models/Count3Modes.lf b/test/C/src/modal_models/Count3Modes.lf index 5ef26ccde0..72e0eb262b 100644 --- a/test/C/src/modal_models/Count3Modes.lf +++ b/test/C/src/modal_models/Count3Modes.lf @@ -4,6 +4,10 @@ target C { timeout: 2 sec } +preamble {= + #include +=} + reactor CounterCycle { input next: bool output count: int diff --git a/test/C/src/modal_models/MixedReactions.lf b/test/C/src/modal_models/MixedReactions.lf index e0c9c7f0f7..1a6c8ba99f 100644 --- a/test/C/src/modal_models/MixedReactions.lf +++ b/test/C/src/modal_models/MixedReactions.lf @@ -7,6 +7,10 @@ target C { timeout: 110 msec } +preamble {= + #include +=} + main reactor { state x: int(0) state first: bool(true) diff --git a/test/C/src/modal_models/ModalActions.lf b/test/C/src/modal_models/ModalActions.lf index 1d8dff8cb4..b395820e8e 100644 --- a/test/C/src/modal_models/ModalActions.lf +++ b/test/C/src/modal_models/ModalActions.lf @@ -9,6 +9,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalAfter.lf b/test/C/src/modal_models/ModalAfter.lf index 038a368cc9..1dcae4ff3d 100644 --- a/test/C/src/modal_models/ModalAfter.lf +++ b/test/C/src/modal_models/ModalAfter.lf @@ -9,6 +9,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalCycleBreaker.lf b/test/C/src/modal_models/ModalCycleBreaker.lf index 680323a729..9d51d7391b 100644 --- a/test/C/src/modal_models/ModalCycleBreaker.lf +++ b/test/C/src/modal_models/ModalCycleBreaker.lf @@ -11,6 +11,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input in1: int input in2: int diff --git a/test/C/src/modal_models/ModalNestedReactions.lf b/test/C/src/modal_models/ModalNestedReactions.lf index 454acbfc75..583d51fb9b 100644 --- a/test/C/src/modal_models/ModalNestedReactions.lf +++ b/test/C/src/modal_models/ModalNestedReactions.lf @@ -7,6 +7,10 @@ target C { timeout: 2 sec } +preamble {= + #include +=} + reactor CounterCycle { input next: bool diff --git a/test/C/src/modal_models/ModalStartupShutdown.lf b/test/C/src/modal_models/ModalStartupShutdown.lf index fa1ebaacdf..96c3e74a2c 100644 --- a/test/C/src/modal_models/ModalStartupShutdown.lf +++ b/test/C/src/modal_models/ModalStartupShutdown.lf @@ -6,6 +6,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalStateReset.lf b/test/C/src/modal_models/ModalStateReset.lf index cd963cfd8d..5c27d7c6aa 100644 --- a/test/C/src/modal_models/ModalStateReset.lf +++ b/test/C/src/modal_models/ModalStateReset.lf @@ -6,6 +6,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalStateResetAuto.lf b/test/C/src/modal_models/ModalStateResetAuto.lf index 24cfe9b187..5b6645faae 100644 --- a/test/C/src/modal_models/ModalStateResetAuto.lf +++ b/test/C/src/modal_models/ModalStateResetAuto.lf @@ -6,6 +6,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalTimers.lf b/test/C/src/modal_models/ModalTimers.lf index 47fcf5f9e4..bd5370c72c 100644 --- a/test/C/src/modal_models/ModalTimers.lf +++ b/test/C/src/modal_models/ModalTimers.lf @@ -6,6 +6,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool diff --git a/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf b/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf index 7e75afec13..aec7927c62 100644 --- a/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf +++ b/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf @@ -11,6 +11,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool output count: int diff --git a/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf b/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf index 48b335d2b3..2683eb4de5 100644 --- a/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf +++ b/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf @@ -11,6 +11,10 @@ target C { import TraceTesting from "util/TraceTesting.lf" +preamble {= + #include +=} + reactor Modal { input next: bool output count: int diff --git a/test/C/src/multiport/BankIndexInitializer.lf b/test/C/src/multiport/BankIndexInitializer.lf index a5a30330e1..1d97babff9 100644 --- a/test/C/src/multiport/BankIndexInitializer.lf +++ b/test/C/src/multiport/BankIndexInitializer.lf @@ -1,7 +1,10 @@ // Test bank of reactors to multiport input with id parameter in the bank. target C -preamble {= extern int table[4]; =} +preamble {= + #include + extern int table[4]; +=} reactor Source(bank_index: int(0), value: int(0)) { preamble {= int table[] = {4, 3, 2, 1}; =} diff --git a/test/C/src/multiport/BankToBank.lf b/test/C/src/multiport/BankToBank.lf index 19a784efd4..a8aee088b5 100644 --- a/test/C/src/multiport/BankToBank.lf +++ b/test/C/src/multiport/BankToBank.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(bank_index: int(0)) { timer t(0, 200 msec) output out: int diff --git a/test/C/src/multiport/BankToBankMultiport.lf b/test/C/src/multiport/BankToBankMultiport.lf index 22c5821cc6..3ec44451c3 100644 --- a/test/C/src/multiport/BankToBankMultiport.lf +++ b/test/C/src/multiport/BankToBankMultiport.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(1)) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/BankToBankMultiportAfter.lf b/test/C/src/multiport/BankToBankMultiportAfter.lf index 38daec6ccf..8f701a2136 100644 --- a/test/C/src/multiport/BankToBankMultiportAfter.lf +++ b/test/C/src/multiport/BankToBankMultiportAfter.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(1)) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/BankToMultiport.lf b/test/C/src/multiport/BankToMultiport.lf index ee0ad53dc3..adb74afacd 100644 --- a/test/C/src/multiport/BankToMultiport.lf +++ b/test/C/src/multiport/BankToMultiport.lf @@ -1,6 +1,10 @@ // Test bank of reactors to multiport input with id parameter in the bank. target C +preamble {= + #include +=} + reactor Source(bank_index: int(0)) { output out: int diff --git a/test/C/src/multiport/Broadcast.lf b/test/C/src/multiport/Broadcast.lf index dee0ad62ed..c651d0420d 100644 --- a/test/C/src/multiport/Broadcast.lf +++ b/test/C/src/multiport/Broadcast.lf @@ -3,6 +3,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output out: int diff --git a/test/C/src/multiport/BroadcastAfter.lf b/test/C/src/multiport/BroadcastAfter.lf index b66979e182..c8983b06da 100644 --- a/test/C/src/multiport/BroadcastAfter.lf +++ b/test/C/src/multiport/BroadcastAfter.lf @@ -3,6 +3,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output out: int diff --git a/test/C/src/multiport/BroadcastMultipleAfter.lf b/test/C/src/multiport/BroadcastMultipleAfter.lf index b83540e3d4..2b2b6dc600 100644 --- a/test/C/src/multiport/BroadcastMultipleAfter.lf +++ b/test/C/src/multiport/BroadcastMultipleAfter.lf @@ -3,6 +3,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(value: int(42)) { output out: int diff --git a/test/C/src/multiport/DualBanks.lf b/test/C/src/multiport/DualBanks.lf index aa8faf4b75..012c48fb60 100644 --- a/test/C/src/multiport/DualBanks.lf +++ b/test/C/src/multiport/DualBanks.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Base(bank_index: int(0)) { input I: int state received: bool(false) diff --git a/test/C/src/multiport/DualBanksMultiport.lf b/test/C/src/multiport/DualBanksMultiport.lf index 42c4adb11e..b713eb8afc 100644 --- a/test/C/src/multiport/DualBanksMultiport.lf +++ b/test/C/src/multiport/DualBanksMultiport.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Base(bank_index: int(0)) { input[2] I: int state received: bool(false) diff --git a/test/C/src/multiport/FullyConnected.lf b/test/C/src/multiport/FullyConnected.lf index 8a26fee83f..6f096a09a4 100644 --- a/test/C/src/multiport/FullyConnected.lf +++ b/test/C/src/multiport/FullyConnected.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Node(num_nodes: size_t(4), bank_index: int(0)) { input[num_nodes] in: int output out: int diff --git a/test/C/src/multiport/FullyConnectedAddressable.lf b/test/C/src/multiport/FullyConnectedAddressable.lf index ae99d5397e..37fd7cccfa 100644 --- a/test/C/src/multiport/FullyConnectedAddressable.lf +++ b/test/C/src/multiport/FullyConnectedAddressable.lf @@ -1,6 +1,10 @@ // In this pattern, each node can send direct messages to individual other nodes target C +preamble {= + #include +=} + reactor Node(num_nodes: size_t(4), bank_index: int(0)) { input[num_nodes] in: int output[num_nodes] out: int diff --git a/test/C/src/multiport/MultiportFromBank.lf b/test/C/src/multiport/MultiportFromBank.lf index b8ade7a354..e182b1f72c 100644 --- a/test/C/src/multiport/MultiportFromBank.lf +++ b/test/C/src/multiport/MultiportFromBank.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(check_override: int(0), bank_index: int(0)) { output out: int diff --git a/test/C/src/multiport/MultiportFromHierarchy.lf b/test/C/src/multiport/MultiportFromHierarchy.lf index f38661345c..41293d7bc5 100644 --- a/test/C/src/multiport/MultiportFromHierarchy.lf +++ b/test/C/src/multiport/MultiportFromHierarchy.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(3)) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportFromReaction.lf b/test/C/src/multiport/MultiportFromReaction.lf index acaa59e519..a931715a84 100644 --- a/test/C/src/multiport/MultiportFromReaction.lf +++ b/test/C/src/multiport/MultiportFromReaction.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Destination(width: int(1)) { state s: int(6) input[width] in: int diff --git a/test/C/src/multiport/MultiportIn.lf b/test/C/src/multiport/MultiportIn.lf index 80269896d8..c21c49d0fd 100644 --- a/test/C/src/multiport/MultiportIn.lf +++ b/test/C/src/multiport/MultiportIn.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/multiport/MultiportInParameterized.lf b/test/C/src/multiport/MultiportInParameterized.lf index cd9bb27ad2..2e4fcdaa55 100644 --- a/test/C/src/multiport/MultiportInParameterized.lf +++ b/test/C/src/multiport/MultiportInParameterized.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/multiport/MultiportMutableInputArray.lf b/test/C/src/multiport/MultiportMutableInputArray.lf index cd279bb6a2..2d072d4b92 100644 --- a/test/C/src/multiport/MultiportMutableInputArray.lf +++ b/test/C/src/multiport/MultiportMutableInputArray.lf @@ -4,6 +4,10 @@ // Print. It gets freed after Print is done with it. target C +preamble {= + #include +=} + reactor Source { output[2] out: int[] diff --git a/test/C/src/multiport/MultiportOut.lf b/test/C/src/multiport/MultiportOut.lf index c2707d5d33..52f7b571da 100644 --- a/test/C/src/multiport/MultiportOut.lf +++ b/test/C/src/multiport/MultiportOut.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { timer t(0, 200 msec) output[4] out: int diff --git a/test/C/src/multiport/MultiportToBank.lf b/test/C/src/multiport/MultiportToBank.lf index c1f19d3553..16bde64f71 100644 --- a/test/C/src/multiport/MultiportToBank.lf +++ b/test/C/src/multiport/MultiportToBank.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(2)) { output[width] out: int // Connected to a bank of Destination reactors input dummy: int // Not connected to anything diff --git a/test/C/src/multiport/MultiportToBankAfter.lf b/test/C/src/multiport/MultiportToBankAfter.lf index 66e0fdf837..562f139152 100644 --- a/test/C/src/multiport/MultiportToBankAfter.lf +++ b/test/C/src/multiport/MultiportToBankAfter.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(2)) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToBankDouble.lf b/test/C/src/multiport/MultiportToBankDouble.lf index a116ef9c00..c5216a9e55 100644 --- a/test/C/src/multiport/MultiportToBankDouble.lf +++ b/test/C/src/multiport/MultiportToBankDouble.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output[3] out: int // Connected to a bank of Destination reactors diff --git a/test/C/src/multiport/MultiportToBankHierarchy.lf b/test/C/src/multiport/MultiportToBankHierarchy.lf index e4f231390f..10602ab990 100644 --- a/test/C/src/multiport/MultiportToBankHierarchy.lf +++ b/test/C/src/multiport/MultiportToBankHierarchy.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(2)) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToHierarchy.lf b/test/C/src/multiport/MultiportToHierarchy.lf index 24290b56a5..d175fc18b9 100644 --- a/test/C/src/multiport/MultiportToHierarchy.lf +++ b/test/C/src/multiport/MultiportToHierarchy.lf @@ -6,6 +6,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(2)) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiport.lf b/test/C/src/multiport/MultiportToMultiport.lf index bf4bbefde4..c8d87f888e 100644 --- a/test/C/src/multiport/MultiportToMultiport.lf +++ b/test/C/src/multiport/MultiportToMultiport.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(1)) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiport2.lf b/test/C/src/multiport/MultiportToMultiport2.lf index 29a8632399..2f14f89b4a 100644 --- a/test/C/src/multiport/MultiportToMultiport2.lf +++ b/test/C/src/multiport/MultiportToMultiport2.lf @@ -1,6 +1,10 @@ // Test multiport to multiport connections. See also MultiportToMultiport. target C +preamble {= + #include +=} + reactor Source(width: int(2)) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiport2After.lf b/test/C/src/multiport/MultiportToMultiport2After.lf index b6f078a099..371116281c 100644 --- a/test/C/src/multiport/MultiportToMultiport2After.lf +++ b/test/C/src/multiport/MultiportToMultiport2After.lf @@ -1,6 +1,10 @@ // Test multiport to multiport connections. See also MultiportToMultiport. target C +preamble {= + #include +=} + reactor Source(width: int(2)) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiportArray.lf b/test/C/src/multiport/MultiportToMultiportArray.lf index 100a57c393..dcea70b544 100644 --- a/test/C/src/multiport/MultiportToMultiportArray.lf +++ b/test/C/src/multiport/MultiportToMultiportArray.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { timer t(0, 200 msec) output[2] out: int[] diff --git a/test/C/src/multiport/MultiportToMultiportParameter.lf b/test/C/src/multiport/MultiportToMultiportParameter.lf index 9dc7288a52..9e715e3cd3 100644 --- a/test/C/src/multiport/MultiportToMultiportParameter.lf +++ b/test/C/src/multiport/MultiportToMultiportParameter.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(1)) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportToPort.lf b/test/C/src/multiport/MultiportToPort.lf index ccee46566c..48d1f15758 100644 --- a/test/C/src/multiport/MultiportToPort.lf +++ b/test/C/src/multiport/MultiportToPort.lf @@ -5,6 +5,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output[2] out: int diff --git a/test/C/src/multiport/MultiportToReaction.lf b/test/C/src/multiport/MultiportToReaction.lf index 62e2c302f2..2259f47b27 100644 --- a/test/C/src/multiport/MultiportToReaction.lf +++ b/test/C/src/multiport/MultiportToReaction.lf @@ -4,6 +4,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source(width: int(1)) { timer t(0, 200 msec) state s: int(0) diff --git a/test/C/src/multiport/PipelineAfter.lf b/test/C/src/multiport/PipelineAfter.lf index a9f9085873..a32973a65c 100644 --- a/test/C/src/multiport/PipelineAfter.lf +++ b/test/C/src/multiport/PipelineAfter.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor Source { output out: unsigned diff --git a/test/C/src/no_inlining/Count.lf b/test/C/src/no_inlining/Count.lf index f8fd51bec7..009af57489 100644 --- a/test/C/src/no_inlining/Count.lf +++ b/test/C/src/no_inlining/Count.lf @@ -3,6 +3,10 @@ target C { files: ["../../c"] } +preamble {= + #include +=} + main reactor Count { timer t(0, 1 msec) diff --git a/test/C/src/serialization/PersonProtocolBuffers.lf b/test/C/src/serialization/PersonProtocolBuffers.lf index a01243d846..6e12989a46 100644 --- a/test/C/src/serialization/PersonProtocolBuffers.lf +++ b/test/C/src/serialization/PersonProtocolBuffers.lf @@ -23,6 +23,10 @@ target C { protobufs: Person.proto } +preamble {= + #include +=} + main reactor { reaction(startup) {= Person person = PERSON__INIT; // Macro to create the protocol buffer diff --git a/test/C/src/serialization/ProtoNoPacking.lf b/test/C/src/serialization/ProtoNoPacking.lf index 283e4feafb..2929a67f6a 100644 --- a/test/C/src/serialization/ProtoNoPacking.lf +++ b/test/C/src/serialization/ProtoNoPacking.lf @@ -22,6 +22,10 @@ target C { protobufs: [ProtoHelloWorld.proto] } +preamble {= + #include +=} + reactor SourceProto { output out: ProtoHelloWorld diff --git a/test/C/src/target/HelloWorldCCPP.lf b/test/C/src/target/HelloWorldCCPP.lf index 0b0e54ed52..490c6283d2 100644 --- a/test/C/src/target/HelloWorldCCPP.lf +++ b/test/C/src/target/HelloWorldCCPP.lf @@ -7,6 +7,10 @@ target CCpp { logging: DEBUG } +preamble {= + #include +=} + reactor HelloWorld { preamble {= #include diff --git a/test/C/src/token/TokenContainedSource.lf b/test/C/src/token/TokenContainedSource.lf index 9bf517bc18..375e859aa7 100644 --- a/test/C/src/token/TokenContainedSource.lf +++ b/test/C/src/token/TokenContainedSource.lf @@ -9,6 +9,10 @@ target C { import TokenSource from "lib/Token.lf" +preamble {= + #include +=} + main reactor(scale: int(1)) { state count: int(0) state input_received: bool(false) diff --git a/test/C/src/token/TokenContainedSourceBank.lf b/test/C/src/token/TokenContainedSourceBank.lf index f1faee87dd..a92453ef88 100644 --- a/test/C/src/token/TokenContainedSourceBank.lf +++ b/test/C/src/token/TokenContainedSourceBank.lf @@ -10,6 +10,10 @@ target C { import TokenSource from "lib/Token.lf" +preamble {= + #include +=} + main reactor(scale: int(1)) { state count: int(0) state input_received: bool(false) diff --git a/test/C/src/token/lib/Token.lf b/test/C/src/token/lib/Token.lf index 4e49cd0006..3fbfcdb534 100644 --- a/test/C/src/token/lib/Token.lf +++ b/test/C/src/token/lib/Token.lf @@ -8,6 +8,7 @@ target C { } preamble {= + #include #include "array.h" =} diff --git a/test/C/src/zephyr/HelloZephyr.lf b/test/C/src/zephyr/HelloZephyr.lf index 2c4a98890f..0768fcaa4d 100644 --- a/test/C/src/zephyr/HelloZephyr.lf +++ b/test/C/src/zephyr/HelloZephyr.lf @@ -6,6 +6,10 @@ target C { } } +preamble {= + #include +=} + main reactor { reaction(startup) {= printf("Hello World!\n"); =} } diff --git a/test/C/src/zephyr/Timer.lf b/test/C/src/zephyr/Timer.lf index cac30ae9b1..ae426361bd 100644 --- a/test/C/src/zephyr/Timer.lf +++ b/test/C/src/zephyr/Timer.lf @@ -6,6 +6,10 @@ target C { threading: false } +preamble {= + #include +=} + main reactor { timer t(0, 1 sec) diff --git a/test/C/src/zephyr/lib/Led.lf b/test/C/src/zephyr/lib/Led.lf index 04999cf14b..c006f35aad 100644 --- a/test/C/src/zephyr/lib/Led.lf +++ b/test/C/src/zephyr/lib/Led.lf @@ -1,5 +1,9 @@ target C +preamble {= + #include +=} + reactor NrfLeds { preamble {= #include From 1fa316c6e304baefbdf57668a318ac8ef71d66bb Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 13:48:40 -0700 Subject: [PATCH 57/92] Prune user-visible namespace. See corresponding commit message in reactor-c --- org.lflang/src/lib/c/reactor-c | 2 +- .../org/lflang/generator/c/CGenerator.java | 191 +++++++++--------- .../generator/c/CPreambleGenerator.java | 2 + 3 files changed, 95 insertions(+), 100 deletions(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index d71b259c29..43221e5837 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit d71b259c299bbd52d98a3f38be2f28db899190c7 +Subproject commit 43221e58375a2416ad1f9d0b2811a9c8d670041f diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index fcd1cc3c78..455618655d 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -465,111 +465,77 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { var cFilename = CCompiler.getTargetFileName(lfModuleName, this.CCppMode, targetConfig); var targetFile = fileConfig.getSrcGenPath() + File.separator + cFilename; try { - generateCodeFor(lfModuleName); - - - String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; - - // Copy the core lib - FileUtil.copyDirectoryFromClassPath( - "/lib/c/reactor-c/core", - fileConfig.getSrcGenPath().resolve(srcPrefix + "core"), - true - ); - // Copy the C target files - copyTargetFiles(); - - // For the Zephyr target, copy default config and board files. - if (targetConfig.platformOptions.platform == Platform.ZEPHYR) { - FileUtil.copyDirectoryFromClassPath( - "/lib/platform/zephyr/boards", - fileConfig.getSrcGenPath().resolve("boards"), - false - ); - FileUtil.copyFileFromClassPath( - "/lib/platform/zephyr/prj_lf.conf", - fileConfig.getSrcGenPath().resolve("prj_lf.conf"), - true - ); - - FileUtil.copyFileFromClassPath( - "/lib/platform/zephyr/Kconfig", - fileConfig.getSrcGenPath().resolve("Kconfig"), - true - ); - } + generateCodeFor(lfModuleName); + copyTargetFiles(); + generateHeaders(); + code.writeToFile(targetFile); + } catch (IOException e) { + //noinspection ThrowableNotThrown,ResultOfMethodCallIgnored + Exceptions.sneakyThrow(e); + } - generateHeaders(); + // Create docker file. + if (targetConfig.dockerOptions != null && mainDef != null) { + try { + var dockerData = getDockerGenerator(context).generateDockerData(); + dockerData.writeDockerFile(); + (new DockerComposeGenerator(context)).writeDockerComposeFile(List.of(dockerData)); + } catch (IOException e) { + throw new RuntimeException("Error while writing Docker files", e); + } + } - // Write the generated code - code.writeToFile(targetFile); + // If cmake is requested, generate the CMakeLists.txt + if (targetConfig.platformOptions.platform != Platform.ARDUINO) { + var cmakeFile = fileConfig.getSrcGenPath() + File.separator + "CMakeLists.txt"; + var sources = new HashSet<>(ASTUtils.recursiveChildren(main)).stream() + .map(CUtil::getName).map(it -> it + (CCppMode ? ".cpp" : ".c")) + .collect(Collectors.toList()); + sources.add(cFilename); + var cmakeCode = cmakeGenerator.generateCMakeCode( + sources, + lfModuleName, + errorReporter, + CCppMode, + mainDef != null, + cMakeExtras, + targetConfig + ); + try { + cmakeCode.writeToFile(cmakeFile); } catch (IOException e) { //noinspection ThrowableNotThrown,ResultOfMethodCallIgnored Exceptions.sneakyThrow(e); } - - // Create docker file. - if (targetConfig.dockerOptions != null && mainDef != null) { - try { - var dockerData = getDockerGenerator(context).generateDockerData(); - dockerData.writeDockerFile(); - (new DockerComposeGenerator(context)).writeDockerComposeFile(List.of(dockerData)); - } catch (IOException e) { - throw new RuntimeException("Error while writing Docker files", e); - } + } else { + try { + Path include = fileConfig.getSrcGenPath().resolve("include/"); + Path src = fileConfig.getSrcGenPath().resolve("src/"); + FileUtil.arduinoDeleteHelper(src, targetConfig.threading); + FileUtil.relativeIncludeHelper(src, include); + FileUtil.relativeIncludeHelper(include, include); + } catch (IOException e) { + //noinspection ThrowableNotThrown,ResultOfMethodCallIgnored + Exceptions.sneakyThrow(e); } - // If cmake is requested, generate the CMakeLists.txt - if (targetConfig.platformOptions.platform != Platform.ARDUINO) { - var cmakeFile = fileConfig.getSrcGenPath() + File.separator + "CMakeLists.txt"; - var sources = new HashSet<>(ASTUtils.recursiveChildren(main)).stream() - .map(CUtil::getName).map(it -> it + (CCppMode ? ".cpp" : ".c")) - .collect(Collectors.toList()); - sources.add(cFilename); - var cmakeCode = cmakeGenerator.generateCMakeCode( - sources, - lfModuleName, - errorReporter, - CCppMode, - mainDef != null, - cMakeExtras, - targetConfig + if (!targetConfig.noCompile) { + ArduinoUtil arduinoUtil = new ArduinoUtil(context, commandFactory, errorReporter); + arduinoUtil.buildArduino(fileConfig, targetConfig); + context.finish( + GeneratorResult.Status.COMPILED, null ); - try { - cmakeCode.writeToFile(cmakeFile); - } catch (IOException e) { - //noinspection ThrowableNotThrown,ResultOfMethodCallIgnored - Exceptions.sneakyThrow(e); - } } else { - try { - Path include = fileConfig.getSrcGenPath().resolve("include/"); - Path src = fileConfig.getSrcGenPath().resolve("src/"); - FileUtil.arduinoDeleteHelper(src, targetConfig.threading); - FileUtil.relativeIncludeHelper(src, include); - FileUtil.relativeIncludeHelper(include, include); - } catch (IOException e) { - //noinspection ThrowableNotThrown,ResultOfMethodCallIgnored - Exceptions.sneakyThrow(e); - } - - if (!targetConfig.noCompile) { - ArduinoUtil arduinoUtil = new ArduinoUtil(context, commandFactory, errorReporter); - arduinoUtil.buildArduino(fileConfig, targetConfig); - context.finish( - GeneratorResult.Status.COMPILED, null - ); - } else { - System.out.println("********"); - System.out.println("To compile your program, run the following command to see information about the board you plugged in:\n\n\tarduino-cli board list\n\nGrab the FQBN and PORT from the command and run the following command in the generated sources directory:\n\n\tarduino-cli compile -b --build-property compiler.c.extra_flags='-DLF_UNTHREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10' --build-property compiler.cpp.extra_flags='-DLF_UNTHREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10' .\n\nTo flash/upload your generated sketch to the board, run the following command in the generated sources directory:\n\n\tarduino-cli upload -b -p \n"); - // System.out.println("For a list of all boards installed on your computer, you can use the following command:\n\n\tarduino-cli board listall\n"); - context.finish( - GeneratorResult.GENERATED_NO_EXECUTABLE.apply(context, null) - ); - } - GeneratorUtils.refreshProject(resource, context.getMode()); - return; + System.out.println("********"); + System.out.println("To compile your program, run the following command to see information about the board you plugged in:\n\n\tarduino-cli board list\n\nGrab the FQBN and PORT from the command and run the following command in the generated sources directory:\n\n\tarduino-cli compile -b --build-property compiler.c.extra_flags='-DLF_UNTHREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10' --build-property compiler.cpp.extra_flags='-DLF_UNTHREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10' .\n\nTo flash/upload your generated sketch to the board, run the following command in the generated sources directory:\n\n\tarduino-cli upload -b -p \n"); + // System.out.println("For a list of all boards installed on your computer, you can use the following command:\n\n\tarduino-cli board listall\n"); + context.finish( + GeneratorResult.GENERATED_NO_EXECUTABLE.apply(context, null) + ); } + GeneratorUtils.refreshProject(resource, context.getMode()); + return; + } // Dump the additional compile definitions to a file to keep the generated project // self-contained. In this way, third-party build tools like PlatformIO, west, arduino-cli can @@ -1012,11 +978,38 @@ protected void copyTargetFiles() throws IOException { String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; - FileUtil.copyDirectoryFromClassPath( - "/lib/c/reactor-c/lib", - fileConfig.getSrcGenPath().resolve(srcPrefix + "lib"), - false - ); + // Copy the core lib + String coreLib = LFGeneratorContext.BuildParm.EXTERNAL_RUNTIME_PATH.getValue(context); + Path dest = fileConfig.getSrcGenPath().resolve(srcPrefix + "core"); + if (coreLib != null) { + FileUtil.copyDirectory(Path.of(coreLib), dest, true); + } else { + FileUtil.copyDirectoryFromClassPath( + "/lib/c/reactor-c/core", + dest, + true + ); + } + + // For the Zephyr target, copy default config and board files. + if (targetConfig.platformOptions.platform == Platform.ZEPHYR) { + FileUtil.copyDirectoryFromClassPath( + "/lib/platform/zephyr/boards", + fileConfig.getSrcGenPath().resolve("boards"), + false + ); + FileUtil.copyFileFromClassPath( + "/lib/platform/zephyr/prj_lf.conf", + fileConfig.getSrcGenPath().resolve("prj_lf.conf"), + true + ); + + FileUtil.copyFileFromClassPath( + "/lib/platform/zephyr/Kconfig", + fileConfig.getSrcGenPath().resolve("Kconfig"), + true + ); + } } //////////////////////////////////////////// diff --git a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java index 503ca0dff2..2c33af51cb 100644 --- a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java @@ -36,6 +36,8 @@ public static String generateIncludeStatements( if (cppMode || targetConfig.platformOptions.platform == Platform.ARDUINO) { code.pr("extern \"C\" {"); } + code.pr("#include "); + code.pr("#include \"platform.h\""); CCoreFilesUtils.getCTargetHeader().forEach( it -> code.pr("#include " + StringUtil.addDoubleQuotes(it)) ); From a8c9693e17d9b880d979fba698326545007b7900 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 14:00:13 -0700 Subject: [PATCH 58/92] Update tracing utilities. --- util/tracing/.gitignore | 2 ++ util/tracing/trace_to_chrome.c | 25 ++++++++++++------------ util/tracing/trace_to_csv.c | 9 +++++---- util/tracing/trace_to_influxdb.c | 33 ++++++++++++++++---------------- util/tracing/trace_util.c | 7 +++++-- 5 files changed, 42 insertions(+), 34 deletions(-) create mode 100644 util/tracing/.gitignore diff --git a/util/tracing/.gitignore b/util/tracing/.gitignore new file mode 100644 index 0000000000..5fe4f5283d --- /dev/null +++ b/util/tracing/.gitignore @@ -0,0 +1,2 @@ +*.o +trace_to_csv diff --git a/util/tracing/trace_to_chrome.c b/util/tracing/trace_to_chrome.c index 92eeee71dd..5cf979227a 100644 --- a/util/tracing/trace_to_chrome.c +++ b/util/tracing/trace_to_chrome.c @@ -31,6 +31,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * point your chrome browser to chrome://tracing/ and the load the .json file. */ #define LF_TRACE +#include #include "reactor.h" #include "trace.h" #include "trace_util.h" @@ -92,7 +93,7 @@ size_t read_and_write_trace(FILE* trace_file, FILE* output_file) { if (reactor_name == NULL) { if (trace[i].event_type == worker_wait_starts || trace[i].event_type == worker_wait_ends) { reactor_name = "WAIT"; - } else if (trace[i].event_type == scheduler_advancing_time_starts + } else if (trace[i].event_type == scheduler_advancing_time_starts || trace[i].event_type == scheduler_advancing_time_starts) { reactor_name = "ADVANCE TIME"; } else { @@ -194,7 +195,7 @@ size_t read_and_write_trace(FILE* trace_file, FILE* output_file) { phase = "E"; break; default: - fprintf(stderr, "WARNING: Unrecognized event type %d: %s\n", + fprintf(stderr, "WARNING: Unrecognized event type %d: %s\n", trace[i].event_type, trace_event_names[trace[i].event_type]); pid = PID_FOR_UNKNOWN_EVENT; phase = "i"; @@ -275,7 +276,7 @@ void write_metadata_events(FILE* output_file) { "\"pid\": 0, " "\"tid\": 0, " "\"args\": {" - "\"name\": \"Main thread\"" + "\"name\": \"Main thread\"" "}},\n" ); @@ -328,7 +329,7 @@ void write_metadata_events(FILE* output_file) { ); } } - + // Write the reactor names for the logical timelines. for (int i = 0; i < object_table_size; i++) { if (object_table[i].type == trace_trigger) { @@ -341,10 +342,10 @@ void write_metadata_events(FILE* output_file) { "\"pid\": %d, " // the "process" to identify by reactor. "\"tid\": %d," // The "thread" to label with action or timer name. "\"args\": {" - "\"name\": \"Trigger %s\"" + "\"name\": \"Trigger %s\"" "}},\n", reactor_index + 1, // Offset of 1 prevents collision with Execution. - i, + i, object_table[i].description); } else if (object_table[i].type == trace_reactor) { fprintf(output_file, "{" @@ -352,7 +353,7 @@ void write_metadata_events(FILE* output_file) { "\"ph\": \"M\", " // mark as metadata. "\"pid\": %d, " // the "process" to label as reactor. "\"args\": {" - "\"name\": \"Reactor %s reactions, actions, and timers in logical time\"" + "\"name\": \"Reactor %s reactions, actions, and timers in logical time\"" "}},\n", i + 1, // Offset of 1 prevents collision with Execution. object_table[i].description); @@ -363,7 +364,7 @@ void write_metadata_events(FILE* output_file) { "\"pid\": %d, " // the "process" to label as reactor. "\"tid\": %d," // The "thread" to label with action or timer name. "\"args\": {" - "\"name\": \"%s\"" + "\"name\": \"%s\"" "}},\n", PID_FOR_USER_EVENT, i, // This is the index in the object table. @@ -376,7 +377,7 @@ void write_metadata_events(FILE* output_file) { "\"ph\": \"M\", " // mark as metadata. "\"pid\": 0, " // the "process" to label "Execution". "\"args\": {" - "\"name\": \"Execution of %s\"" + "\"name\": \"Execution of %s\"" "}},\n", top_level); // Name the "process" for "Worker Waiting" if the PID is not the main execution one. @@ -386,7 +387,7 @@ void write_metadata_events(FILE* output_file) { "\"ph\": \"M\", " // mark as metadata. "\"pid\": %d, " // the "process" to label "Workers waiting for reaction queue". "\"args\": {" - "\"name\": \"Workers waiting for reaction queue\"" + "\"name\": \"Workers waiting for reaction queue\"" "}},\n", PID_FOR_WORKER_WAIT); } @@ -397,7 +398,7 @@ void write_metadata_events(FILE* output_file) { "\"ph\": \"M\", " // mark as metadata. "\"pid\": %d, " // the "process" to label "Workers waiting for reaction queue". "\"args\": {" - "\"name\": \"Workers advancing time\"" + "\"name\": \"Workers advancing time\"" "}},\n", PID_FOR_WORKER_ADVANCING_TIME); } @@ -408,7 +409,7 @@ void write_metadata_events(FILE* output_file) { "\"ph\": \"M\", " // mark as metadata. "\"pid\": %d, " // the "process" to label "User events". "\"args\": {" - "\"name\": \"User events in %s, shown in physical time:\"" + "\"name\": \"User events in %s, shown in physical time:\"" "}}\n", PID_FOR_USER_EVENT, top_level); } diff --git a/util/tracing/trace_to_csv.c b/util/tracing/trace_to_csv.c index 707cc5f43b..44ba37086f 100644 --- a/util/tracing/trace_to_csv.c +++ b/util/tracing/trace_to_csv.c @@ -30,6 +30,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * text file. */ #define LF_TRACE +#include #include "reactor.h" #include "trace.h" #include "trace_util.h" @@ -84,7 +85,7 @@ typedef struct summary_stats_t { reaction_stats_t reactions[MAX_NUM_REACTIONS]; } summary_stats_t; -/** +/** * Sumary stats array. This array has the same size as the * object table. Pointer in the array will be void if there * are no stats for the object table item. @@ -135,7 +136,7 @@ size_t read_and_write_trace() { if (trigger_instance >= 0 && summary_stats[NUM_EVENT_TYPES + trigger_instance] == NULL) { summary_stats[NUM_EVENT_TYPES + trigger_instance] = (summary_stats_t*)calloc(1, sizeof(summary_stats_t)); } - + summary_stats_t* stats = NULL; interval_t exec_time; reaction_stats_t* rstats; @@ -198,7 +199,7 @@ size_t read_and_write_trace() { // commandeer the first entry in the reactions array to track values. stats = summary_stats[NUM_EVENT_TYPES + object_instance]; stats->description = reactor_name; - rstats = &stats->reactions[0]; + rstats = &stats->reactions[0]; rstats->occurrences++; // User values are stored in the "extra_delay" field, which is an interval_t. interval_t value = trace[i].extra_delay; @@ -332,7 +333,7 @@ void write_summary_file() { first = true; for (int i = NUM_EVENT_TYPES; i < table_size; i++) { summary_stats_t* stats = summary_stats[i]; - if (stats != NULL + if (stats != NULL && (stats->event_type == user_event || stats->event_type == user_value) && stats->occurrences > 0) { if (first) { diff --git a/util/tracing/trace_to_influxdb.c b/util/tracing/trace_to_influxdb.c index a99ae003ec..aa50911e5e 100644 --- a/util/tracing/trace_to_influxdb.c +++ b/util/tracing/trace_to_influxdb.c @@ -27,13 +27,13 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @section DESCRIPTION - * + * * Standalone program to send a Lingua Franca trace file to InfluxDB. * InfluxDB is a database server to which data can be posted using HTTP * or sent as a UDP datagram. - * + * * ## Compiling this Program - * + * * To compile this program, simply do this in this source directory: * ``` * make install @@ -41,13 +41,13 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * This will place an executable program `trace_to_influxdb` in the directory `lingua-franca/bin`. * I find it convenient to have this directory in my `PATH` (this is also where the * `lfc` command-line Lingua Franca compiler is located). - * + * * ## Setting up InfluxDB - * + * * To set up InfluxDB, see: - * + * * [https://docs.influxdata.com/influxdb/v2.0/get-started/](https://docs.influxdata.com/influxdb/v2.0/get-started/) - * + * * If you have previously installed InfluxDB and you want a fresh start, do this: * ```shell * rm -rf ~/.influxdbv2/ @@ -58,13 +58,13 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * kill -9 PID * ``` * where 'PID' is replaced with whatever process ID(s) are reported by the `ps` command above. - * + * * To start an InfluxDB server on localhost with port 8087: * ```shell * influxd --http-bind-address :8087 --reporting-disabled * ``` * The 'reporting-disabled' option simply disables notifications to the InfluxDB mother ship. - * + * * You then need to set up at least one user, organization, and bucket. You can do this by pointing your browser to * ``` * http://localhost:8087 @@ -77,9 +77,9 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ``` * The UI in the browser will then give you the options Quick Start or Advanced, either of which you can select. * If you select "Data" on the left, you can browse Buckets to verify that your test bucket was created. - * + * * ## Uploading Trace Data to InfluxDB - * + * * First, generate a trace file by setting a target parameter in a Lingua Franca program: * ``` * target C { @@ -87,7 +87,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * }; * ``` * Then, when you run this program, a binary file with extension `.lft` will be created. - * + * * In your browser, in the InfluxDB UI, select Data on the left, then select the Tokens tab. * Select a token and copy the token string to clipboard. It will looks something like this: * ``` @@ -100,15 +100,16 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ``` * where 'Filename' and the token are replaced with your values. * This will upload the trace data to InfluxDB. - * + * * You can also specify the following command-line options: * * -h, --host: The host name running InfluxDB. If not given, this defaults to "localhost". * * -p, --port: The port for accessing InfluxDB. This defaults to 8086. If you used 8087, as shown above, then you have to give this option. - * + * * The data can then be viewed in the InfluxDB browser, or you can configure an external * tool such as Grafana to visualize it (see https://grafana.com/docs/grafana/latest/datasources/influxdb/). */ #define LF_TRACE +#include #include "reactor.h" #include "trace.h" #include "trace_util.h" @@ -208,7 +209,7 @@ int main(int argc, char* argv[]) { influx_v2_client.token = NULL; influx_v2_client.host = "localhost"; influx_v2_client.port = 8086; - influx_v2_client.org = "iCyPhy"; + influx_v2_client.org = "iCyPhy"; influx_v2_client.bucket = "test"; char* filename = NULL; @@ -277,4 +278,4 @@ int main(int argc, char* argv[]) { printf("***** %zu records written to InfluxDB.\n", num_records); // File closing is handled by termination function. } -} \ No newline at end of file +} diff --git a/util/tracing/trace_util.c b/util/tracing/trace_util.c index 0f97b3bdb9..551ec94473 100644 --- a/util/tracing/trace_util.c +++ b/util/tracing/trace_util.c @@ -30,6 +30,9 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * text file. */ #define LF_TRACE +#include +#include +#include #include "reactor.h" #include "trace.h" #include "trace_util.h" @@ -187,12 +190,12 @@ void print_table() { } else { type = "unknown type"; } - printf("pointer = %p, trigger = %p, type = %s: %s\n", + printf("pointer = %p, trigger = %p, type = %s: %s\n", object_table[i].pointer, object_table[i].trigger, type, object_table[i].description); - } + } printf("-------\n"); } From 9729f27f475ebbe4a8ff970b848797b6e9ed5181 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 14:06:23 -0700 Subject: [PATCH 59/92] Update submodule. --- org.lflang/src/lib/c/reactor-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index 43221e5837..493805af82 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit 43221e58375a2416ad1f9d0b2811a9c8d670041f +Subproject commit 493805af82ae1c423c50083dc2581c8cca5d55c7 From 84cae076618747b84162e01117f885c9a9a38715 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 14:09:34 -0700 Subject: [PATCH 60/92] Another fix in tracing utilities. --- util/tracing/trace_to_csv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/util/tracing/trace_to_csv.c b/util/tracing/trace_to_csv.c index 44ba37086f..1abf08c082 100644 --- a/util/tracing/trace_to_csv.c +++ b/util/tracing/trace_to_csv.c @@ -31,6 +31,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define LF_TRACE #include +#include #include "reactor.h" #include "trace.h" #include "trace_util.h" From c130d603e612cfe4f05b97c23b44c1c9b8550160 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 14:51:28 -0700 Subject: [PATCH 61/92] Repair runtime copying. --- .../src/org/lflang/generator/c/CGenerator.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 455618655d..8825e75ac9 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -975,18 +975,21 @@ private void pickCompilePlatform() { * Copy target-specific header file to the src-gen directory. */ protected void copyTargetFiles() throws IOException { - - String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : ""; - // Copy the core lib String coreLib = LFGeneratorContext.BuildParm.EXTERNAL_RUNTIME_PATH.getValue(context); - Path dest = fileConfig.getSrcGenPath().resolve(srcPrefix + "core"); + Path dest = fileConfig.getSrcGenPath(); + if (targetConfig.platformOptions.platform == Platform.ARDUINO) dest = dest.resolve("src"); if (coreLib != null) { FileUtil.copyDirectory(Path.of(coreLib), dest, true); } else { FileUtil.copyDirectoryFromClassPath( "/lib/c/reactor-c/core", - dest, + dest.resolve("core"), + true + ); + FileUtil.copyDirectoryFromClassPath( + "/lib/c/reactor-c/lib", + dest.resolve("lib"), true ); } From 8009d8bc4e5d9694e34fb81740fa93cd653d629e Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 15:30:12 -0700 Subject: [PATCH 62/92] More missing #includes in tests. --- test/C/src/CharLiteralInitializer.lf | 4 ++++ test/C/src/TriggerDownstreamOnlyIfPresent2.lf | 4 ++++ test/C/src/federated/HelloDistributed.lf | 5 +++++ test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/test/C/src/CharLiteralInitializer.lf b/test/C/src/CharLiteralInitializer.lf index 9ee206efbf..358f4ce8b3 100644 --- a/test/C/src/CharLiteralInitializer.lf +++ b/test/C/src/CharLiteralInitializer.lf @@ -1,6 +1,10 @@ // Check that a state variable can have a char literal initializer target C +preamble {= + #include +=} + main reactor CharLiteralInitializer { state c: char('x') diff --git a/test/C/src/TriggerDownstreamOnlyIfPresent2.lf b/test/C/src/TriggerDownstreamOnlyIfPresent2.lf index 544d269242..72737e80c7 100644 --- a/test/C/src/TriggerDownstreamOnlyIfPresent2.lf +++ b/test/C/src/TriggerDownstreamOnlyIfPresent2.lf @@ -7,6 +7,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output[2] out: int state count: int(0) diff --git a/test/C/src/federated/HelloDistributed.lf b/test/C/src/federated/HelloDistributed.lf index 14b446f26d..bd9a2cc4e0 100644 --- a/test/C/src/federated/HelloDistributed.lf +++ b/test/C/src/federated/HelloDistributed.lf @@ -7,6 +7,11 @@ */ target C +preamble {= + #include + #include +=} + reactor Source { output out: string diff --git a/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf b/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf index c696261db7..042d4ecc20 100644 --- a/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf +++ b/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf @@ -7,6 +7,10 @@ target C { fast: true } +preamble {= + #include +=} + reactor Source { output a: int output b: int From 368f01a7156b737df6ed6f520191206e771566c4 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 24 Mar 2023 23:26:47 -0700 Subject: [PATCH 63/92] Address another round of test failures. These are all related to the namespace pruning. --- org.lflang/src/lib/c/reactor-c | 2 +- org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java | 2 +- test/C/src/concurrent/AsyncCallback.lf | 4 +++- test/C/src/concurrent/AsyncCallbackDrop.lf | 1 + test/C/src/concurrent/AsyncCallbackReplace.lf | 1 + test/C/src/concurrent/DeadlineHandledAboveThreaded.lf | 3 ++- test/C/src/concurrent/DeadlineThreaded.lf | 3 ++- test/C/src/concurrent/HelloThreaded.lf | 1 + test/C/src/concurrent/Tracing.lf | 1 + 9 files changed, 13 insertions(+), 5 deletions(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index 493805af82..220da23b8a 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit 493805af82ae1c423c50083dc2581c8cca5d55c7 +Subproject commit 220da23b8ae7c7436a9f6900a319b6e246ae7fdd diff --git a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java index 2c33af51cb..8ca0404d75 100644 --- a/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java @@ -37,7 +37,7 @@ public static String generateIncludeStatements( code.pr("extern \"C\" {"); } code.pr("#include "); - code.pr("#include \"platform.h\""); + code.pr("#include \"include/core/platform.h\""); CCoreFilesUtils.getCTargetHeader().forEach( it -> code.pr("#include " + StringUtil.addDoubleQuotes(it)) ); diff --git a/test/C/src/concurrent/AsyncCallback.lf b/test/C/src/concurrent/AsyncCallback.lf index 817cc60457..6d1ae33fdf 100644 --- a/test/C/src/concurrent/AsyncCallback.lf +++ b/test/C/src/concurrent/AsyncCallback.lf @@ -9,11 +9,13 @@ */ target C { tracing: true, - timeout: 2 sec + timeout: 2 sec, + keepalive: true } preamble {= #include + #include "platform.h" =} main reactor AsyncCallback { diff --git a/test/C/src/concurrent/AsyncCallbackDrop.lf b/test/C/src/concurrent/AsyncCallbackDrop.lf index 055e13fb66..1d7de28cab 100644 --- a/test/C/src/concurrent/AsyncCallbackDrop.lf +++ b/test/C/src/concurrent/AsyncCallbackDrop.lf @@ -9,6 +9,7 @@ target C { preamble {= #include + #include "platform.h" =} main reactor { diff --git a/test/C/src/concurrent/AsyncCallbackReplace.lf b/test/C/src/concurrent/AsyncCallbackReplace.lf index 287dceb9ab..436c724cb6 100644 --- a/test/C/src/concurrent/AsyncCallbackReplace.lf +++ b/test/C/src/concurrent/AsyncCallbackReplace.lf @@ -9,6 +9,7 @@ target C { preamble {= #include + #include "platform.h" =} main reactor { diff --git a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf index 9886ef5630..ebbc830512 100644 --- a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf +++ b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf @@ -4,6 +4,7 @@ target C preamble {= #include + #include "platform.h" =} reactor Deadline(threshold: time(100 msec)) { @@ -24,7 +25,7 @@ main reactor { d = new Deadline(threshold = 10 msec) reaction(startup) -> d.x {= - lf_nanosleep(MSEC(200)); + lf_sleep(MSEC(200)); lf_set(d.x, 42); =} diff --git a/test/C/src/concurrent/DeadlineThreaded.lf b/test/C/src/concurrent/DeadlineThreaded.lf index 914e7efee6..e03fedc1d4 100644 --- a/test/C/src/concurrent/DeadlineThreaded.lf +++ b/test/C/src/concurrent/DeadlineThreaded.lf @@ -7,6 +7,7 @@ target C { preamble {= #include + #include "platform.h" =} reactor Source(period: time(3000 msec)) { @@ -18,7 +19,7 @@ reactor Source(period: time(3000 msec)) { if (2 * (self->count / 2) != self->count) { // The count variable is odd. // Take time to cause a deadline violation. - lf_nanosleep(MSEC(210)); + lf_sleep(MSEC(210)); } printf("Source sends: %d.\n", self->count); lf_set(y, self->count); diff --git a/test/C/src/concurrent/HelloThreaded.lf b/test/C/src/concurrent/HelloThreaded.lf index ef5cdae997..68455ff951 100644 --- a/test/C/src/concurrent/HelloThreaded.lf +++ b/test/C/src/concurrent/HelloThreaded.lf @@ -10,6 +10,7 @@ target C { preamble {= #include + #include =} reactor Reschedule(period: time(2 sec), message: string("Hello C")) { diff --git a/test/C/src/concurrent/Tracing.lf b/test/C/src/concurrent/Tracing.lf index 1e4d478cda..fd4224878f 100644 --- a/test/C/src/concurrent/Tracing.lf +++ b/test/C/src/concurrent/Tracing.lf @@ -9,6 +9,7 @@ target C { preamble {= #include + #include =} reactor Source { From 26e0637a57a93e9ef47b4b0860c88ee725f9f400 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 25 Mar 2023 00:00:13 -0700 Subject: [PATCH 64/92] Address another round of test failures. These are all related to the namespace pruning. --- test/C/src/Hello.lf | 1 + test/C/src/concurrent/AsyncCallback.lf | 8 +++++++- test/C/src/concurrent/AsyncCallbackDrop.lf | 6 ++++++ test/C/src/concurrent/AsyncCallbackReplace.lf | 6 ++++++ test/C/src/concurrent/DeadlineHandledAboveThreaded.lf | 6 ++++++ test/C/src/concurrent/DeadlineThreaded.lf | 6 ++++++ 6 files changed, 32 insertions(+), 1 deletion(-) diff --git a/test/C/src/Hello.lf b/test/C/src/Hello.lf index ac52790967..5c8195ca3b 100644 --- a/test/C/src/Hello.lf +++ b/test/C/src/Hello.lf @@ -10,6 +10,7 @@ target C { preamble {= #include + #include =} reactor Reschedule(period: time(2 sec), message: string("Hello C")) { diff --git a/test/C/src/concurrent/AsyncCallback.lf b/test/C/src/concurrent/AsyncCallback.lf index 6d1ae33fdf..6835c32ba9 100644 --- a/test/C/src/concurrent/AsyncCallback.lf +++ b/test/C/src/concurrent/AsyncCallback.lf @@ -7,15 +7,21 @@ * Note: This test uses the LF platform support to enable it to run on multiple * platforms. */ -target C { +target CCpp { tracing: true, timeout: 2 sec, keepalive: true } preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include #include "platform.h" + #ifdef __cplusplus + } + #endif =} main reactor AsyncCallback { diff --git a/test/C/src/concurrent/AsyncCallbackDrop.lf b/test/C/src/concurrent/AsyncCallbackDrop.lf index 1d7de28cab..356015ade0 100644 --- a/test/C/src/concurrent/AsyncCallbackDrop.lf +++ b/test/C/src/concurrent/AsyncCallbackDrop.lf @@ -8,8 +8,14 @@ target C { } preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include #include "platform.h" + #ifdef __cplusplus + } + #endif =} main reactor { diff --git a/test/C/src/concurrent/AsyncCallbackReplace.lf b/test/C/src/concurrent/AsyncCallbackReplace.lf index 436c724cb6..56530aa2c0 100644 --- a/test/C/src/concurrent/AsyncCallbackReplace.lf +++ b/test/C/src/concurrent/AsyncCallbackReplace.lf @@ -8,8 +8,14 @@ target C { } preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include #include "platform.h" + #ifdef __cplusplus + } + #endif =} main reactor { diff --git a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf index ebbc830512..a40450c5bd 100644 --- a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf +++ b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf @@ -3,8 +3,14 @@ target C preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include #include "platform.h" + #ifdef __cplusplus + } + #endif =} reactor Deadline(threshold: time(100 msec)) { diff --git a/test/C/src/concurrent/DeadlineThreaded.lf b/test/C/src/concurrent/DeadlineThreaded.lf index e03fedc1d4..ff9787c661 100644 --- a/test/C/src/concurrent/DeadlineThreaded.lf +++ b/test/C/src/concurrent/DeadlineThreaded.lf @@ -6,8 +6,14 @@ target C { } preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include #include "platform.h" + #ifdef __cplusplus + } + #endif =} reactor Source(period: time(3000 msec)) { From bfb69ec4b11b81044d5439933e8cd5085fb44071 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 25 Mar 2023 08:20:20 -0700 Subject: [PATCH 65/92] Address another round of test failures. These are all related to the namespace pruning. --- test/C/src/Deadline.lf | 9 ++++++++- test/C/src/DeadlineHandledAbove.lf | 7 +++++++ test/C/src/DelayString.lf | 7 +++++++ test/C/src/ScheduleValue.lf | 8 ++++++++ test/C/src/SimpleDeadline.lf | 7 +++++++ test/C/src/TestForPreviousOutput.lf | 7 +++++++ 6 files changed, 44 insertions(+), 1 deletion(-) diff --git a/test/C/src/Deadline.lf b/test/C/src/Deadline.lf index 6964d8f90f..118e1db7b0 100644 --- a/test/C/src/Deadline.lf +++ b/test/C/src/Deadline.lf @@ -1,12 +1,19 @@ // This example illustrates local deadline handling. Even numbers are sent by // the Source immediately, whereas odd numbers are sent after a big enough delay // to violate the deadline. -target C { +target CCpp { timeout: 6 sec } preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include + #include "platform.h" + #ifdef __cplusplus + } + #endif =} reactor Source(period: time(3 sec)) { diff --git a/test/C/src/DeadlineHandledAbove.lf b/test/C/src/DeadlineHandledAbove.lf index 5557469462..6d2f1e2157 100644 --- a/test/C/src/DeadlineHandledAbove.lf +++ b/test/C/src/DeadlineHandledAbove.lf @@ -3,7 +3,14 @@ target C preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include + #include "platform.h" + #ifdef __cplusplus + } + #endif =} reactor Deadline(threshold: time(100 msec)) { diff --git a/test/C/src/DelayString.lf b/test/C/src/DelayString.lf index c30f19f321..a6cc66a16e 100644 --- a/test/C/src/DelayString.lf +++ b/test/C/src/DelayString.lf @@ -3,7 +3,14 @@ target C preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include + #include + #ifdef __cplusplus + } + #endif =} reactor DelayString2(delay: time(100 msec)) { diff --git a/test/C/src/ScheduleValue.lf b/test/C/src/ScheduleValue.lf index 985380cbc4..506e4cea18 100644 --- a/test/C/src/ScheduleValue.lf +++ b/test/C/src/ScheduleValue.lf @@ -4,7 +4,15 @@ target C { } preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include + #include + #include + #ifdef __cplusplus + } + #endif =} main reactor ScheduleValue { diff --git a/test/C/src/SimpleDeadline.lf b/test/C/src/SimpleDeadline.lf index a890ad124f..d20cb9b16b 100644 --- a/test/C/src/SimpleDeadline.lf +++ b/test/C/src/SimpleDeadline.lf @@ -4,7 +4,14 @@ target C preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include + #include "platform.h" + #ifdef __cplusplus + } + #endif =} reactor Deadline(threshold: time(100 msec)) { diff --git a/test/C/src/TestForPreviousOutput.lf b/test/C/src/TestForPreviousOutput.lf index 6a5757d02c..d1f27e2bd9 100644 --- a/test/C/src/TestForPreviousOutput.lf +++ b/test/C/src/TestForPreviousOutput.lf @@ -3,7 +3,14 @@ target C preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include + #include + #ifdef __cplusplus + } + #endif =} reactor Source { From d491f5ed90a6f10a0b1b4f488c1df6593d1e7f7d Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 25 Mar 2023 08:55:53 -0700 Subject: [PATCH 66/92] Address another round of test failures. These are all related to the namespace pruning. --- test/C/src/federated/DistributedMultiportToken.lf | 10 ++++++++++ test/C/src/federated/DistributedNetworkOrder.lf | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/test/C/src/federated/DistributedMultiportToken.lf b/test/C/src/federated/DistributedMultiportToken.lf index 065f480e11..0e9285eacf 100644 --- a/test/C/src/federated/DistributedMultiportToken.lf +++ b/test/C/src/federated/DistributedMultiportToken.lf @@ -5,6 +5,16 @@ target C { coordination: centralized } +preamble {= + #ifdef __cplusplus + extern "C" { + #endif + #include + #ifdef __cplusplus + } + #endif +=} + reactor Source { output[4] out: char* timer t(0, 200 msec) diff --git a/test/C/src/federated/DistributedNetworkOrder.lf b/test/C/src/federated/DistributedNetworkOrder.lf index a41b7853a7..10305f983f 100644 --- a/test/C/src/federated/DistributedNetworkOrder.lf +++ b/test/C/src/federated/DistributedNetworkOrder.lf @@ -8,13 +8,20 @@ * * @author Soroush Bateni */ -target C { +target CCpp { timeout: 1 sec, build-type: RelWithDebInfo // Release with debug info } preamble {= + #ifdef __cplusplus + extern "C" { + #endif #include + #include "federate.h" + #ifdef __cplusplus + } + #endif =} reactor Sender { From 2dc2fd04f81bdd416a9d4b0996fbd9d3356040a2 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 25 Mar 2023 12:57:52 -0700 Subject: [PATCH 67/92] Address another round of test failures. --- org.lflang/src/lib/c/reactor-c | 2 +- test/C/c/sendreceive.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index 220da23b8a..a17d591213 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit 220da23b8ae7c7436a9f6900a319b6e246ae7fdd +Subproject commit a17d591213bb4899b33da9d3369702ed8ddc4d04 diff --git a/test/C/c/sendreceive.c b/test/C/c/sendreceive.c index 5f4c19f896..95a08176e7 100644 --- a/test/C/c/sendreceive.c +++ b/test/C/c/sendreceive.c @@ -1,3 +1,5 @@ +#include + #include "../include/IntPrint/Print.h" #include "../include/IntPrint/Check.h" #include "../include/api/set.h" From 02a56b47baf732ba2e6c648420d6f04852ef6e18 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 25 Mar 2023 14:17:04 -0700 Subject: [PATCH 68/92] Try again to pass on Windows. --- org.lflang/src/lib/c/reactor-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index a17d591213..c0a67e9e74 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit a17d591213bb4899b33da9d3369702ed8ddc4d04 +Subproject commit c0a67e9e74b968c1f3fe408659ef64ff033973bb From f25358dd46bc2e33483532ea1b377996458e87f8 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 25 Mar 2023 17:46:44 -0700 Subject: [PATCH 69/92] Fix mistakes in previous commits. --- org.lflang/src/lib/c/reactor-c | 2 +- test/C/src/Deadline.lf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index c0a67e9e74..efe4047679 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit c0a67e9e74b968c1f3fe408659ef64ff033973bb +Subproject commit efe40476795afc9ba40824336c8a3f9e58964f94 diff --git a/test/C/src/Deadline.lf b/test/C/src/Deadline.lf index 118e1db7b0..5936e89854 100644 --- a/test/C/src/Deadline.lf +++ b/test/C/src/Deadline.lf @@ -1,7 +1,7 @@ // This example illustrates local deadline handling. Even numbers are sent by // the Source immediately, whereas odd numbers are sent after a big enough delay // to violate the deadline. -target CCpp { +target C { timeout: 6 sec } From e6ced4e35b9afd7b108cb82e686dd252b8a76a21 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sat, 25 Mar 2023 19:15:35 -0700 Subject: [PATCH 70/92] Try again to pass on Windows. --- org.lflang/src/lib/c/reactor-c | 2 +- org.lflang/src/lib/py/reactor-c-py | 2 +- test/C/src/Deadline.lf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index efe4047679..b57ac873ba 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit efe40476795afc9ba40824336c8a3f9e58964f94 +Subproject commit b57ac873baf69bd075c0ecf58330ce815023303b diff --git a/org.lflang/src/lib/py/reactor-c-py b/org.lflang/src/lib/py/reactor-c-py index 14146b2f7b..5bdd8b836c 160000 --- a/org.lflang/src/lib/py/reactor-c-py +++ b/org.lflang/src/lib/py/reactor-c-py @@ -1 +1 @@ -Subproject commit 14146b2f7be6db8261b6a45724e18e0693f1f822 +Subproject commit 5bdd8b836c984457d8f4a830fa340f2f1d22cfa6 diff --git a/test/C/src/Deadline.lf b/test/C/src/Deadline.lf index 5936e89854..d5efe476af 100644 --- a/test/C/src/Deadline.lf +++ b/test/C/src/Deadline.lf @@ -25,7 +25,7 @@ reactor Source(period: time(3 sec)) { if (2 * (self->count / 2) != self->count) { // The count variable is odd. // Take time to cause a deadline violation. - lf_nanosleep(MSEC(1500)); + lf_sleep(MSEC(1500)); } printf("Source sends: %d.\n", self->count); lf_set(y, self->count); From 3ea395273a80d633eb27ad7f0cec4775481404f7 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sun, 26 Mar 2023 11:38:08 -0700 Subject: [PATCH 71/92] Revert more accidental C -> CCpp changes. --- test/C/src/concurrent/AsyncCallback.lf | 2 +- test/C/src/federated/DistributedNetworkOrder.lf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/C/src/concurrent/AsyncCallback.lf b/test/C/src/concurrent/AsyncCallback.lf index 6835c32ba9..4bda6c4b62 100644 --- a/test/C/src/concurrent/AsyncCallback.lf +++ b/test/C/src/concurrent/AsyncCallback.lf @@ -7,7 +7,7 @@ * Note: This test uses the LF platform support to enable it to run on multiple * platforms. */ -target CCpp { +target C { tracing: true, timeout: 2 sec, keepalive: true diff --git a/test/C/src/federated/DistributedNetworkOrder.lf b/test/C/src/federated/DistributedNetworkOrder.lf index 10305f983f..987078d414 100644 --- a/test/C/src/federated/DistributedNetworkOrder.lf +++ b/test/C/src/federated/DistributedNetworkOrder.lf @@ -8,7 +8,7 @@ * * @author Soroush Bateni */ -target CCpp { +target C { timeout: 1 sec, build-type: RelWithDebInfo // Release with debug info } From d82edb397c45a4f397f768e034b01de62b506587 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sun, 26 Mar 2023 20:25:58 -0700 Subject: [PATCH 72/92] Handle a hierarchical reference. --- org.lflang/src/org/lflang/ASTUtils.java | 6 ++ .../org/lflang/generator/c/CGenerator.java | 8 +-- .../generator/c/CReactionGenerator.java | 5 +- .../c/CReactorHeaderFileGenerator.java | 71 ++++++++++++++++--- test/C/c/count_hierarchy.c | 15 ++++ test/C/c/count_hierarchy.cmake | 1 + test/C/src/no_inlining/CountHierarchy.lf | 28 ++++++++ 7 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 test/C/c/count_hierarchy.c create mode 100644 test/C/c/count_hierarchy.cmake create mode 100644 test/C/src/no_inlining/CountHierarchy.lf diff --git a/org.lflang/src/org/lflang/ASTUtils.java b/org.lflang/src/org/lflang/ASTUtils.java index 16f3182056..a54406c59c 100644 --- a/org.lflang/src/org/lflang/ASTUtils.java +++ b/org.lflang/src/org/lflang/ASTUtils.java @@ -379,6 +379,12 @@ public static List allInstantiations(Reactor definition) { return ASTUtils.collectElements(definition, featurePackage.getReactor_Instantiations()); } + public static Stream allNestedClasses(Reactor definition) { + return new HashSet<>(ASTUtils.allInstantiations(definition)).stream() + .map(Instantiation::getReactorClass) + .map(ASTUtils::toDefinition); + } + /** * Given a reactor class, return a list of all its methods, * which includes methods of base classes that it extends. diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 8825e75ac9..662789e895 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -1068,13 +1068,7 @@ protected void generateReactorClassHeaders(Reactor reactor, String headerName, C } src.pr("#include \"include/" + CReactorHeaderFileGenerator.outputPath(fileConfig, reactor) + "\""); src.pr("#include \"" + headerName + "\""); - Stream.concat( - reactor.getInstantiations().stream(), - reactor.getModes().stream().flatMap(it -> it.getInstantiations().stream()) - ) - .collect(Collectors.toSet()).stream() - .map(Instantiation::getReactorClass) - .map(ASTUtils::toDefinition).map(CUtil::getName) + ASTUtils.allNestedClasses(reactor).map(CUtil::getName) .map(name -> "#include \"" + name + ".h\"") .forEach(header::pr); } diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index 051540bbf6..6677baa512 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -1085,7 +1085,10 @@ init, getCode(types, reaction, r) private static Code getCode(CTypes types, Reaction r, ReactorDecl container) { if (r.getCode() != null) return r.getCode(); Code ret = LfFactory.eINSTANCE.createCode(); - ret.setBody(r.getName() + "( " + CReactorHeaderFileGenerator.reactionArguments(types, r, ASTUtils.toDefinition(container)) + " );"); + var reactor = ASTUtils.toDefinition(container); + ret.setBody( + CReactorHeaderFileGenerator.nonInlineInitialization(types, r, reactor) + "\n" + + r.getName() + "( " + CReactorHeaderFileGenerator.reactionArguments(types, r, reactor) + " );"); return ret; } diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index b947f3ca67..6b390a286e 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -9,7 +9,10 @@ import org.eclipse.emf.ecore.EObject; +import org.lflang.ASTUtils; import org.lflang.generator.CodeBuilder; +import org.lflang.lf.Instantiation; +import org.lflang.lf.LfFactory; import org.lflang.lf.Parameter; import org.lflang.lf.Port; import org.lflang.lf.Reaction; @@ -19,6 +22,7 @@ import org.lflang.lf.TypedVariable; import org.lflang.lf.VarRef; import org.lflang.lf.Variable; +import org.lflang.lf.WidthSpec; import org.lflang.util.FileUtil; public class CReactorHeaderFileGenerator { @@ -41,7 +45,7 @@ private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxili CodeBuilder builder = new CodeBuilder(); appendIncludeGuard(builder, r); builder.pr(topLevelPreamble); - appendPoundIncludes(builder); + appendPoundIncludes(builder, r); appendSelfStruct(builder, types, r); generator.generate(builder, r, true); for (Reaction reaction : r.getReactions()) { @@ -56,7 +60,7 @@ private static void appendIncludeGuard(CodeBuilder builder, Reactor r) { builder.pr("#ifndef " + macro); builder.pr("#define " + macro); } - private static void appendPoundIncludes(CodeBuilder builder) { + private static void appendPoundIncludes(CodeBuilder builder, Reactor r) { builder.pr(""" #ifdef __cplusplus extern "C" { @@ -68,6 +72,10 @@ private static void appendPoundIncludes(CodeBuilder builder) { } #endif """); + ASTUtils.allNestedClasses(r) + .map(Reactor::getName) + .map(it -> it + ".h") + .forEach(it -> builder.pr(String.format("#include \"%s\"", it))); } private static String userFacingSelfType(Reactor r) { @@ -91,14 +99,37 @@ private static void appendSignature(CodeBuilder builder, CTypes types, Reaction } private static String reactionParameters(CTypes types, Reaction r, Reactor reactor) { - return Stream.concat(Stream.of(userFacingSelfType(reactor) + "* self"), ioTypedVariableStream(r) - .map((tv) -> reactor.getName().toLowerCase() + "_" + tv.getName() + "_t* " + tv.getName())) + return Stream.concat(Stream.of(userFacingSelfType(reactor) + "* self"), ioTypedVariableStream(r, reactor) + .map(it -> it.getType(true) + "* " + it.getName())) .collect(Collectors.joining(", ")); } + public static String nonInlineInitialization(CTypes types, Reaction r, Reactor reactor) { + var mainDef = LfFactory.eINSTANCE.createInstantiation(); + mainDef.setName(reactor.getName()); + mainDef.setReactorClass(ASTUtils.findMainReactor(reactor.eResource())); + return ioTypedVariableStream(r, reactor) + .map(it -> it.getWidth() == null ? + String.format("%s* %s = %s;", it.getType(false), it.getAlias(), it.getRvalue()) + : String.format(""" + %s* %s[%s]; + for (int i = 0; i < %s; i++) { + %s[i] = self->_lf_%s[i].%s; + } + """, + it.getType(false), + it.getAlias(), + CReactionGenerator.maxContainedReactorBankWidth(it.r.getInstantiations().get(0), null, 0, mainDef), + "self->_lf_"+it.r.getName()+"_width", + it.getAlias(), + it.r.getName(), + it.getName())) + .collect(Collectors.joining("\n")); + } + public static String reactionArguments(CTypes types, Reaction r, Reactor reactor) { - return Stream.concat(Stream.of(getApiSelfStruct(reactor)), ioTypedVariableStream(r) - .map(it -> String.format("((%s*) %s)", CGenerator.variableStructType(it, reactor, true), it.getName()))) + return Stream.concat(Stream.of(getApiSelfStruct(reactor)), ioTypedVariableStream(r, reactor) + .map(it -> String.format("((%s*) %s)", it.getType(true), it.getAlias()))) .collect(Collectors.joining(", ")); } @@ -106,11 +137,35 @@ private static String getApiSelfStruct(Reactor reactor) { return "(" + userFacingSelfType(reactor) + "*) (((char*) self) + sizeof(self_base_t))"; } - private static Stream ioTypedVariableStream(Reaction r) { - return varRefStream(r).map(it -> it.getVariable() instanceof TypedVariable tv ? tv : null) + private static Stream ioTypedVariableStream(Reaction r, Reactor defaultReactorClass) { + return varRefStream(r) + .map(it -> it.getVariable() instanceof TypedVariable tv ? + new PortVariable( + tv, + ASTUtils.toDefinition(it.getContainer() == null ? defaultReactorClass : it.getContainer().getReactorClass()), + it.getContainer()) + : null) .filter(Objects::nonNull); } + private record PortVariable(TypedVariable tv, Reactor r, Instantiation container) { + String getType(boolean userFacing) { + return CGenerator.variableStructType(tv, r, userFacing); + } + String getName() { + return tv.getName(); + } + String getAlias() { + return getName(); + } + String getWidth() { + return container.getWidthSpec() == null ? null : "self->_lf_"+r.getName()+"_width"; + } + String getRvalue() { + return container == null ? getName() : container.getName() + "." + getName(); + } + } + private static Stream inputVarRefStream(Reaction reaction) { return varRefStream(Stream.concat(reaction.getTriggers().stream(), reaction.getSources().stream())); } diff --git a/test/C/c/count_hierarchy.c b/test/C/c/count_hierarchy.c new file mode 100644 index 0000000000..999159aab8 --- /dev/null +++ b/test/C/c/count_hierarchy.c @@ -0,0 +1,15 @@ +#include +#include "../include/CountHierarchy/CountHierarchy.h" + +void increment(counthierarchy_self_t* self, timer_out_t* out) { + printf("in increment, count=%d\n", self->count); + self->count++; +} + +void check_done(counthierarchy_self_t* self, timer_out_t* out) { + printf("in done, count=%d\n", self->count); + if (self->count > 10) { + printf("%s", "requesting stop\n"); + lf_request_stop(); + } +} diff --git a/test/C/c/count_hierarchy.cmake b/test/C/c/count_hierarchy.cmake new file mode 100644 index 0000000000..955c07270a --- /dev/null +++ b/test/C/c/count_hierarchy.cmake @@ -0,0 +1 @@ +target_sources(${LF_MAIN_TARGET} PRIVATE c/count_hierarchy.c) diff --git a/test/C/src/no_inlining/CountHierarchy.lf b/test/C/src/no_inlining/CountHierarchy.lf new file mode 100644 index 0000000000..83054acfbb --- /dev/null +++ b/test/C/src/no_inlining/CountHierarchy.lf @@ -0,0 +1,28 @@ +target C { + cmake-include: ["../../c/count_hierarchy.cmake"], + files: ["../../c"] +} + +preamble {= + #include +=} + +reactor Timer(m: time(0), n: time(0)) { + output out: int + timer t(m, n) + reaction(t) -> out {= + lf_set(out, 0); + =} +} + +main reactor { + t = new Timer(m(0), n(1 msec)) + + state count: int + + reaction(t.out) named increment + + reaction(t.out) named check_done + + reaction(shutdown) {= printf("%s", "shutting down\n"); =} +} From 48540b39b993e3fc8fd3da6e5b922021781bc385 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sun, 26 Mar 2023 20:48:28 -0700 Subject: [PATCH 73/92] Minor bugfixes in previous commit. --- .../generator/c/CReactorHeaderFileGenerator.java | 12 ++++++------ test/C/src/no_inlining/CountHierarchy.lf | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 6b390a286e..e5532749b5 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -10,6 +10,7 @@ import org.eclipse.emf.ecore.EObject; import org.lflang.ASTUtils; +import org.lflang.FileConfig; import org.lflang.generator.CodeBuilder; import org.lflang.lf.Instantiation; import org.lflang.lf.LfFactory; @@ -38,14 +39,14 @@ public static Path outputPath(CFileConfig fileConfig, Reactor r) { } public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator, Function topLevelPreamble) throws IOException { - String contents = generateHeaderFile(types, r, generator, topLevelPreamble.apply(r)); + String contents = generateHeaderFile(types, fileConfig, r, generator, topLevelPreamble.apply(r)); FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(outputPath(fileConfig, r))); } - private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator, String topLevelPreamble) { + private static String generateHeaderFile(CTypes types, CFileConfig fileConfig, Reactor r, GenerateAuxiliaryStructs generator, String topLevelPreamble) { CodeBuilder builder = new CodeBuilder(); appendIncludeGuard(builder, r); builder.pr(topLevelPreamble); - appendPoundIncludes(builder, r); + appendPoundIncludes(builder, r, fileConfig); appendSelfStruct(builder, types, r); generator.generate(builder, r, true); for (Reaction reaction : r.getReactions()) { @@ -60,7 +61,7 @@ private static void appendIncludeGuard(CodeBuilder builder, Reactor r) { builder.pr("#ifndef " + macro); builder.pr("#define " + macro); } - private static void appendPoundIncludes(CodeBuilder builder, Reactor r) { + private static void appendPoundIncludes(CodeBuilder builder, Reactor r, CFileConfig fileConfig) { builder.pr(""" #ifdef __cplusplus extern "C" { @@ -73,8 +74,7 @@ private static void appendPoundIncludes(CodeBuilder builder, Reactor r) { #endif """); ASTUtils.allNestedClasses(r) - .map(Reactor::getName) - .map(it -> it + ".h") + .map(it -> outputPath(fileConfig, r).getParent().relativize(outputPath(fileConfig, it))) .forEach(it -> builder.pr(String.format("#include \"%s\"", it))); } diff --git a/test/C/src/no_inlining/CountHierarchy.lf b/test/C/src/no_inlining/CountHierarchy.lf index 83054acfbb..68c925d5cd 100644 --- a/test/C/src/no_inlining/CountHierarchy.lf +++ b/test/C/src/no_inlining/CountHierarchy.lf @@ -10,9 +10,8 @@ preamble {= reactor Timer(m: time(0), n: time(0)) { output out: int timer t(m, n) - reaction(t) -> out {= - lf_set(out, 0); - =} + + reaction(t) -> out {= lf_set(out, 0); =} } main reactor { From f168342c6632a457dddc896f13d576113b71f623 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Sun, 26 Mar 2023 21:41:12 -0700 Subject: [PATCH 74/92] Pass smoke test for reacting to contained bank. --- .../c/CReactorHeaderFileGenerator.java | 25 +++++++++++-------- test/C/c/bank_to_reaction_no_inlining.c | 11 ++++++++ test/C/c/bank_to_reaction_no_inlining.cmake | 1 + .../no_inlining/BankToReactionNoInlining.lf | 16 ++++++++++++ 4 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 test/C/c/bank_to_reaction_no_inlining.c create mode 100644 test/C/c/bank_to_reaction_no_inlining.cmake create mode 100644 test/C/src/no_inlining/BankToReactionNoInlining.lf diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index e5532749b5..c906b82ed1 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -68,7 +68,7 @@ private static void appendPoundIncludes(CodeBuilder builder, Reactor r, CFileCon #endif #include "../include/api/api.h" #include "../include/api/set.h" - #include "../include/core/reactor.h" + #include "../include/core/reactor.h" #ifdef __cplusplus } #endif @@ -100,7 +100,7 @@ private static void appendSignature(CodeBuilder builder, CTypes types, Reaction private static String reactionParameters(CTypes types, Reaction r, Reactor reactor) { return Stream.concat(Stream.of(userFacingSelfType(reactor) + "* self"), ioTypedVariableStream(r, reactor) - .map(it -> it.getType(true) + "* " + it.getName())) + .map(it -> it.getType(true) + " " + it.getName())) .collect(Collectors.joining(", ")); } @@ -110,26 +110,30 @@ public static String nonInlineInitialization(CTypes types, Reaction r, Reactor r mainDef.setReactorClass(ASTUtils.findMainReactor(reactor.eResource())); return ioTypedVariableStream(r, reactor) .map(it -> it.getWidth() == null ? - String.format("%s* %s = %s;", it.getType(false), it.getAlias(), it.getRvalue()) + String.format("%s %s = %s;", it.getType(false), it.getAlias(), it.getRvalue()) : String.format(""" - %s* %s[%s]; + %s %s[%s]; for (int i = 0; i < %s; i++) { %s[i] = self->_lf_%s[i].%s; } """, - it.getType(false), + it.getType(false).replaceFirst("\\*", ""), it.getAlias(), - CReactionGenerator.maxContainedReactorBankWidth(it.r.getInstantiations().get(0), null, 0, mainDef), - "self->_lf_"+it.r.getName()+"_width", + CReactionGenerator.maxContainedReactorBankWidth( + reactor.getInstantiations().stream() + .filter(instantiation -> ASTUtils.toDefinition(instantiation.getReactorClass()).equals(it.r)) + .findAny().orElseThrow(), + null, 0, mainDef), + "self->_lf_"+it.container.getName()+"_width", it.getAlias(), - it.r.getName(), + it.container.getName(), it.getName())) .collect(Collectors.joining("\n")); } public static String reactionArguments(CTypes types, Reaction r, Reactor reactor) { return Stream.concat(Stream.of(getApiSelfStruct(reactor)), ioTypedVariableStream(r, reactor) - .map(it -> String.format("((%s*) %s)", it.getType(true), it.getAlias()))) + .map(it -> String.format("((%s) %s)", it.getType(true), it.getAlias()))) .collect(Collectors.joining(", ")); } @@ -150,7 +154,8 @@ private static Stream ioTypedVariableStream(Reaction r, Reactor de private record PortVariable(TypedVariable tv, Reactor r, Instantiation container) { String getType(boolean userFacing) { - return CGenerator.variableStructType(tv, r, userFacing); + return CGenerator.variableStructType(tv, r, userFacing) + + "*" + (getWidth() != null ? "*" : ""); } String getName() { return tv.getName(); diff --git a/test/C/c/bank_to_reaction_no_inlining.c b/test/C/c/bank_to_reaction_no_inlining.c new file mode 100644 index 0000000000..9cf5b220b9 --- /dev/null +++ b/test/C/c/bank_to_reaction_no_inlining.c @@ -0,0 +1,11 @@ +#include "../include/BankToReactionNoInlining/BankToReactionNoInlining.h" + +void check(banktoreactionnoinlining_self_t* self, count_out_t** out) { + for (int i = 0; i < 2; i++) { + lf_print("Received %d.", out[i]->value); + if (self->count != out[i]->value) { + lf_print_error_and_exit("Expected %d but got %d.", self->count, out[i]->value); + } + } + self->count++; +} diff --git a/test/C/c/bank_to_reaction_no_inlining.cmake b/test/C/c/bank_to_reaction_no_inlining.cmake new file mode 100644 index 0000000000..a4f8d8dfa3 --- /dev/null +++ b/test/C/c/bank_to_reaction_no_inlining.cmake @@ -0,0 +1 @@ +target_sources(${LF_MAIN_TARGET} PRIVATE c/bank_to_reaction_no_inlining.c) diff --git a/test/C/src/no_inlining/BankToReactionNoInlining.lf b/test/C/src/no_inlining/BankToReactionNoInlining.lf new file mode 100644 index 0000000000..6ac95f093e --- /dev/null +++ b/test/C/src/no_inlining/BankToReactionNoInlining.lf @@ -0,0 +1,16 @@ +target C { + timeout: 5 sec, + fast: true, + cmake-include: ["../../c/bank_to_reaction_no_inlining.cmake"], + files: ["../../c"] +} + +import Count from "../lib/Count.lf" + +main reactor { + state count: int(1) + + s = new[2] Count() + + reaction(s.out) named check +} From 1647e59dc1eb962281c753ef21d229ab60f222ca Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 27 Mar 2023 11:27:05 -0700 Subject: [PATCH 75/92] Address failing modal models test. --- .../org/lflang/generator/c/CGenerator.java | 16 ++++++++++++++-- .../lflang/generator/c/CPortGenerator.java | 19 +++++++++++++++---- .../c/CReactorHeaderFileGenerator.java | 14 +++++++------- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 662789e895..c0894bc614 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -922,7 +922,18 @@ private void generateHeaders() throws IOException { false ); for (Reactor r : reactors) { - CReactorHeaderFileGenerator.doGenerate(types, r, fileConfig, this::generateAuxiliaryStructs, this::generateTopLevelPreambles); + CReactorHeaderFileGenerator.doGenerate( + types, r, fileConfig, + (builder, rr, userFacing) -> { + generateAuxiliaryStructs(builder, rr, userFacing); + if (userFacing) ASTUtils.allInstantiations(r).stream().map(Instantiation::getReactorClass).forEach(it -> { + ASTUtils.allPorts(ASTUtils.toDefinition(it)) + .forEach(p -> builder.pr(CPortGenerator.generateAuxiliaryStruct( + ASTUtils.toDefinition(it), p, getTarget(), errorReporter, types, new CodeBuilder(), true, it + ))); + }); + }, + this::generateTopLevelPreambles); } FileUtil.copyDirectory(fileConfig.getIncludePath(), fileConfig.getSrcGenPath().resolve("include"), false); } @@ -1154,7 +1165,8 @@ protected void generateAuxiliaryStructs(CodeBuilder builder, Reactor r, boolean errorReporter, types, federatedExtension, - userFacing + userFacing, + null )); } // The very first item on this struct needs to be diff --git a/org.lflang/src/org/lflang/generator/c/CPortGenerator.java b/org.lflang/src/org/lflang/generator/c/CPortGenerator.java index cf6ea06b64..1b22b41f9a 100644 --- a/org.lflang/src/org/lflang/generator/c/CPortGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CPortGenerator.java @@ -44,23 +44,28 @@ public static void generateDeclarations( * Generate the struct type definitions for the port of the * reactor * - * @param decl The reactor declaration + * @param r The reactor * @param port The port to generate the struct * @param target The target of the code generation (C, CCpp or Python) * @param errorReporter The error reporter * @param types The helper object for types related stuff * @param federatedExtension The code needed to support federated execution + * @param userFacing Whether this struct is to be presented in a user-facing header + * @param decl The reactorDecl if this struct is for the header of this reactor's container; + * null otherwise * @return The auxiliary struct for the port as a string */ public static String generateAuxiliaryStruct( - Reactor decl, + Reactor r, Port port, Target target, ErrorReporter errorReporter, CTypes types, CodeBuilder federatedExtension, - boolean userFacing + boolean userFacing, + ReactorDecl decl ) { + assert decl == null || userFacing; var code = new CodeBuilder(); code.pr("typedef struct {"); code.indent(); @@ -80,10 +85,16 @@ public static String generateAuxiliaryStruct( code.pr(valueDeclaration(port, target, errorReporter, types)); code.pr(federatedExtension.toString()); code.unindent(); - code.pr("} "+variableStructType(port, decl, userFacing)+";"); + var name = decl != null ? localPortName(decl, port.getName()) + : variableStructType(port, r, userFacing); + code.pr("} " + name + ";"); return code.toString(); } + public static String localPortName(ReactorDecl decl, String portName) { + return decl.getName().toLowerCase() + "_" + portName + "_t"; + } + /** * Allocate memory for the input port. * @param input The input port diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index c906b82ed1..0e2d14f4d5 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -73,9 +73,6 @@ private static void appendPoundIncludes(CodeBuilder builder, Reactor r, CFileCon } #endif """); - ASTUtils.allNestedClasses(r) - .map(it -> outputPath(fileConfig, r).getParent().relativize(outputPath(fileConfig, it))) - .forEach(it -> builder.pr(String.format("#include \"%s\"", it))); } private static String userFacingSelfType(Reactor r) { @@ -114,10 +111,10 @@ public static String nonInlineInitialization(CTypes types, Reaction r, Reactor r : String.format(""" %s %s[%s]; for (int i = 0; i < %s; i++) { - %s[i] = self->_lf_%s[i].%s; + %s[i] = (%s) self->_lf_%s[i].%s; } """, - it.getType(false).replaceFirst("\\*", ""), + it.getType(true).replaceFirst("\\*", ""), it.getAlias(), CReactionGenerator.maxContainedReactorBankWidth( reactor.getInstantiations().stream() @@ -126,6 +123,7 @@ public static String nonInlineInitialization(CTypes types, Reaction r, Reactor r null, 0, mainDef), "self->_lf_"+it.container.getName()+"_width", it.getAlias(), + it.getType(true).replaceFirst("\\*", ""), it.container.getName(), it.getName())) .collect(Collectors.joining("\n")); @@ -154,8 +152,10 @@ private static Stream ioTypedVariableStream(Reaction r, Reactor de private record PortVariable(TypedVariable tv, Reactor r, Instantiation container) { String getType(boolean userFacing) { - return CGenerator.variableStructType(tv, r, userFacing) - + "*" + (getWidth() != null ? "*" : ""); + var typeName = container == null ? + CGenerator.variableStructType(tv, r, userFacing) + : CPortGenerator.localPortName(container.getReactorClass(), getName()); + return typeName + "*" + (getWidth() != null ? "*" : ""); } String getName() { return tv.getName(); From 389392c8895c0eba016bdf6aaab4578da331d9a8 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 27 Mar 2023 13:20:38 -0700 Subject: [PATCH 76/92] Fix duplicate typedefs. --- .../src/org/lflang/generator/c/CGenerator.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index f1dd6fb732..9b58482d97 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -926,12 +926,14 @@ private void generateHeaders() throws IOException { types, r, fileConfig, (builder, rr, userFacing) -> { generateAuxiliaryStructs(builder, rr, userFacing); - if (userFacing) ASTUtils.allInstantiations(r).stream().map(Instantiation::getReactorClass).forEach(it -> { - ASTUtils.allPorts(ASTUtils.toDefinition(it)) - .forEach(p -> builder.pr(CPortGenerator.generateAuxiliaryStruct( - ASTUtils.toDefinition(it), p, getTarget(), errorReporter, types, new CodeBuilder(), true, it - ))); - }); + if (userFacing) { + ASTUtils.allInstantiations(r).stream().map(Instantiation::getReactorClass).collect(Collectors.toSet()).forEach(it -> { + ASTUtils.allPorts(ASTUtils.toDefinition(it)) + .forEach(p -> builder.pr(CPortGenerator.generateAuxiliaryStruct( + ASTUtils.toDefinition(it), p, getTarget(), errorReporter, types, new CodeBuilder(), true, it + ))); + }); + } }, this::generateTopLevelPreambles); } From c5f61906a23a84a6bd208aaffff143b5f480ec67 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 27 Mar 2023 14:04:53 -0700 Subject: [PATCH 77/92] Address failing TokenContainedPrint. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 11 +++++------ .../generator/c/CReactorHeaderFileGenerator.java | 2 +- .../org/lflang/generator/python/PythonGenerator.java | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 9b58482d97..c0343f5378 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -2009,15 +2009,14 @@ public String generateDirectives() { /** * Generate top-level preamble code. */ - protected String generateTopLevelPreambles(EObject reactor) { + protected String generateTopLevelPreambles(Reactor reactor) { CodeBuilder builder = new CodeBuilder(); - var mainModel = (Model) reactor.eContainer(); - var guard = "TOP_LEVEL_PREAMBLE_" + mainModel.hashCode() + "_H"; + var guard = "TOP_LEVEL_PREAMBLE_" + reactor.eContainer().hashCode() + "_H"; builder.pr("#ifndef " + guard); builder.pr("#define " + guard); - for (Preamble p : mainModel.getPreambles()) { - builder.pr(toText(p.getCode())); - } + Stream.concat(Stream.of(reactor), ASTUtils.allNestedClasses(reactor)) + .flatMap(it -> ((Model) it.eContainer()).getPreambles().stream()) + .forEach(it -> builder.pr(toText(it.getCode()))); for (String file : targetConfig.protoFiles) { var dotIndex = file.lastIndexOf("."); var rootFilename = file; diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 0e2d14f4d5..da780bbe7b 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -38,7 +38,7 @@ public static Path outputPath(CFileConfig fileConfig, Reactor r) { .resolve(r.getName() + ".h"); } - public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator, Function topLevelPreamble) throws IOException { + public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator, Function topLevelPreamble) throws IOException { String contents = generateHeaderFile(types, fileConfig, r, generator, topLevelPreamble.apply(r)); FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(outputPath(fileConfig, r))); } diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java index 56e40163af..020954be80 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.java +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.java @@ -288,7 +288,7 @@ public String generateDirectives() { * execution setup preamble specified in the target config. */ @Override - protected String generateTopLevelPreambles(EObject ignored) { + protected String generateTopLevelPreambles(Reactor ignored) { // user preambles Set models = new LinkedHashSet<>(); for (Reactor r : ASTUtils.convertToEmptyListIfNull(reactors)) { From 1ebb38f886cbe0099cb540235c75501a9a3c0a00 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 27 Mar 2023 14:05:49 -0700 Subject: [PATCH 78/92] Pass MultiportToReactionNoInlining test. --- .../c/CReactorHeaderFileGenerator.java | 11 ++++-- test/C/c/multiport_to_reaction_no_inlining.c | 14 +++++++ .../c/multiport_to_reaction_no_inlining.cmake | 1 + .../MultiportToReactionNoInlining.lf | 39 +++++++++++++++++++ 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 test/C/c/multiport_to_reaction_no_inlining.c create mode 100644 test/C/c/multiport_to_reaction_no_inlining.cmake create mode 100644 test/C/src/no_inlining/MultiportToReactionNoInlining.lf diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index da780bbe7b..164609639c 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -106,8 +106,8 @@ public static String nonInlineInitialization(CTypes types, Reaction r, Reactor r mainDef.setName(reactor.getName()); mainDef.setReactorClass(ASTUtils.findMainReactor(reactor.eResource())); return ioTypedVariableStream(r, reactor) - .map(it -> it.getWidth() == null ? - String.format("%s %s = %s;", it.getType(false), it.getAlias(), it.getRvalue()) + .map(it -> it.container == null ? "" : it.getWidth() == null ? + String.format("%s %s = (%s) %s;", it.getType(false), it.getAlias(), it.getType(false), it.getRvalue()) : String.format(""" %s %s[%s]; for (int i = 0; i < %s; i++) { @@ -155,7 +155,10 @@ String getType(boolean userFacing) { var typeName = container == null ? CGenerator.variableStructType(tv, r, userFacing) : CPortGenerator.localPortName(container.getReactorClass(), getName()); - return typeName + "*" + (getWidth() != null ? "*" : ""); + var isMultiport = ASTUtils.isMultiport(ASTUtils.allPorts(r).stream() + .filter(it -> it.getName().equals(tv.getName())) + .findAny().orElseThrow()); + return typeName + "*" + (getWidth() != null ? "*" : "") + (isMultiport ? "*" : ""); } String getName() { return tv.getName(); @@ -164,7 +167,7 @@ String getAlias() { return getName(); } String getWidth() { - return container.getWidthSpec() == null ? null : "self->_lf_"+r.getName()+"_width"; + return container == null || container.getWidthSpec() == null ? null : "self->_lf_"+r.getName()+"_width"; } String getRvalue() { return container == null ? getName() : container.getName() + "." + getName(); diff --git a/test/C/c/multiport_to_reaction_no_inlining.c b/test/C/c/multiport_to_reaction_no_inlining.c new file mode 100644 index 0000000000..5036771cbd --- /dev/null +++ b/test/C/c/multiport_to_reaction_no_inlining.c @@ -0,0 +1,14 @@ +#include "../include/MultiportToReactionNoInlining/MultiportToReactionNoInlining.h" + +void check(multiporttoreactionnoinlining_self_t* self, source_out_t** out) { + int sum = 0; + for (int i = 0; i < 4; i++) { + if (out[i]->is_present) sum += out[i]->value; + } + printf("Sum of received: %d.\n", sum); + if (sum != self->s) { + printf("ERROR: Expected %d.\n", self->s); + exit(1); + } + self->s += 16; +} diff --git a/test/C/c/multiport_to_reaction_no_inlining.cmake b/test/C/c/multiport_to_reaction_no_inlining.cmake new file mode 100644 index 0000000000..8f4226aff2 --- /dev/null +++ b/test/C/c/multiport_to_reaction_no_inlining.cmake @@ -0,0 +1 @@ +target_sources(${LF_MAIN_TARGET} PRIVATE c/multiport_to_reaction_no_inlining.c) diff --git a/test/C/src/no_inlining/MultiportToReactionNoInlining.lf b/test/C/src/no_inlining/MultiportToReactionNoInlining.lf new file mode 100644 index 0000000000..2ed1e14483 --- /dev/null +++ b/test/C/src/no_inlining/MultiportToReactionNoInlining.lf @@ -0,0 +1,39 @@ +// Check reaction to multiport output of a contained reactor. +target C { + timeout: 2 sec, + fast: true, + cmake-include: ["../../c/multiport_to_reaction_no_inlining.cmake"], + files: ["../../c"] +} + +preamble {= + #include +=} + +reactor Source(width: int = 1) { + timer t(0, 200 msec) + state s: int = 0 + output[width] out: int + + reaction(t) -> out {= + printf("Sending.\n"); + for(int i = 0; i < out_width; i++) { + lf_set(out[i], self->s++); + } + =} +} + +main reactor { + state s: int = 6 + b = new Source(width = 4) + + reaction(b.out) named check + + reaction(shutdown) {= + if (self->s <= 6) { + fprintf(stderr, "ERROR: Destination received no input!\n"); + exit(1); + } + printf("Success.\n"); + =} +} From c33786cee0d0e0b3ba11e1d0b069f12374e4aad0 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 27 Mar 2023 14:19:02 -0700 Subject: [PATCH 79/92] Address failing benchmark tests. Preambles were being duplicated. --- org.lflang/src/org/lflang/generator/c/CGenerator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index c0343f5378..877a303414 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -2016,6 +2016,7 @@ protected String generateTopLevelPreambles(Reactor reactor) { builder.pr("#define " + guard); Stream.concat(Stream.of(reactor), ASTUtils.allNestedClasses(reactor)) .flatMap(it -> ((Model) it.eContainer()).getPreambles().stream()) + .collect(Collectors.toSet()) .forEach(it -> builder.pr(toText(it.getCode()))); for (String file : targetConfig.protoFiles) { var dotIndex = file.lastIndexOf("."); From c8e4c2f2e2625e48fb3e62257ee05cf000c02b50 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 27 Mar 2023 14:19:37 -0700 Subject: [PATCH 80/92] Update modal models tests. --- test/C/src/modal_models/BanksCount3ModesComplex.lf | 4 ++-- test/C/src/modal_models/BanksCount3ModesSimple.lf | 4 ++-- test/C/src/modal_models/BanksModalStateReset.lf | 4 ++-- test/C/src/modal_models/ConvertCaseTest.lf | 4 ++-- test/C/src/modal_models/ModalActions.lf | 4 ++-- test/C/src/modal_models/ModalAfter.lf | 4 ++-- test/C/src/modal_models/ModalCycleBreaker.lf | 4 ++-- test/C/src/modal_models/ModalStartupShutdown.lf | 4 ++-- test/C/src/modal_models/ModalStateReset.lf | 4 ++-- test/C/src/modal_models/ModalStateResetAuto.lf | 4 ++-- test/C/src/modal_models/ModalTimers.lf | 4 ++-- test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf | 4 ++-- .../modal_models/MultipleOutputFeeder_ReactionConnections.lf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/test/C/src/modal_models/BanksCount3ModesComplex.lf b/test/C/src/modal_models/BanksCount3ModesComplex.lf index ad08cc7325..47805f1009 100644 --- a/test/C/src/modal_models/BanksCount3ModesComplex.lf +++ b/test/C/src/modal_models/BanksCount3ModesComplex.lf @@ -55,7 +55,7 @@ main reactor { test = new TraceTesting( // keep-format events_size = 16, trace_size = 429, - trace = ( + trace = { 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 250000000,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 250000000,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -69,7 +69,7 @@ main reactor { 250000000,1,2,1,2,1,2,1,2,0,2,0,2,0,2,0,2,1,2,1,2,1,2,1,2,0,0,0,0,0,0,0,0, 250000000,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,0,2,0,2,0,2,0,2,0,0,0,0,0,0,0,0, 250000000,1,1,1,1,1,1,1,1,0,3,0,3,0,3,0,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 - ), training = false) + }, training = false) counters.always, counters.mode1, counters.mode2, counters.never -> test.events diff --git a/test/C/src/modal_models/BanksCount3ModesSimple.lf b/test/C/src/modal_models/BanksCount3ModesSimple.lf index c03fb7e562..40c2ba50a8 100644 --- a/test/C/src/modal_models/BanksCount3ModesSimple.lf +++ b/test/C/src/modal_models/BanksCount3ModesSimple.lf @@ -13,7 +13,7 @@ main reactor { test = new TraceTesting( events_size = 3, trace_size = 63, - trace = ( // keep-format + trace = { // keep-format 0,1,1,1,1,1,1, 250000000,1,2,1,2,1,2, 250000000,1,3,1,3,1,3, @@ -23,7 +23,7 @@ main reactor { 250000000,1,1,1,1,1,1, 250000000,1,2,1,2,1,2, 250000000,1,3,1,3,1,3 - ), + }, training = false ) diff --git a/test/C/src/modal_models/BanksModalStateReset.lf b/test/C/src/modal_models/BanksModalStateReset.lf index 1dde9c5b97..8e075715c8 100644 --- a/test/C/src/modal_models/BanksModalStateReset.lf +++ b/test/C/src/modal_models/BanksModalStateReset.lf @@ -16,7 +16,7 @@ main reactor { reset1 = new[2] ResetReaction() reset2 = new[2] AutoReset() - test = new TraceTesting(events_size = 16, trace_size = 627, trace = ( // keep-format + test = new TraceTesting(events_size = 16, trace_size = 627, trace = { // keep-format 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, 250000000,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0, 250000000,0,0,0,0,0,0,0,0,1,2,1,2,0,0,0,0, 0,0,0,0,0,0,0,0,1,2,1,2,0,0,0,0, @@ -36,7 +36,7 @@ main reactor { 250000000,0,1,0,1,0,2,0,2,0,8,0,8,1,0,1,0, 0,1,0,1,0,2,0,2,0,8,0,8,1,0,1,0, 250000000,0,1,0,1,0,2,0,2,0,8,0,8,1,1,1,1, 0,1,0,1,0,2,0,2,0,8,0,8,1,1,1,1, 250000000,1,1,1,1,1,3,1,3,0,8,0,8,1,2,1,2, 1,1,1,1,1,3,1,3,0,8,0,8,1,2,1,2 - ), training = false) + }, training = false) reset1.mode_switch, reset1.count0, diff --git a/test/C/src/modal_models/ConvertCaseTest.lf b/test/C/src/modal_models/ConvertCaseTest.lf index fe4d8e7fb5..ca6323b148 100644 --- a/test/C/src/modal_models/ConvertCaseTest.lf +++ b/test/C/src/modal_models/ConvertCaseTest.lf @@ -118,7 +118,7 @@ main reactor { test = new TraceTesting( events_size = 2, trace_size = 60, - trace = ( // keep-format + trace = { // keep-format 0,1,72,1,72, 250000000,1,69,1,69, 250000000,1,76,1,76, @@ -131,7 +131,7 @@ main reactor { 250000000,1,76,1,108, 250000000,1,68,1,100, 250000000,1,95,1,95 - ), + }, training = false ) diff --git a/test/C/src/modal_models/ModalActions.lf b/test/C/src/modal_models/ModalActions.lf index b395820e8e..d8bcfecbbf 100644 --- a/test/C/src/modal_models/ModalActions.lf +++ b/test/C/src/modal_models/ModalActions.lf @@ -72,7 +72,7 @@ main reactor { test = new TraceTesting( events_size = 5, trace_size = 165, - trace = ( // keep-format + trace = { // keep-format 0,0,0,1,1,0,0,0,0,0,0, 500000000,0,0,0,1,1,1,0,0,0,0, 250000000,0,0,1,1,0,1,0,0,0,0, @@ -88,7 +88,7 @@ main reactor { 500000000,0,1,0,1,0,1,0,1,1,1, 250000000,0,1,0,1,0,1,1,1,0,1, 250000000,1,1,0,1,0,1,0,1,0,1 - ), + }, training = false ) diff --git a/test/C/src/modal_models/ModalAfter.lf b/test/C/src/modal_models/ModalAfter.lf index 29eb2376ee..5535c8c1aa 100644 --- a/test/C/src/modal_models/ModalAfter.lf +++ b/test/C/src/modal_models/ModalAfter.lf @@ -77,7 +77,7 @@ main reactor { test = new TraceTesting( events_size = 5, trace_size = 165, - trace = ( // keep-format + trace = { // keep-format 0,0,0,1,1,0,0,0,0,0,0, 500000000,0,0,0,1,1,1,0,0,0,0, 250000000,0,0,1,1,0,1,0,0,0,0, @@ -93,7 +93,7 @@ main reactor { 500000000,0,1,0,1,0,1,0,1,1,1, 250000000,0,1,0,1,0,1,1,1,0,1, 250000000,1,1,0,1,0,1,0,1,0,1 - ), + }, training = false ) diff --git a/test/C/src/modal_models/ModalCycleBreaker.lf b/test/C/src/modal_models/ModalCycleBreaker.lf index 2fb0ccbfc9..1de6dc30f4 100644 --- a/test/C/src/modal_models/ModalCycleBreaker.lf +++ b/test/C/src/modal_models/ModalCycleBreaker.lf @@ -61,7 +61,7 @@ main reactor { test = new TraceTesting( events_size = 1, trace_size = 27, - trace = ( // keep-format + trace = { // keep-format 0,1,0, 100000000,1,1, 100000000,1,2, @@ -71,7 +71,7 @@ main reactor { 100000000,1,7, 100000000,1,8, 100000000,1,9 - ), + }, training = false ) diff --git a/test/C/src/modal_models/ModalStartupShutdown.lf b/test/C/src/modal_models/ModalStartupShutdown.lf index 96c3e74a2c..6ef8ce6336 100644 --- a/test/C/src/modal_models/ModalStartupShutdown.lf +++ b/test/C/src/modal_models/ModalStartupShutdown.lf @@ -117,7 +117,7 @@ main reactor { test = new TraceTesting( events_size = 11, trace_size = 253, - trace = ( // keep-format + trace = { // keep-format 0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 500000000,1,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,2,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -129,7 +129,7 @@ main reactor { 500000000,1,4,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,4,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0, 500000000,1,4,0,1,0,1,1,1,1,1,0,1,0,1,1,1,0,0,0,0,0,0 - ), + }, training = false ) diff --git a/test/C/src/modal_models/ModalStateReset.lf b/test/C/src/modal_models/ModalStateReset.lf index 7cd376b8d2..45261641c6 100644 --- a/test/C/src/modal_models/ModalStateReset.lf +++ b/test/C/src/modal_models/ModalStateReset.lf @@ -67,7 +67,7 @@ main reactor { test = new TraceTesting( events_size = 4, trace_size = 171, - trace = ( // keep-format + trace = { // keep-format 0,0,0,0,0,1,0,0,0, 250000000,0,0,0,0,1,1,0,0, 250000000,0,0,0,0,1,2,0,0, @@ -87,7 +87,7 @@ main reactor { 250000000,0,1,0,2,0,8,1,0, 250000000,0,1,0,2,0,8,1,1, 250000000,1,1,1,3,0,8,1,2 - ), + }, training = false ) diff --git a/test/C/src/modal_models/ModalStateResetAuto.lf b/test/C/src/modal_models/ModalStateResetAuto.lf index 2eaf5c0fcf..02215bca09 100644 --- a/test/C/src/modal_models/ModalStateResetAuto.lf +++ b/test/C/src/modal_models/ModalStateResetAuto.lf @@ -63,7 +63,7 @@ main reactor { test = new TraceTesting( events_size = 4, trace_size = 171, - trace = ( // keep-format + trace = { // keep-format 0,0,0,0,0,1,0,0,0, 250000000,0,0,0,0,1,1,0,0, 250000000,0,0,0,0,1,2,0,0, @@ -83,7 +83,7 @@ main reactor { 250000000,0,1,0,2,0,8,1,0, 250000000,0,1,0,2,0,8,1,1, 250000000,1,1,1,3,0,8,1,2 - ), + }, training = false ) diff --git a/test/C/src/modal_models/ModalTimers.lf b/test/C/src/modal_models/ModalTimers.lf index bd5370c72c..ac76940da9 100644 --- a/test/C/src/modal_models/ModalTimers.lf +++ b/test/C/src/modal_models/ModalTimers.lf @@ -53,7 +53,7 @@ main reactor { test = new TraceTesting( events_size = 3, trace_size = 77, - trace = ( // keep-format + trace = { // keep-format 0,0,0,1,1,0,0, 750000000,0,0,1,1,0,0, 250000000,1,1,0,1,0,0, @@ -65,7 +65,7 @@ main reactor { 0,0,1,0,1,1,1, 750000000,0,1,0,1,1,1, 250000000,1,1,0,1,0,1 - ), + }, training = false ) diff --git a/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf b/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf index d41c00788a..f5790444f5 100644 --- a/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf +++ b/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf @@ -48,7 +48,7 @@ main reactor { test = new TraceTesting( events_size = 1, trace_size = 51, - trace = ( // keep-format + trace = { // keep-format 0,1,0, 250000000,1,1, 250000000,1,2, @@ -66,7 +66,7 @@ main reactor { 100000000,1,3, 100000000,1,4, 100000000,1,5 - ), + }, training = false ) diff --git a/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf b/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf index ca4546b890..74a5e9541b 100644 --- a/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf +++ b/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf @@ -51,7 +51,7 @@ main reactor { test = new TraceTesting( events_size = 1, trace_size = 51, - trace = ( // keep-format + trace = { // keep-format 0,1,0, 250000000,1,1, 250000000,1,2, @@ -69,7 +69,7 @@ main reactor { 100000000,1,30, 100000000,1,40, 100000000,1,50 - ), + }, training = false ) From 7627c4e85a2ae5636d6cc32ac996e7c4e2528990 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 27 Mar 2023 14:29:17 -0700 Subject: [PATCH 81/92] Pass BankMultiportToReactionNoInlining.lf. --- .../bank_multiport_to_reaction_no_inlining.c | 16 ++++++++++ ...nk_multiport_to_reaction_no_inlining.cmake | 1 + .../BankMultiportToReactionNoInlining.lf | 30 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 test/C/c/bank_multiport_to_reaction_no_inlining.c create mode 100644 test/C/c/bank_multiport_to_reaction_no_inlining.cmake create mode 100644 test/C/src/no_inlining/BankMultiportToReactionNoInlining.lf diff --git a/test/C/c/bank_multiport_to_reaction_no_inlining.c b/test/C/c/bank_multiport_to_reaction_no_inlining.c new file mode 100644 index 0000000000..ae54c84c2d --- /dev/null +++ b/test/C/c/bank_multiport_to_reaction_no_inlining.c @@ -0,0 +1,16 @@ +#include "../include/BankMultiportToReactionNoInlining/BankMultiportToReactionNoInlining.h" + +void check(bankmultiporttoreactionnoinlining_self_t* self, doublecount_out_t*** out) { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + if (out[i][j]->is_present) { + lf_print("Received %d.", out[i][j]->value); + if (self->count != out[i][j]->value) { + lf_print_error_and_exit("Expected %d.", self->count); + } + self->received = true; + } + } + } + self->count++; +} diff --git a/test/C/c/bank_multiport_to_reaction_no_inlining.cmake b/test/C/c/bank_multiport_to_reaction_no_inlining.cmake new file mode 100644 index 0000000000..c433f89d7e --- /dev/null +++ b/test/C/c/bank_multiport_to_reaction_no_inlining.cmake @@ -0,0 +1 @@ +target_sources(${LF_MAIN_TARGET} PRIVATE c/bank_multiport_to_reaction_no_inlining.c) diff --git a/test/C/src/no_inlining/BankMultiportToReactionNoInlining.lf b/test/C/src/no_inlining/BankMultiportToReactionNoInlining.lf new file mode 100644 index 0000000000..e69e0af0b4 --- /dev/null +++ b/test/C/src/no_inlining/BankMultiportToReactionNoInlining.lf @@ -0,0 +1,30 @@ +target C { + timeout: 5 sec, + fast: true, + cmake-include: ["../../c/bank_multiport_to_reaction_no_inlining.cmake"], + files: ["../../c"] +} + +import Count from "../lib/Count.lf" + +reactor DoubleCount { + output[2] out: int + c1 = new Count() + c2 = new Count() + c1.out, c2.out -> out +} + +main reactor { + state count: int = 1 + state received: bool = false + + s = new[2] DoubleCount() + + reaction(s.out) named check + + reaction(shutdown) {= + if (!self->received) { + lf_print_error_and_exit("No inputs present."); + } + =} +} From 83f09b792fe5abc52bbc966368292ede9c125223 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 30 Mar 2023 19:12:33 -0700 Subject: [PATCH 82/92] Add Javadoc; trivially refactor. --- org.lflang/src/org/lflang/ASTUtils.java | 2 + .../org/lflang/generator/c/CGenerator.java | 6 +- .../generator/c/CReactionGenerator.java | 5 +- .../c/CReactorHeaderFileGenerator.java | 86 +++++++++---------- 4 files changed, 45 insertions(+), 54 deletions(-) diff --git a/org.lflang/src/org/lflang/ASTUtils.java b/org.lflang/src/org/lflang/ASTUtils.java index 7ea6d12b7e..afda11bb46 100644 --- a/org.lflang/src/org/lflang/ASTUtils.java +++ b/org.lflang/src/org/lflang/ASTUtils.java @@ -372,6 +372,7 @@ public static List allInputs(Reactor definition) { return ASTUtils.collectElements(definition, featurePackage.getReactor_Inputs()); } + /** A list of all ports of {@code definition}, in an unspecified order. */ public static List allPorts(Reactor definition) { return Stream.concat(ASTUtils.allInputs(definition).stream(), ASTUtils.allOutputs(definition).stream()).toList(); } @@ -462,6 +463,7 @@ public static List allModes(Reactor definition) { return ASTUtils.collectElements(definition, featurePackage.getReactor_Modes()); } + /** A list of all reactors instantiated, transitively or intransitively, by {@code r}. */ public static List recursiveChildren(ReactorInstance r) { List ret = new ArrayList<>(); ret.add(r.reactorDefinition); diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.java b/org.lflang/src/org/lflang/generator/c/CGenerator.java index 877a303414..f598219ddd 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.java @@ -42,12 +42,10 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; -import java.util.Locale; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.xbase.lib.Exceptions; import org.eclipse.xtext.xbase.lib.IterableExtensions; @@ -85,7 +83,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import org.lflang.generator.TriggerInstance; import org.lflang.lf.Action; import org.lflang.lf.ActionOrigin; -import org.lflang.lf.Code; import org.lflang.lf.Input; import org.lflang.lf.Instantiation; import org.lflang.lf.Mode; @@ -914,6 +911,7 @@ private void generateReactorDefinitions() throws IOException { } } + /** Generate user-visible header files for all reactors instantiated. */ private void generateHeaders() throws IOException { FileUtil.deleteDirectory(fileConfig.getIncludePath()); FileUtil.copyDirectoryFromClassPath( @@ -1079,7 +1077,7 @@ protected void generateReactorClassHeaders(Reactor reactor, String headerName, C src.pr("}"); header.pr("}"); } - src.pr("#include \"include/" + CReactorHeaderFileGenerator.outputPath(fileConfig, reactor) + "\""); + src.pr("#include \"include/" + CReactorHeaderFileGenerator.outputPath(reactor) + "\""); src.pr("#include \"" + headerName + "\""); ASTUtils.allNestedClasses(reactor).map(CUtil::getName) .map(name -> "#include \"" + name + ".h\"") diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index 6677baa512..ae91aac32b 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -14,7 +14,6 @@ import org.lflang.ErrorReporter; import org.lflang.InferredType; import org.lflang.TargetConfig; -import org.lflang.TargetProperty.Platform; import org.lflang.federated.extensions.CExtensionUtils; import org.lflang.generator.CodeBuilder; import org.lflang.lf.Action; @@ -1087,8 +1086,8 @@ private static Code getCode(CTypes types, Reaction r, ReactorDecl container) { Code ret = LfFactory.eINSTANCE.createCode(); var reactor = ASTUtils.toDefinition(container); ret.setBody( - CReactorHeaderFileGenerator.nonInlineInitialization(types, r, reactor) + "\n" - + r.getName() + "( " + CReactorHeaderFileGenerator.reactionArguments(types, r, reactor) + " );"); + CReactorHeaderFileGenerator.nonInlineInitialization(r, reactor) + "\n" + + r.getName() + "( " + CReactorHeaderFileGenerator.reactionArguments(r, reactor) + " );"); return ret; } diff --git a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java index 164609639c..68b05f656a 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactorHeaderFileGenerator.java @@ -7,50 +7,48 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.eclipse.emf.ecore.EObject; - import org.lflang.ASTUtils; -import org.lflang.FileConfig; import org.lflang.generator.CodeBuilder; import org.lflang.lf.Instantiation; import org.lflang.lf.LfFactory; import org.lflang.lf.Parameter; -import org.lflang.lf.Port; import org.lflang.lf.Reaction; import org.lflang.lf.Reactor; import org.lflang.lf.StateVar; import org.lflang.lf.TriggerRef; import org.lflang.lf.TypedVariable; import org.lflang.lf.VarRef; -import org.lflang.lf.Variable; -import org.lflang.lf.WidthSpec; import org.lflang.util.FileUtil; +/** Generate user-visible header files. */ public class CReactorHeaderFileGenerator { + /** Functional interface for generating auxiliary structs such as port structs. */ public interface GenerateAuxiliaryStructs { void generate(CodeBuilder b, Reactor r, boolean userFacing); } - public static Path outputPath(CFileConfig fileConfig, Reactor r) { + /** Return the path to the user-visible header file that would be generated for {@code r}. */ + public static Path outputPath(Reactor r) { return Path.of(Path.of(r.eResource().getURI().toFileString()) .getFileName().toString().replaceFirst("[.][^.]+$", "")) .resolve(r.getName() + ".h"); } + /** Generate the user-visible header file for {@code r}. */ public static void doGenerate(CTypes types, Reactor r, CFileConfig fileConfig, GenerateAuxiliaryStructs generator, Function topLevelPreamble) throws IOException { - String contents = generateHeaderFile(types, fileConfig, r, generator, topLevelPreamble.apply(r)); - FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(outputPath(fileConfig, r))); + String contents = generateHeaderFile(types, r, generator, topLevelPreamble.apply(r)); + FileUtil.writeToFile(contents, fileConfig.getIncludePath().resolve(outputPath(r))); } - private static String generateHeaderFile(CTypes types, CFileConfig fileConfig, Reactor r, GenerateAuxiliaryStructs generator, String topLevelPreamble) { + private static String generateHeaderFile(CTypes types, Reactor r, GenerateAuxiliaryStructs generator, String topLevelPreamble) { CodeBuilder builder = new CodeBuilder(); appendIncludeGuard(builder, r); builder.pr(topLevelPreamble); - appendPoundIncludes(builder, r, fileConfig); + appendPoundIncludes(builder); appendSelfStruct(builder, types, r); generator.generate(builder, r, true); for (Reaction reaction : r.getReactions()) { - appendSignature(builder, types, reaction, r); + appendSignature(builder, reaction, r); } builder.pr("#endif"); return builder.getCode(); @@ -61,7 +59,7 @@ private static void appendIncludeGuard(CodeBuilder builder, Reactor r) { builder.pr("#ifndef " + macro); builder.pr("#define " + macro); } - private static void appendPoundIncludes(CodeBuilder builder, Reactor r, CFileConfig fileConfig) { + private static void appendPoundIncludes(CodeBuilder builder) { builder.pr(""" #ifdef __cplusplus extern "C" { @@ -75,6 +73,7 @@ private static void appendPoundIncludes(CodeBuilder builder, Reactor r, CFileCon """); } + /** The type name of the user-facing version of the self struct. */ private static String userFacingSelfType(Reactor r) { return r.getName().toLowerCase() + "_self_t"; } @@ -91,21 +90,23 @@ private static void appendSelfStruct(CodeBuilder builder, CTypes types, Reactor builder.pr("} " + userFacingSelfType(r) + ";"); } - private static void appendSignature(CodeBuilder builder, CTypes types, Reaction r, Reactor reactor) { - if (r.getName() != null) builder.pr("void " + r.getName() + "(" + reactionParameters(types, r, reactor) + ");"); + /** Generate the signature of the reaction function of {@code r}. */ + private static void appendSignature(CodeBuilder builder, Reaction r, Reactor reactor) { + if (r.getName() != null) builder.pr("void " + r.getName() + "(" + reactionParameters(r, reactor) + ");"); } - - private static String reactionParameters(CTypes types, Reaction r, Reactor reactor) { - return Stream.concat(Stream.of(userFacingSelfType(reactor) + "* self"), ioTypedVariableStream(r, reactor) + /** Return a string representation of the parameters of the reaction function of {@code r}. */ + private static String reactionParameters(Reaction r, Reactor reactor) { + return Stream.concat(Stream.of(userFacingSelfType(reactor) + "* self"), portVariableStream(r, reactor) .map(it -> it.getType(true) + " " + it.getName())) .collect(Collectors.joining(", ")); } - public static String nonInlineInitialization(CTypes types, Reaction r, Reactor reactor) { + /** Generate initialization code that is needed if {@code r} is not inlined. */ + public static String nonInlineInitialization(Reaction r, Reactor reactor) { var mainDef = LfFactory.eINSTANCE.createInstantiation(); mainDef.setName(reactor.getName()); mainDef.setReactorClass(ASTUtils.findMainReactor(reactor.eResource())); - return ioTypedVariableStream(r, reactor) + return portVariableStream(r, reactor) .map(it -> it.container == null ? "" : it.getWidth() == null ? String.format("%s %s = (%s) %s;", it.getType(false), it.getAlias(), it.getType(false), it.getRvalue()) : String.format(""" @@ -129,17 +130,20 @@ public static String nonInlineInitialization(CTypes types, Reaction r, Reactor r .collect(Collectors.joining("\n")); } - public static String reactionArguments(CTypes types, Reaction r, Reactor reactor) { - return Stream.concat(Stream.of(getApiSelfStruct(reactor)), ioTypedVariableStream(r, reactor) + /** Return a string representation of the arguments passed to the function for {@code r}. */ + public static String reactionArguments(Reaction r, Reactor reactor) { + return Stream.concat(Stream.of(getApiSelfStruct(reactor)), portVariableStream(r, reactor) .map(it -> String.format("((%s) %s)", it.getType(true), it.getAlias()))) .collect(Collectors.joining(", ")); } + /** Return code for extracting the user-facing part of the self struct from the self struct. */ private static String getApiSelfStruct(Reactor reactor) { return "(" + userFacingSelfType(reactor) + "*) (((char*) self) + sizeof(self_base_t))"; } - private static Stream ioTypedVariableStream(Reaction r, Reactor defaultReactorClass) { + /** Return a stream of all ports referenced by the signature of {@code r}. */ + private static Stream portVariableStream(Reaction r, Reactor defaultReactorClass) { return varRefStream(r) .map(it -> it.getVariable() instanceof TypedVariable tv ? new PortVariable( @@ -150,6 +154,13 @@ private static Stream ioTypedVariableStream(Reaction r, Reactor de .filter(Objects::nonNull); } + /** + * A variable that refers to a port. + * @param tv The variable of the variable reference. + * @param r The reactor that contains the port. + * @param container The {@code Instantiation} referenced in the obtaining of {@code tv}, if + * applicable; {@code null} otherwise. + */ private record PortVariable(TypedVariable tv, Reactor r, Instantiation container) { String getType(boolean userFacing) { var typeName = container == null ? @@ -160,15 +171,19 @@ String getType(boolean userFacing) { .findAny().orElseThrow()); return typeName + "*" + (getWidth() != null ? "*" : "") + (isMultiport ? "*" : ""); } + /** The name of the variable as it appears in the LF source. */ String getName() { return tv.getName(); } + /** The alias of the variable that should be used in code generation. */ String getAlias() { - return getName(); + return getName(); // TODO: avoid naming conflicts } + /** The width of the container, if applicable. */ String getWidth() { return container == null || container.getWidthSpec() == null ? null : "self->_lf_"+r.getName()+"_width"; } + /** The representation of this port as used by the LF programmer. */ String getRvalue() { return container == null ? getName() : container.getName() + "." + getName(); } @@ -178,10 +193,6 @@ private static Stream inputVarRefStream(Reaction reaction) { return varRefStream(Stream.concat(reaction.getTriggers().stream(), reaction.getSources().stream())); } - private static Stream triggerVarRefStream(Reaction reaction) { - return varRefStream(reaction.getTriggers().stream()); - } - private static Stream varRefStream(Stream toFilter) { return toFilter.map(it -> it instanceof VarRef v ? v : null) .filter(Objects::nonNull); @@ -191,25 +202,6 @@ private static Stream outputVarRefStream(Reaction reaction) { return reaction.getEffects().stream(); } - private static Stream inputVariableStream(Reaction reaction) { - return inputVarRefStream(reaction).map(VarRef::getVariable); - } - - private static String representVarRef(VarRef it, String multiportIndex, String bankIndex) { - String containerRepresentation = it.getContainer() == null ? null : - it.getContainer().getName() + ( - it.getContainer().getWidthSpec() == null ? "" : "[" + bankIndex + "]" - ); - String varRepresentation = it.getVariable().getName() + ( - !(it instanceof Port p) ? "" : p.getWidthSpec() == null ? "" : "[" + multiportIndex + "]" - ); - return (containerRepresentation == null ? "" : containerRepresentation + ".") + varRepresentation; - } - - private static String cVariableOfVarRef(VarRef it) { - return it.getContainer() != null ? it.getContainer().getName() : it.getVariable().getName(); - } - private static Stream varRefStream(Reaction reaction) { return Stream.concat(inputVarRefStream(reaction), outputVarRefStream(reaction)); } From 3e5e959bb2281fdde84ce083c37efcd966fe9fa5 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 31 Mar 2023 01:33:10 -0700 Subject: [PATCH 83/92] Update unit-tests.yml and submodule. --- .github/workflows/unit-tests.yml | 1 + org.lflang/src/lib/c/reactor-c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 6c2704629e..1caec5c1ac 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -12,6 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 with: + submodules: true fetch-depth: 0 - name: Prepare build environment uses: ./.github/actions/prepare-build-env diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index 3ab930e0d4..ac3d19a58a 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit 3ab930e0d4cb30524a946097f199185d32ea789f +Subproject commit ac3d19a58ad86dd57c14b2505289f64b8c651d79 From da9c9eaba07c64f382c2ce29c3f0a758ebfbb9e2 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 31 Mar 2023 13:17:17 -0700 Subject: [PATCH 84/92] Update ci.yml. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e182bae77..8678561b9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: # Run the unit tests. unit-tests: - uses: lf-lang/lingua-franca/.github/workflows/unit-tests.yml@master + uses: lf-lang/lingua-franca/.github/workflows/unit-tests.yml@bodyless-reactions needs: cancel # Run tests for the standalone compiler. From a4dd88c50ffe6aec79ea2d53938762833f51e8c8 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 31 Mar 2023 13:23:13 -0700 Subject: [PATCH 85/92] Add stdio.h back into the user-visible namespace. I think that in the long run this might not be what we want, but it reduces the impact of this and the accompanying reactor-c PR on existing LF programs. --- org.lflang/src/lib/c/reactor-c | 2 +- test/C/src/ActionDelay.lf | 4 ---- test/C/src/ActionIsPresent.lf | 4 ---- test/C/src/ActionWithNoReaction.lf | 4 ---- test/C/src/After.lf | 4 ---- test/C/src/AfterCycles.lf | 4 ---- test/C/src/AfterOverlapped.lf | 4 ---- test/C/src/AfterZero.lf | 4 ---- test/C/src/ArrayAsParameter.lf | 4 ---- test/C/src/ArrayAsType.lf | 4 ---- test/C/src/ArrayPrint.lf | 4 ---- test/C/src/CharLiteralInitializer.lf | 4 ---- test/C/src/Composition.lf | 4 ---- test/C/src/CompositionAfter.lf | 4 ---- test/C/src/CompositionGain.lf | 4 ---- test/C/src/CompositionInheritance.lf | 4 ---- test/C/src/DanglingOutput.lf | 4 ---- test/C/src/Deadline.lf | 1 - test/C/src/DeadlineAnytime.lf | 4 ---- test/C/src/DeadlineHandledAbove.lf | 1 - test/C/src/DeadlineZero.lf | 4 ---- test/C/src/DelayArray.lf | 4 ---- test/C/src/DelayArrayWithAfter.lf | 4 ---- test/C/src/DelayInt.lf | 4 ---- test/C/src/DelayPointer.lf | 4 ---- test/C/src/DelayString.lf | 1 - test/C/src/DelayStructWithAfter.lf | 1 - test/C/src/DelayStructWithAfterOverlapped.lf | 1 - test/C/src/DelayedAction.lf | 4 ---- test/C/src/DelayedReaction.lf | 4 ---- test/C/src/Determinism.lf | 4 ---- test/C/src/DoubleInvocation.lf | 4 ---- test/C/src/DoublePort.lf | 4 ---- test/C/src/DoubleReaction.lf | 4 ---- test/C/src/DoubleTrigger.lf | 4 ---- test/C/src/Gain.lf | 4 ---- test/C/src/GetTime.lf | 4 ---- test/C/src/Hello.lf | 1 - test/C/src/HelloWorld.lf | 4 ---- test/C/src/Hierarchy.lf | 4 ---- test/C/src/Hierarchy2.lf | 4 ---- test/C/src/IdentifierLength.lf | 4 ---- test/C/src/ImportComposition.lf | 4 ---- test/C/src/InheritanceAction.lf | 4 ---- test/C/src/ManualDelayedReaction.lf | 4 ---- test/C/src/Microsteps.lf | 4 ---- test/C/src/Minimal.lf | 4 ---- test/C/src/MultipleContained.lf | 4 ---- test/C/src/ParameterizedState.lf | 4 ---- test/C/src/PeriodicDesugared.lf | 4 ---- test/C/src/PhysicalConnection.lf | 4 ---- test/C/src/PingPong.lf | 4 ---- test/C/src/Preamble.lf | 4 ---- test/C/src/ReadOutputOfContainedReactor.lf | 4 ---- test/C/src/Schedule.lf | 4 ---- test/C/src/ScheduleLogicalAction.lf | 4 ---- test/C/src/ScheduleValue.lf | 1 - test/C/src/SelfLoop.lf | 4 ---- test/C/src/SendingInside.lf | 4 ---- test/C/src/SendingInside2.lf | 4 ---- test/C/src/SendsPointerTest.lf | 5 +---- test/C/src/SetArray.lf | 4 ---- test/C/src/SetToken.lf | 4 ---- test/C/src/SimpleDeadline.lf | 1 - test/C/src/SlowingClock.lf | 4 ---- test/C/src/SlowingClockPhysical.lf | 4 ---- test/C/src/StartupOutFromInside.lf | 4 ---- test/C/src/Starvation.lf | 4 ---- test/C/src/Stop.lf | 4 ---- test/C/src/StopZero.lf | 4 ---- test/C/src/Stride.lf | 4 ---- test/C/src/StructAsState.lf | 2 -- test/C/src/StructAsType.lf | 1 - test/C/src/StructAsTypeDirect.lf | 1 - test/C/src/StructParallel.lf | 1 - test/C/src/StructPrint.lf | 1 - test/C/src/StructScale.lf | 1 - test/C/src/SubclassesAndStartup.lf | 4 ---- test/C/src/TestForPreviousOutput.lf | 1 - test/C/src/TimeLimit.lf | 4 ---- test/C/src/TimeState.lf | 4 ---- test/C/src/Timeout.lf | 4 ---- test/C/src/TimeoutZero.lf | 4 ---- test/C/src/TriggerDownstreamOnlyIfPresent2.lf | 4 ---- test/C/src/UnconnectedInput.lf | 4 ---- test/C/src/Wcet.lf | 4 ---- test/C/src/concurrent/AsyncCallback.lf | 1 - test/C/src/concurrent/AsyncCallbackDrop.lf | 1 - test/C/src/concurrent/AsyncCallbackReplace.lf | 1 - test/C/src/concurrent/CompositionThreaded.lf | 4 ---- test/C/src/concurrent/DeadlineHandledAboveThreaded.lf | 1 - test/C/src/concurrent/DeadlineThreaded.lf | 1 - test/C/src/concurrent/DelayIntThreaded.lf | 4 ---- test/C/src/concurrent/DeterminismThreaded.lf | 4 ---- test/C/src/concurrent/DoubleReactionThreaded.lf | 4 ---- test/C/src/concurrent/GainThreaded.lf | 4 ---- test/C/src/concurrent/HelloThreaded.lf | 1 - test/C/src/concurrent/MinimalThreaded.lf | 4 ---- test/C/src/concurrent/PingPongThreaded.lf | 4 ---- test/C/src/concurrent/ScheduleAt.lf | 4 ---- test/C/src/concurrent/ScheduleTwice.lf | 4 ---- test/C/src/concurrent/ScheduleTwiceThreaded.lf | 4 ---- test/C/src/concurrent/SendingInsideThreaded.lf | 4 ---- test/C/src/concurrent/StarvationThreaded.lf | 4 ---- test/C/src/concurrent/StopZeroThreaded.lf | 4 ---- test/C/src/concurrent/Threaded.lf | 4 ---- test/C/src/concurrent/ThreadedMultiport.lf | 4 ---- test/C/src/concurrent/ThreadedThreaded.lf | 4 ---- test/C/src/concurrent/TimeLimitThreaded.lf | 4 ---- test/C/src/concurrent/TimeoutThreaded.lf | 4 ---- test/C/src/concurrent/TimeoutZeroThreaded.lf | 4 ---- test/C/src/concurrent/Tracing.lf | 1 - test/C/src/docker/FilesPropertyContainerized.lf | 1 - test/C/src/federated/DistributedCountDecentralized.lf | 4 ---- test/C/src/federated/DistributedCountDecentralizedLate.lf | 4 ---- .../DistributedCountDecentralizedLateHierarchy.lf | 4 ---- test/C/src/federated/DistributedCountPhysical.lf | 4 ---- .../C/src/federated/DistributedCountPhysicalAfterDelay.lf | 4 ---- .../federated/DistributedCountPhysicalDecentralized.lf | 4 ---- test/C/src/federated/DistributedLoopedAction.lf | 4 ---- test/C/src/federated/DistributedMultiportToken.lf | 1 - test/C/src/federated/DistributedNetworkOrder.lf | 1 - test/C/src/federated/DistributedStopZero.lf | 4 ---- test/C/src/federated/DistributedToken.lf | 4 ---- test/C/src/federated/HelloDistributed.lf | 1 - test/C/src/federated/PingPongDistributedPhysical.lf | 4 ---- .../failing/DistributedNetworkOrderDecentralized.lf | 4 ---- test/C/src/lib/ImportedAgain.lf | 4 ---- test/C/src/lib/Test.lf | 4 ---- test/C/src/modal_models/ConvertCaseTest.lf | 8 +------- test/C/src/modal_models/Count3Modes.lf | 4 ---- test/C/src/modal_models/MixedReactions.lf | 4 ---- test/C/src/modal_models/ModalActions.lf | 4 ---- test/C/src/modal_models/ModalAfter.lf | 4 ---- test/C/src/modal_models/ModalCycleBreaker.lf | 4 ---- test/C/src/modal_models/ModalNestedReactions.lf | 4 ---- test/C/src/modal_models/ModalStartupShutdown.lf | 4 ---- test/C/src/modal_models/ModalStateReset.lf | 4 ---- test/C/src/modal_models/ModalStateResetAuto.lf | 4 ---- test/C/src/modal_models/ModalTimers.lf | 4 ---- .../src/modal_models/MultipleOutputFeeder_2Connections.lf | 4 ---- .../MultipleOutputFeeder_ReactionConnections.lf | 4 ---- test/C/src/modal_models/util/TraceTesting.lf | 4 ---- test/C/src/multiport/BankIndexInitializer.lf | 5 +---- test/C/src/multiport/BankToBank.lf | 4 ---- test/C/src/multiport/BankToBankMultiport.lf | 4 ---- test/C/src/multiport/BankToBankMultiportAfter.lf | 4 ---- test/C/src/multiport/BankToMultiport.lf | 4 ---- test/C/src/multiport/Broadcast.lf | 4 ---- test/C/src/multiport/BroadcastAfter.lf | 4 ---- test/C/src/multiport/BroadcastMultipleAfter.lf | 4 ---- test/C/src/multiport/DualBanks.lf | 4 ---- test/C/src/multiport/DualBanksMultiport.lf | 4 ---- test/C/src/multiport/FullyConnected.lf | 4 ---- test/C/src/multiport/FullyConnectedAddressable.lf | 4 ---- test/C/src/multiport/MultiportFromBank.lf | 4 ---- test/C/src/multiport/MultiportFromHierarchy.lf | 4 ---- test/C/src/multiport/MultiportFromReaction.lf | 4 ---- test/C/src/multiport/MultiportIn.lf | 4 ---- test/C/src/multiport/MultiportInParameterized.lf | 4 ---- test/C/src/multiport/MultiportMutableInputArray.lf | 4 ---- test/C/src/multiport/MultiportOut.lf | 4 ---- test/C/src/multiport/MultiportToBank.lf | 4 ---- test/C/src/multiport/MultiportToBankAfter.lf | 4 ---- test/C/src/multiport/MultiportToBankDouble.lf | 4 ---- test/C/src/multiport/MultiportToBankHierarchy.lf | 4 ---- test/C/src/multiport/MultiportToHierarchy.lf | 4 ---- test/C/src/multiport/MultiportToMultiport.lf | 4 ---- test/C/src/multiport/MultiportToMultiport2.lf | 4 ---- test/C/src/multiport/MultiportToMultiport2After.lf | 4 ---- test/C/src/multiport/MultiportToMultiportArray.lf | 4 ---- test/C/src/multiport/MultiportToMultiportParameter.lf | 4 ---- test/C/src/multiport/MultiportToPort.lf | 4 ---- test/C/src/multiport/MultiportToReaction.lf | 4 ---- test/C/src/multiport/PipelineAfter.lf | 4 ---- test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf | 4 ---- test/C/src/no_inlining/Count.lf | 4 ---- test/C/src/no_inlining/CountHierarchy.lf | 4 ---- test/C/src/no_inlining/MultiportToReactionNoInlining.lf | 4 ---- test/C/src/serialization/PersonProtocolBuffers.lf | 4 ---- test/C/src/serialization/ProtoNoPacking.lf | 4 ---- test/C/src/target/HelloWorldCCPP.lf | 4 ---- test/C/src/token/TokenContainedSource.lf | 4 ---- test/C/src/token/TokenContainedSourceBank.lf | 4 ---- test/C/src/token/lib/Token.lf | 1 - test/C/src/zephyr/HelloZephyr.lf | 4 ---- test/C/src/zephyr/Timer.lf | 4 ---- test/C/src/zephyr/lib/Led.lf | 4 ---- 188 files changed, 4 insertions(+), 672 deletions(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index ac3d19a58a..9eb95b0559 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit ac3d19a58ad86dd57c14b2505289f64b8c651d79 +Subproject commit 9eb95b0559fc30d192790fd13af1891ccbf57746 diff --git a/test/C/src/ActionDelay.lf b/test/C/src/ActionDelay.lf index 59179c1936..86e510080a 100644 --- a/test/C/src/ActionDelay.lf +++ b/test/C/src/ActionDelay.lf @@ -1,10 +1,6 @@ // Test logical action with delay. target C -preamble {= - #include -=} - reactor GeneratedDelay { input y_in: int output y_out: int diff --git a/test/C/src/ActionIsPresent.lf b/test/C/src/ActionIsPresent.lf index cc773c82f4..b94108949e 100644 --- a/test/C/src/ActionIsPresent.lf +++ b/test/C/src/ActionIsPresent.lf @@ -1,10 +1,6 @@ // Tests the is_present variable for actions. target C -preamble {= - #include -=} - main reactor ActionIsPresent(offset: time = 1 nsec, period: time = 500 msec) { logical action a state success: bool = false diff --git a/test/C/src/ActionWithNoReaction.lf b/test/C/src/ActionWithNoReaction.lf index cb4eb18b36..8ac720167d 100644 --- a/test/C/src/ActionWithNoReaction.lf +++ b/test/C/src/ActionWithNoReaction.lf @@ -6,10 +6,6 @@ target C { timeout: 3 sec } -preamble {= - #include -=} - reactor foo { input x: int output y: int diff --git a/test/C/src/After.lf b/test/C/src/After.lf index 05cfd6a8cc..d3663457e4 100644 --- a/test/C/src/After.lf +++ b/test/C/src/After.lf @@ -5,10 +5,6 @@ target C { timeout: 3 sec } -preamble {= - #include -=} - reactor foo { input x: int output y: int diff --git a/test/C/src/AfterCycles.lf b/test/C/src/AfterCycles.lf index ace6feaf5c..d7d621046b 100644 --- a/test/C/src/AfterCycles.lf +++ b/test/C/src/AfterCycles.lf @@ -2,10 +2,6 @@ // running without detected a cycle. target C -preamble {= - #include -=} - reactor Source { output out: unsigned diff --git a/test/C/src/AfterOverlapped.lf b/test/C/src/AfterOverlapped.lf index c0022ef456..0925dc5164 100644 --- a/test/C/src/AfterOverlapped.lf +++ b/test/C/src/AfterOverlapped.lf @@ -6,10 +6,6 @@ target C { import Count from "lib/Count.lf" -preamble {= - #include -=} - reactor Test { input c: int state i: int = 0 diff --git a/test/C/src/AfterZero.lf b/test/C/src/AfterZero.lf index dda3f4c1b8..378114c730 100644 --- a/test/C/src/AfterZero.lf +++ b/test/C/src/AfterZero.lf @@ -5,10 +5,6 @@ target C { timeout: 3 sec } -preamble {= - #include -=} - reactor foo { input x: int output y: int diff --git a/test/C/src/ArrayAsParameter.lf b/test/C/src/ArrayAsParameter.lf index b89516a052..a9df29cb03 100644 --- a/test/C/src/ArrayAsParameter.lf +++ b/test/C/src/ArrayAsParameter.lf @@ -3,10 +3,6 @@ // encode their own length. target C -preamble {= - #include -=} - reactor Source(sequence: int[] = {0, 1, 2}, n_sequence: int = 3) { output out: int state count: int = 0 diff --git a/test/C/src/ArrayAsType.lf b/test/C/src/ArrayAsType.lf index a72a1f17bc..c95e5bf385 100644 --- a/test/C/src/ArrayAsType.lf +++ b/test/C/src/ArrayAsType.lf @@ -2,10 +2,6 @@ // destination references the array directly. target C -preamble {= - #include -=} - reactor Source { output out: int[3] diff --git a/test/C/src/ArrayPrint.lf b/test/C/src/ArrayPrint.lf index 22a3655666..937bc51bea 100644 --- a/test/C/src/ArrayPrint.lf +++ b/test/C/src/ArrayPrint.lf @@ -6,10 +6,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(size: int = 3) { output out: int[] state count: int = 0 diff --git a/test/C/src/CharLiteralInitializer.lf b/test/C/src/CharLiteralInitializer.lf index 582f754d60..319af0224c 100644 --- a/test/C/src/CharLiteralInitializer.lf +++ b/test/C/src/CharLiteralInitializer.lf @@ -1,10 +1,6 @@ // Check that a state variable can have a char literal initializer target C -preamble {= - #include -=} - main reactor CharLiteralInitializer { state c: char = 'x' diff --git a/test/C/src/Composition.lf b/test/C/src/Composition.lf index 39cce2654f..7c024a9eba 100644 --- a/test/C/src/Composition.lf +++ b/test/C/src/Composition.lf @@ -5,10 +5,6 @@ target C { timeout: 10 sec } -preamble {= - #include -=} - reactor Source(period: time = 2 sec) { output y: int timer t(1 sec, period) diff --git a/test/C/src/CompositionAfter.lf b/test/C/src/CompositionAfter.lf index 07c68468a2..cb98ef7d7e 100644 --- a/test/C/src/CompositionAfter.lf +++ b/test/C/src/CompositionAfter.lf @@ -5,10 +5,6 @@ target C { timeout: 10 sec } -preamble {= - #include -=} - reactor Source(period: time = 2 sec) { output y: int timer t(1 sec, period) diff --git a/test/C/src/CompositionGain.lf b/test/C/src/CompositionGain.lf index b574c7ca1c..31cd7e5123 100644 --- a/test/C/src/CompositionGain.lf +++ b/test/C/src/CompositionGain.lf @@ -1,10 +1,6 @@ // This tests send data through a contained reactor. target C -preamble {= - #include -=} - reactor Gain { input gainin: int output y: int diff --git a/test/C/src/CompositionInheritance.lf b/test/C/src/CompositionInheritance.lf index b525f363e3..06221e9788 100644 --- a/test/C/src/CompositionInheritance.lf +++ b/test/C/src/CompositionInheritance.lf @@ -5,10 +5,6 @@ target C { timeout: 10 sec } -preamble {= - #include -=} - reactor Source(period: time = 2 sec) { input foo: int output y: int diff --git a/test/C/src/DanglingOutput.lf b/test/C/src/DanglingOutput.lf index e68c66f9be..6305f17644 100644 --- a/test/C/src/DanglingOutput.lf +++ b/test/C/src/DanglingOutput.lf @@ -2,10 +2,6 @@ // in a compilation error. Passing the test is just compiling and running. target C -preamble {= - #include -=} - reactor Source { output out: int timer t diff --git a/test/C/src/Deadline.lf b/test/C/src/Deadline.lf index 807be07667..21ea7df141 100644 --- a/test/C/src/Deadline.lf +++ b/test/C/src/Deadline.lf @@ -9,7 +9,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/DeadlineAnytime.lf b/test/C/src/DeadlineAnytime.lf index ec63f9f13e..37540fd10b 100644 --- a/test/C/src/DeadlineAnytime.lf +++ b/test/C/src/DeadlineAnytime.lf @@ -1,10 +1,6 @@ // Test whether the lf_check_deadline function works. target C -preamble {= - #include -=} - reactor A { state i: int logical action a diff --git a/test/C/src/DeadlineHandledAbove.lf b/test/C/src/DeadlineHandledAbove.lf index 7d93e69e75..3b0dc49198 100644 --- a/test/C/src/DeadlineHandledAbove.lf +++ b/test/C/src/DeadlineHandledAbove.lf @@ -6,7 +6,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/DeadlineZero.lf b/test/C/src/DeadlineZero.lf index 9e60adb626..3ae49a9409 100644 --- a/test/C/src/DeadlineZero.lf +++ b/test/C/src/DeadlineZero.lf @@ -3,10 +3,6 @@ target C { timeout: 1 sec } -preamble {= - #include -=} - reactor Detector { input trigger: int state cnt: int = 0 diff --git a/test/C/src/DelayArray.lf b/test/C/src/DelayArray.lf index 62c1e02b01..72eb734888 100644 --- a/test/C/src/DelayArray.lf +++ b/test/C/src/DelayArray.lf @@ -4,10 +4,6 @@ target C { build-type: RelWithDebInfo } -preamble {= - #include -=} - reactor DelayPointer(delay: time = 100 msec) { input in: int[] output out: int[] diff --git a/test/C/src/DelayArrayWithAfter.lf b/test/C/src/DelayArrayWithAfter.lf index b77c589ced..c94be3b9a1 100644 --- a/test/C/src/DelayArrayWithAfter.lf +++ b/test/C/src/DelayArrayWithAfter.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output out: int[] state iteration: int = 1 diff --git a/test/C/src/DelayInt.lf b/test/C/src/DelayInt.lf index 9ede30bd32..78ca793716 100644 --- a/test/C/src/DelayInt.lf +++ b/test/C/src/DelayInt.lf @@ -1,10 +1,6 @@ // This tests actions with payloads by delaying an input by a fixed amount. target C -preamble {= - #include -=} - reactor Delay(delay: time = 100 msec) { input in: int output out: int diff --git a/test/C/src/DelayPointer.lf b/test/C/src/DelayPointer.lf index 1152c5fc05..c6313c199d 100644 --- a/test/C/src/DelayPointer.lf +++ b/test/C/src/DelayPointer.lf @@ -1,10 +1,6 @@ // Test delaying a pointer type. target C -preamble {= - #include -=} - reactor DelayPointer2(delay: time = 100 msec) { input in: int* output out: int* diff --git a/test/C/src/DelayString.lf b/test/C/src/DelayString.lf index c44e53387c..80b89020dd 100644 --- a/test/C/src/DelayString.lf +++ b/test/C/src/DelayString.lf @@ -6,7 +6,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include #ifdef __cplusplus } diff --git a/test/C/src/DelayStructWithAfter.lf b/test/C/src/DelayStructWithAfter.lf index 3259ec471b..6693a437e6 100644 --- a/test/C/src/DelayStructWithAfter.lf +++ b/test/C/src/DelayStructWithAfter.lf @@ -5,7 +5,6 @@ target C { preamble {= #include "hello.h" - #include =} reactor Source { diff --git a/test/C/src/DelayStructWithAfterOverlapped.lf b/test/C/src/DelayStructWithAfterOverlapped.lf index 2158894fba..8161022653 100644 --- a/test/C/src/DelayStructWithAfterOverlapped.lf +++ b/test/C/src/DelayStructWithAfterOverlapped.lf @@ -7,7 +7,6 @@ target C { preamble {= #include "hello.h" - #include =} reactor Source { diff --git a/test/C/src/DelayedAction.lf b/test/C/src/DelayedAction.lf index 736dec207f..28a3e81ac5 100644 --- a/test/C/src/DelayedAction.lf +++ b/test/C/src/DelayedAction.lf @@ -3,10 +3,6 @@ target C { timeout: 5 sec } -preamble {= - #include -=} - main reactor DelayedAction { timer t(0, 1 sec) logical action a diff --git a/test/C/src/DelayedReaction.lf b/test/C/src/DelayedReaction.lf index 289d8c9040..2dcf80f106 100644 --- a/test/C/src/DelayedReaction.lf +++ b/test/C/src/DelayedReaction.lf @@ -1,10 +1,6 @@ // Test delay made on a connection. target C -preamble {= - #include -=} - reactor Source { output out: int timer t diff --git a/test/C/src/Determinism.lf b/test/C/src/Determinism.lf index 2bb5e8498b..fea5290373 100644 --- a/test/C/src/Determinism.lf +++ b/test/C/src/Determinism.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Source { output y: int timer t diff --git a/test/C/src/DoubleInvocation.lf b/test/C/src/DoubleInvocation.lf index 628a16b6c8..973c8b18f6 100644 --- a/test/C/src/DoubleInvocation.lf +++ b/test/C/src/DoubleInvocation.lf @@ -10,10 +10,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Ball { output position: int output velocity: int diff --git a/test/C/src/DoublePort.lf b/test/C/src/DoublePort.lf index 6a86916137..c8bf9811f8 100644 --- a/test/C/src/DoublePort.lf +++ b/test/C/src/DoublePort.lf @@ -12,10 +12,6 @@ target C { import Count from "lib/Count.lf" -preamble {= - #include -=} - reactor CountMicrostep { state count: int = 1 output out: int diff --git a/test/C/src/DoubleReaction.lf b/test/C/src/DoubleReaction.lf index 3b32b8f358..8da6210825 100644 --- a/test/C/src/DoubleReaction.lf +++ b/test/C/src/DoubleReaction.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Clock(offset: time = 0, period: time = 1 sec) { output y: int timer t(offset, period) diff --git a/test/C/src/DoubleTrigger.lf b/test/C/src/DoubleTrigger.lf index 7af3a5a9c3..68ad603168 100644 --- a/test/C/src/DoubleTrigger.lf +++ b/test/C/src/DoubleTrigger.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - main reactor DoubleTrigger { timer t1 timer t2 diff --git a/test/C/src/Gain.lf b/test/C/src/Gain.lf index 1a3a0e14ab..7cac5eaae6 100644 --- a/test/C/src/Gain.lf +++ b/test/C/src/Gain.lf @@ -1,10 +1,6 @@ // Example in the Wiki. target C -preamble {= - #include -=} - reactor Scale(scale: int = 2) { input x: int output y: int diff --git a/test/C/src/GetTime.lf b/test/C/src/GetTime.lf index 7f6e98c173..18e70ebf79 100644 --- a/test/C/src/GetTime.lf +++ b/test/C/src/GetTime.lf @@ -5,10 +5,6 @@ target C { fast: false } -preamble {= - #include -=} - main reactor GetTime { timer t(0, 1 sec) diff --git a/test/C/src/Hello.lf b/test/C/src/Hello.lf index 4317588ee3..7784e2f86f 100644 --- a/test/C/src/Hello.lf +++ b/test/C/src/Hello.lf @@ -9,7 +9,6 @@ target C { } preamble {= - #include #include =} diff --git a/test/C/src/HelloWorld.lf b/test/C/src/HelloWorld.lf index 660d1e89d2..7de913c8ad 100644 --- a/test/C/src/HelloWorld.lf +++ b/test/C/src/HelloWorld.lf @@ -6,10 +6,6 @@ target C { build-type: Debug } -preamble {= - #include -=} - reactor HelloWorld2 { state success: bool = false diff --git a/test/C/src/Hierarchy.lf b/test/C/src/Hierarchy.lf index 463c6af403..ea14165e24 100644 --- a/test/C/src/Hierarchy.lf +++ b/test/C/src/Hierarchy.lf @@ -1,10 +1,6 @@ // Test data transport across hierarchy. target C -preamble {= - #include -=} - reactor Source { output out: int timer t diff --git a/test/C/src/Hierarchy2.lf b/test/C/src/Hierarchy2.lf index 2c7487b2b1..0a4f20d4bc 100644 --- a/test/C/src/Hierarchy2.lf +++ b/test/C/src/Hierarchy2.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output out: int timer t(0, 1 sec) diff --git a/test/C/src/IdentifierLength.lf b/test/C/src/IdentifierLength.lf index f3785ff4f9..8fa38b96f0 100644 --- a/test/C/src/IdentifierLength.lf +++ b/test/C/src/IdentifierLength.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor A_Really_Long_Name_For_A_Source(period: time = 2 sec) { output y: int timer t(1 sec, period) diff --git a/test/C/src/ImportComposition.lf b/test/C/src/ImportComposition.lf index c784d483af..22a1bfef87 100644 --- a/test/C/src/ImportComposition.lf +++ b/test/C/src/ImportComposition.lf @@ -4,10 +4,6 @@ target C import ImportedComposition from "lib/ImportedComposition.lf" -preamble {= - #include -=} - main reactor ImportComposition { a = new ImportedComposition() state received: bool = false diff --git a/test/C/src/InheritanceAction.lf b/test/C/src/InheritanceAction.lf index 240bfb4e68..680ffe2f75 100644 --- a/test/C/src/InheritanceAction.lf +++ b/test/C/src/InheritanceAction.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { logical action foo: int output y: int diff --git a/test/C/src/ManualDelayedReaction.lf b/test/C/src/ManualDelayedReaction.lf index 39d0e49747..72c57105ce 100644 --- a/test/C/src/ManualDelayedReaction.lf +++ b/test/C/src/ManualDelayedReaction.lf @@ -5,10 +5,6 @@ target C { keepalive: false } -preamble {= - #include -=} - // That's the stuff that shall be generated for the after reactor GeneratedDelay { input y_in: int diff --git a/test/C/src/Microsteps.lf b/test/C/src/Microsteps.lf index 60babbfa8c..795a4801a7 100644 --- a/test/C/src/Microsteps.lf +++ b/test/C/src/Microsteps.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Destination { input x: int input y: int diff --git a/test/C/src/Minimal.lf b/test/C/src/Minimal.lf index 5999d0c660..350f92a795 100644 --- a/test/C/src/Minimal.lf +++ b/test/C/src/Minimal.lf @@ -1,10 +1,6 @@ // This is a smoke test of a minimal reactor. target C -preamble {= - #include -=} - main reactor Minimal { reaction(startup) {= printf("Hello World.\n"); =} } diff --git a/test/C/src/MultipleContained.lf b/test/C/src/MultipleContained.lf index 341c11cf99..540052ba87 100644 --- a/test/C/src/MultipleContained.lf +++ b/test/C/src/MultipleContained.lf @@ -2,10 +2,6 @@ // reactor. target C -preamble {= - #include -=} - reactor Contained { output trigger: int input in1: int diff --git a/test/C/src/ParameterizedState.lf b/test/C/src/ParameterizedState.lf index ed40c13b33..3d92345ca9 100644 --- a/test/C/src/ParameterizedState.lf +++ b/test/C/src/ParameterizedState.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Foo(bar: int = 42) { state baz = bar diff --git a/test/C/src/PeriodicDesugared.lf b/test/C/src/PeriodicDesugared.lf index c84d7da664..46eb97db9c 100644 --- a/test/C/src/PeriodicDesugared.lf +++ b/test/C/src/PeriodicDesugared.lf @@ -3,10 +3,6 @@ target C { timeout: 1 sec } -preamble {= - #include -=} - main reactor(offset: time = 0, period: time = 500 msec) { logical action init(offset) logical action recur(period) diff --git a/test/C/src/PhysicalConnection.lf b/test/C/src/PhysicalConnection.lf index 4aeb2d85fb..2cac10c240 100644 --- a/test/C/src/PhysicalConnection.lf +++ b/test/C/src/PhysicalConnection.lf @@ -1,10 +1,6 @@ /** Test physical connections. */ target C -preamble {= - #include -=} - reactor Source { output out: int diff --git a/test/C/src/PingPong.lf b/test/C/src/PingPong.lf index 9cec5836d3..2f1699a51d 100644 --- a/test/C/src/PingPong.lf +++ b/test/C/src/PingPong.lf @@ -25,10 +25,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Ping(count: int = 10) { input receive: int output send: int diff --git a/test/C/src/Preamble.lf b/test/C/src/Preamble.lf index 76091241f4..01b4b371b6 100644 --- a/test/C/src/Preamble.lf +++ b/test/C/src/Preamble.lf @@ -3,10 +3,6 @@ target C { fast: true } -preamble {= - #include -=} - main reactor Preamble { preamble {= #include diff --git a/test/C/src/ReadOutputOfContainedReactor.lf b/test/C/src/ReadOutputOfContainedReactor.lf index 165078a8c9..ce2129069b 100644 --- a/test/C/src/ReadOutputOfContainedReactor.lf +++ b/test/C/src/ReadOutputOfContainedReactor.lf @@ -2,10 +2,6 @@ // permutations. target C -preamble {= - #include -=} - reactor Contained { output out: int diff --git a/test/C/src/Schedule.lf b/test/C/src/Schedule.lf index 56d51539e7..91d3e2db2b 100644 --- a/test/C/src/Schedule.lf +++ b/test/C/src/Schedule.lf @@ -1,10 +1,6 @@ // Example from Schedule section of the C Reactor Target wiki page. target C -preamble {= - #include -=} - reactor Schedule2 { input x: int logical action a diff --git a/test/C/src/ScheduleLogicalAction.lf b/test/C/src/ScheduleLogicalAction.lf index 2ede28c9f4..762f8c6f52 100644 --- a/test/C/src/ScheduleLogicalAction.lf +++ b/test/C/src/ScheduleLogicalAction.lf @@ -5,10 +5,6 @@ target C { timeout: 3 sec } -preamble {= - #include -=} - reactor foo { input x: int output y: int diff --git a/test/C/src/ScheduleValue.lf b/test/C/src/ScheduleValue.lf index 506e4cea18..8481d47d61 100644 --- a/test/C/src/ScheduleValue.lf +++ b/test/C/src/ScheduleValue.lf @@ -7,7 +7,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include #include #ifdef __cplusplus diff --git a/test/C/src/SelfLoop.lf b/test/C/src/SelfLoop.lf index 96fa16ebcf..855be46792 100644 --- a/test/C/src/SelfLoop.lf +++ b/test/C/src/SelfLoop.lf @@ -3,10 +3,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Self { input x: int output y: int diff --git a/test/C/src/SendingInside.lf b/test/C/src/SendingInside.lf index e2086279b8..b1e8f25f93 100644 --- a/test/C/src/SendingInside.lf +++ b/test/C/src/SendingInside.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Printer { input x: int state count: int = 1 diff --git a/test/C/src/SendingInside2.lf b/test/C/src/SendingInside2.lf index 2ae20771f2..f65342de52 100644 --- a/test/C/src/SendingInside2.lf +++ b/test/C/src/SendingInside2.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Printer { input x: int diff --git a/test/C/src/SendsPointerTest.lf b/test/C/src/SendsPointerTest.lf index 841d2996f2..1f17bd1388 100644 --- a/test/C/src/SendsPointerTest.lf +++ b/test/C/src/SendsPointerTest.lf @@ -2,10 +2,7 @@ // Reference counting ensures that the struct is freed. target C -preamble {= - #include - typedef int* int_pointer; -=} +preamble {= typedef int* int_pointer; =} reactor SendsPointer { output out: int_pointer diff --git a/test/C/src/SetArray.lf b/test/C/src/SetArray.lf index efa425d972..f30457f9f8 100644 --- a/test/C/src/SetArray.lf +++ b/test/C/src/SetArray.lf @@ -2,10 +2,6 @@ // on a struct. It delays by a logical time any pointer datatype. target C -preamble {= - #include -=} - reactor Source { output out: int[] diff --git a/test/C/src/SetToken.lf b/test/C/src/SetToken.lf index b23d564417..b9af4bff20 100644 --- a/test/C/src/SetToken.lf +++ b/test/C/src/SetToken.lf @@ -1,10 +1,6 @@ // Illustration of lf_set_token() in the wiki. target C -preamble {= - #include -=} - reactor Source { output out: int* logical action a: int diff --git a/test/C/src/SimpleDeadline.lf b/test/C/src/SimpleDeadline.lf index facde3688d..fba3e03cbc 100644 --- a/test/C/src/SimpleDeadline.lf +++ b/test/C/src/SimpleDeadline.lf @@ -7,7 +7,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/SlowingClock.lf b/test/C/src/SlowingClock.lf index 56aa59b6ee..d4a1e1d5f4 100644 --- a/test/C/src/SlowingClock.lf +++ b/test/C/src/SlowingClock.lf @@ -9,10 +9,6 @@ target C { fast: true } -preamble {= - #include -=} - main reactor SlowingClock { logical action a(100 msec) state interval: time = 100 msec diff --git a/test/C/src/SlowingClockPhysical.lf b/test/C/src/SlowingClockPhysical.lf index 608a7df217..0e82730112 100644 --- a/test/C/src/SlowingClockPhysical.lf +++ b/test/C/src/SlowingClockPhysical.lf @@ -9,10 +9,6 @@ target C { timeout: 1500 msec } -preamble {= - #include -=} - main reactor SlowingClockPhysical { physical action a(100 msec) state interval: time = 100 msec diff --git a/test/C/src/StartupOutFromInside.lf b/test/C/src/StartupOutFromInside.lf index f316ab3cdc..cad2d282bf 100644 --- a/test/C/src/StartupOutFromInside.lf +++ b/test/C/src/StartupOutFromInside.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Bar { output out: int diff --git a/test/C/src/Starvation.lf b/test/C/src/Starvation.lf index 01cf26192a..a1c1167850 100644 --- a/test/C/src/Starvation.lf +++ b/test/C/src/Starvation.lf @@ -6,10 +6,6 @@ */ target C -preamble {= - #include -=} - reactor SuperDenseSender(number_of_iterations: int = 10) { logical action loop output out: int diff --git a/test/C/src/Stop.lf b/test/C/src/Stop.lf index 9009c7e5f2..1731bced42 100644 --- a/test/C/src/Stop.lf +++ b/test/C/src/Stop.lf @@ -9,10 +9,6 @@ target C { import Sender from "lib/LoopedActionSender.lf" -preamble {= - #include -=} - reactor Consumer { input in: int state reaction_invoked_correctly: bool = false diff --git a/test/C/src/StopZero.lf b/test/C/src/StopZero.lf index df05fc4d37..e845c6de48 100644 --- a/test/C/src/StopZero.lf +++ b/test/C/src/StopZero.lf @@ -6,10 +6,6 @@ */ target C -preamble {= - #include -=} - reactor Sender { output out: int state reaction_invoked_correctly: bool = false diff --git a/test/C/src/Stride.lf b/test/C/src/Stride.lf index 19aa6a08c6..62b9077878 100644 --- a/test/C/src/Stride.lf +++ b/test/C/src/Stride.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Count(stride: int = 1) { state count: int = 1 output y: int diff --git a/test/C/src/StructAsState.lf b/test/C/src/StructAsState.lf index ee978d080e..119762c14c 100644 --- a/test/C/src/StructAsState.lf +++ b/test/C/src/StructAsState.lf @@ -3,8 +3,6 @@ target C preamble {= - #include - typedef struct hello_t { char* name; int value; diff --git a/test/C/src/StructAsType.lf b/test/C/src/StructAsType.lf index 9bd0440f96..8674685530 100644 --- a/test/C/src/StructAsType.lf +++ b/test/C/src/StructAsType.lf @@ -4,7 +4,6 @@ target C { } preamble {= - #include #include "hello.h" =} diff --git a/test/C/src/StructAsTypeDirect.lf b/test/C/src/StructAsTypeDirect.lf index c0a9062b46..29472f057b 100644 --- a/test/C/src/StructAsTypeDirect.lf +++ b/test/C/src/StructAsTypeDirect.lf @@ -4,7 +4,6 @@ target C { } preamble {= - #include #include "hello.h" =} diff --git a/test/C/src/StructParallel.lf b/test/C/src/StructParallel.lf index 0437277093..3c8e61a3a2 100644 --- a/test/C/src/StructParallel.lf +++ b/test/C/src/StructParallel.lf @@ -8,7 +8,6 @@ target C { import Source from "StructScale.lf" preamble {= - #include #include "hello.h" =} diff --git a/test/C/src/StructPrint.lf b/test/C/src/StructPrint.lf index ddc939c52c..6af0d60c4f 100644 --- a/test/C/src/StructPrint.lf +++ b/test/C/src/StructPrint.lf @@ -5,7 +5,6 @@ target C { } preamble {= - #include #include "hello.h" =} diff --git a/test/C/src/StructScale.lf b/test/C/src/StructScale.lf index c4edc803fe..3b92bab002 100644 --- a/test/C/src/StructScale.lf +++ b/test/C/src/StructScale.lf @@ -7,7 +7,6 @@ target C { } preamble {= - #include #include "hello.h" =} diff --git a/test/C/src/SubclassesAndStartup.lf b/test/C/src/SubclassesAndStartup.lf index 76975c55eb..2dbc1f688f 100644 --- a/test/C/src/SubclassesAndStartup.lf +++ b/test/C/src/SubclassesAndStartup.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Super { state count: int = 0 diff --git a/test/C/src/TestForPreviousOutput.lf b/test/C/src/TestForPreviousOutput.lf index d1f27e2bd9..583c6cbb74 100644 --- a/test/C/src/TestForPreviousOutput.lf +++ b/test/C/src/TestForPreviousOutput.lf @@ -6,7 +6,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include #ifdef __cplusplus } diff --git a/test/C/src/TimeLimit.lf b/test/C/src/TimeLimit.lf index 804fb4cda8..ae178d53b5 100644 --- a/test/C/src/TimeLimit.lf +++ b/test/C/src/TimeLimit.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Clock(offset: time = 0, period: time = 1 sec) { output y: int timer t(offset, period) diff --git a/test/C/src/TimeState.lf b/test/C/src/TimeState.lf index a84587af5f..cb0a9627f3 100644 --- a/test/C/src/TimeState.lf +++ b/test/C/src/TimeState.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Foo(bar: int = 42) { state baz: time = 500 msec diff --git a/test/C/src/Timeout.lf b/test/C/src/Timeout.lf index 00a92804cc..cb13eafba4 100644 --- a/test/C/src/Timeout.lf +++ b/test/C/src/Timeout.lf @@ -9,10 +9,6 @@ target C { import Sender from "lib/LoopedActionSender.lf" -preamble {= - #include -=} - reactor Consumer { input in: int state success: bool = false diff --git a/test/C/src/TimeoutZero.lf b/test/C/src/TimeoutZero.lf index 7c5937dcae..2b146bb57c 100644 --- a/test/C/src/TimeoutZero.lf +++ b/test/C/src/TimeoutZero.lf @@ -10,10 +10,6 @@ target C { import Sender from "lib/LoopedActionSender.lf" -preamble {= - #include -=} - reactor Consumer { input in: int state success: bool = false diff --git a/test/C/src/TriggerDownstreamOnlyIfPresent2.lf b/test/C/src/TriggerDownstreamOnlyIfPresent2.lf index 1d4abd2902..bc62b214e9 100644 --- a/test/C/src/TriggerDownstreamOnlyIfPresent2.lf +++ b/test/C/src/TriggerDownstreamOnlyIfPresent2.lf @@ -7,10 +7,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output[2] out: int state count: int = 0 diff --git a/test/C/src/UnconnectedInput.lf b/test/C/src/UnconnectedInput.lf index a70291634b..21e8cc5a69 100644 --- a/test/C/src/UnconnectedInput.lf +++ b/test/C/src/UnconnectedInput.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output out: int timer t(0, 1 sec) diff --git a/test/C/src/Wcet.lf b/test/C/src/Wcet.lf index 56d9659343..d21268ea79 100644 --- a/test/C/src/Wcet.lf +++ b/test/C/src/Wcet.lf @@ -1,10 +1,6 @@ // Setup for WCET analysis of Worker target C -preamble {= - #include -=} - reactor Source { output out1: int output out2: int diff --git a/test/C/src/concurrent/AsyncCallback.lf b/test/C/src/concurrent/AsyncCallback.lf index 626d62c68c..58120446d4 100644 --- a/test/C/src/concurrent/AsyncCallback.lf +++ b/test/C/src/concurrent/AsyncCallback.lf @@ -17,7 +17,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/concurrent/AsyncCallbackDrop.lf b/test/C/src/concurrent/AsyncCallbackDrop.lf index 739ef7f9f4..b0c5c502f2 100644 --- a/test/C/src/concurrent/AsyncCallbackDrop.lf +++ b/test/C/src/concurrent/AsyncCallbackDrop.lf @@ -11,7 +11,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/concurrent/AsyncCallbackReplace.lf b/test/C/src/concurrent/AsyncCallbackReplace.lf index da95a1cdf2..7bac7496b5 100644 --- a/test/C/src/concurrent/AsyncCallbackReplace.lf +++ b/test/C/src/concurrent/AsyncCallbackReplace.lf @@ -11,7 +11,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/concurrent/CompositionThreaded.lf b/test/C/src/concurrent/CompositionThreaded.lf index 54c05e9f2b..cf0bafeb82 100644 --- a/test/C/src/concurrent/CompositionThreaded.lf +++ b/test/C/src/concurrent/CompositionThreaded.lf @@ -5,10 +5,6 @@ target C { timeout: 10 sec } -preamble {= - #include -=} - reactor Source(period: time = 2 sec) { output y: int timer t(1 sec, period) diff --git a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf index 4ecb9abec8..ad14879080 100644 --- a/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf +++ b/test/C/src/concurrent/DeadlineHandledAboveThreaded.lf @@ -6,7 +6,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/concurrent/DeadlineThreaded.lf b/test/C/src/concurrent/DeadlineThreaded.lf index b25eb19ebd..ffc1be2701 100644 --- a/test/C/src/concurrent/DeadlineThreaded.lf +++ b/test/C/src/concurrent/DeadlineThreaded.lf @@ -9,7 +9,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "platform.h" #ifdef __cplusplus } diff --git a/test/C/src/concurrent/DelayIntThreaded.lf b/test/C/src/concurrent/DelayIntThreaded.lf index 45f2d97095..449b17eb60 100644 --- a/test/C/src/concurrent/DelayIntThreaded.lf +++ b/test/C/src/concurrent/DelayIntThreaded.lf @@ -1,10 +1,6 @@ // This tests actions with payloads by delaying an input by a fixed amount. target C -preamble {= - #include -=} - reactor Delay(delay: time = 100 msec) { input in: int output out: int diff --git a/test/C/src/concurrent/DeterminismThreaded.lf b/test/C/src/concurrent/DeterminismThreaded.lf index b9d92245c2..c141f36330 100644 --- a/test/C/src/concurrent/DeterminismThreaded.lf +++ b/test/C/src/concurrent/DeterminismThreaded.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Source { output y: int timer t diff --git a/test/C/src/concurrent/DoubleReactionThreaded.lf b/test/C/src/concurrent/DoubleReactionThreaded.lf index 11b734bb9a..ba6c38ca19 100644 --- a/test/C/src/concurrent/DoubleReactionThreaded.lf +++ b/test/C/src/concurrent/DoubleReactionThreaded.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Clock(offset: time = 0, period: time = 1 sec) { output y: int timer t(offset, period) diff --git a/test/C/src/concurrent/GainThreaded.lf b/test/C/src/concurrent/GainThreaded.lf index e2cccfbb06..d9d6ec7673 100644 --- a/test/C/src/concurrent/GainThreaded.lf +++ b/test/C/src/concurrent/GainThreaded.lf @@ -1,10 +1,6 @@ // Example in the Wiki. target C -preamble {= - #include -=} - reactor Scale(scale: int = 2) { input x: int output y: int diff --git a/test/C/src/concurrent/HelloThreaded.lf b/test/C/src/concurrent/HelloThreaded.lf index 1ffb69adc1..285811a17d 100644 --- a/test/C/src/concurrent/HelloThreaded.lf +++ b/test/C/src/concurrent/HelloThreaded.lf @@ -9,7 +9,6 @@ target C { } preamble {= - #include #include =} diff --git a/test/C/src/concurrent/MinimalThreaded.lf b/test/C/src/concurrent/MinimalThreaded.lf index 47ef3d8766..5252d0465f 100644 --- a/test/C/src/concurrent/MinimalThreaded.lf +++ b/test/C/src/concurrent/MinimalThreaded.lf @@ -1,10 +1,6 @@ // This is a smoke test of a minimal reactor. target C -preamble {= - #include -=} - main reactor MinimalThreaded { timer t diff --git a/test/C/src/concurrent/PingPongThreaded.lf b/test/C/src/concurrent/PingPongThreaded.lf index a61c783688..4fae17911e 100644 --- a/test/C/src/concurrent/PingPongThreaded.lf +++ b/test/C/src/concurrent/PingPongThreaded.lf @@ -25,10 +25,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Ping(count: int = 10) { input receive: int output send: int diff --git a/test/C/src/concurrent/ScheduleAt.lf b/test/C/src/concurrent/ScheduleAt.lf index dc4344307b..2ef6af7af6 100644 --- a/test/C/src/concurrent/ScheduleAt.lf +++ b/test/C/src/concurrent/ScheduleAt.lf @@ -9,10 +9,6 @@ target C { keepalive: true } -preamble {= - #include -=} - reactor Scheduler { preamble {= #ifdef __cplusplus diff --git a/test/C/src/concurrent/ScheduleTwice.lf b/test/C/src/concurrent/ScheduleTwice.lf index 8f962837b9..e19f4d02d5 100644 --- a/test/C/src/concurrent/ScheduleTwice.lf +++ b/test/C/src/concurrent/ScheduleTwice.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - main reactor ScheduleTwice { logical action a: int state rc_count: int = 0 diff --git a/test/C/src/concurrent/ScheduleTwiceThreaded.lf b/test/C/src/concurrent/ScheduleTwiceThreaded.lf index f3132e68ac..499e0e4999 100644 --- a/test/C/src/concurrent/ScheduleTwiceThreaded.lf +++ b/test/C/src/concurrent/ScheduleTwiceThreaded.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - main reactor { logical action a: int state rc_count: int = 0 diff --git a/test/C/src/concurrent/SendingInsideThreaded.lf b/test/C/src/concurrent/SendingInsideThreaded.lf index c06a42eafd..e5185ecfc8 100644 --- a/test/C/src/concurrent/SendingInsideThreaded.lf +++ b/test/C/src/concurrent/SendingInsideThreaded.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Printer { input x: int state count: int = 1 diff --git a/test/C/src/concurrent/StarvationThreaded.lf b/test/C/src/concurrent/StarvationThreaded.lf index 0277dc3509..a16b5e46b6 100644 --- a/test/C/src/concurrent/StarvationThreaded.lf +++ b/test/C/src/concurrent/StarvationThreaded.lf @@ -7,10 +7,6 @@ */ target C -preamble {= - #include -=} - reactor SuperDenseSender(number_of_iterations: int = 10) { logical action loop output out: int diff --git a/test/C/src/concurrent/StopZeroThreaded.lf b/test/C/src/concurrent/StopZeroThreaded.lf index 1bab223f0b..7afd4b0069 100644 --- a/test/C/src/concurrent/StopZeroThreaded.lf +++ b/test/C/src/concurrent/StopZeroThreaded.lf @@ -6,10 +6,6 @@ */ target C -preamble {= - #include -=} - reactor Sender { output out: int state reaction_invoked_correctly: bool = false diff --git a/test/C/src/concurrent/Threaded.lf b/test/C/src/concurrent/Threaded.lf index 393c164405..01f67c1bd4 100644 --- a/test/C/src/concurrent/Threaded.lf +++ b/test/C/src/concurrent/Threaded.lf @@ -13,10 +13,6 @@ target C { flags: "" } -preamble {= - #include -=} - reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/concurrent/ThreadedMultiport.lf b/test/C/src/concurrent/ThreadedMultiport.lf index 33469ea541..2878393dac 100644 --- a/test/C/src/concurrent/ThreadedMultiport.lf +++ b/test/C/src/concurrent/ThreadedMultiport.lf @@ -5,10 +5,6 @@ target C { flags: "" } -preamble {= - #include -=} - reactor Source(width: int = 4) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/concurrent/ThreadedThreaded.lf b/test/C/src/concurrent/ThreadedThreaded.lf index 3b6f5354af..4037e8c193 100644 --- a/test/C/src/concurrent/ThreadedThreaded.lf +++ b/test/C/src/concurrent/ThreadedThreaded.lf @@ -12,10 +12,6 @@ target C { flags: "" } -preamble {= - #include -=} - reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/concurrent/TimeLimitThreaded.lf b/test/C/src/concurrent/TimeLimitThreaded.lf index f930eb6420..8d3824af47 100644 --- a/test/C/src/concurrent/TimeLimitThreaded.lf +++ b/test/C/src/concurrent/TimeLimitThreaded.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Clock(offset: time = 0, period: time = 1 sec) { output y: int timer t(offset, period) diff --git a/test/C/src/concurrent/TimeoutThreaded.lf b/test/C/src/concurrent/TimeoutThreaded.lf index 5750c0849e..3a7e2181d7 100644 --- a/test/C/src/concurrent/TimeoutThreaded.lf +++ b/test/C/src/concurrent/TimeoutThreaded.lf @@ -10,10 +10,6 @@ target C { import Sender from "../lib/LoopedActionSender.lf" -preamble {= - #include -=} - reactor Consumer { input in: int state success: bool = false diff --git a/test/C/src/concurrent/TimeoutZeroThreaded.lf b/test/C/src/concurrent/TimeoutZeroThreaded.lf index b71933a23d..9b24ef080f 100644 --- a/test/C/src/concurrent/TimeoutZeroThreaded.lf +++ b/test/C/src/concurrent/TimeoutZeroThreaded.lf @@ -10,10 +10,6 @@ target C { import Sender from "../lib/LoopedActionSender.lf" -preamble {= - #include -=} - reactor Consumer { input in: int state success: bool = false diff --git a/test/C/src/concurrent/Tracing.lf b/test/C/src/concurrent/Tracing.lf index e7c553e438..cbc4513732 100644 --- a/test/C/src/concurrent/Tracing.lf +++ b/test/C/src/concurrent/Tracing.lf @@ -8,7 +8,6 @@ target C { } preamble {= - #include #include =} diff --git a/test/C/src/docker/FilesPropertyContainerized.lf b/test/C/src/docker/FilesPropertyContainerized.lf index f88c986311..f9a1a240f3 100644 --- a/test/C/src/docker/FilesPropertyContainerized.lf +++ b/test/C/src/docker/FilesPropertyContainerized.lf @@ -4,7 +4,6 @@ target C { } preamble {= - #include #include "hello.h" =} diff --git a/test/C/src/federated/DistributedCountDecentralized.lf b/test/C/src/federated/DistributedCountDecentralized.lf index ca27cca03e..631dfab0c0 100644 --- a/test/C/src/federated/DistributedCountDecentralized.lf +++ b/test/C/src/federated/DistributedCountDecentralized.lf @@ -12,10 +12,6 @@ target C { import Count from "../lib/Count.lf" -preamble {= - #include -=} - reactor Print { input in: int state c: int = 1 diff --git a/test/C/src/federated/DistributedCountDecentralizedLate.lf b/test/C/src/federated/DistributedCountDecentralizedLate.lf index 8200c6d938..9fb6d3b064 100644 --- a/test/C/src/federated/DistributedCountDecentralizedLate.lf +++ b/test/C/src/federated/DistributedCountDecentralizedLate.lf @@ -13,10 +13,6 @@ target C { import Count from "../lib/Count.lf" -preamble {= - #include -=} - reactor Print { input in: int // STP () state success: int = 0 // STP(in, 30 msec); diff --git a/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf b/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf index ab5d75602d..31ab87e110 100644 --- a/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf +++ b/test/C/src/federated/DistributedCountDecentralizedLateHierarchy.lf @@ -15,10 +15,6 @@ target C { import Count from "../lib/Count.lf" -preamble {= - #include -=} - reactor ImportantActuator { input in: int state success: int = 0 diff --git a/test/C/src/federated/DistributedCountPhysical.lf b/test/C/src/federated/DistributedCountPhysical.lf index 4cecf77c8e..9e1e15f775 100644 --- a/test/C/src/federated/DistributedCountPhysical.lf +++ b/test/C/src/federated/DistributedCountPhysical.lf @@ -11,10 +11,6 @@ target C { timeout: 1 sec } -preamble {= - #include -=} - reactor Count { timer t(200 msec, 1 sec) state s: int = 0 diff --git a/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf b/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf index 9cea140502..b0da42218a 100644 --- a/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf +++ b/test/C/src/federated/DistributedCountPhysicalAfterDelay.lf @@ -10,10 +10,6 @@ target C import Count from "../lib/Count.lf" -preamble {= - #include -=} - reactor Print { input in: int state c: int = 1 diff --git a/test/C/src/federated/DistributedCountPhysicalDecentralized.lf b/test/C/src/federated/DistributedCountPhysicalDecentralized.lf index d80e58eae6..e821e4fb70 100644 --- a/test/C/src/federated/DistributedCountPhysicalDecentralized.lf +++ b/test/C/src/federated/DistributedCountPhysicalDecentralized.lf @@ -12,10 +12,6 @@ target C { coordination: decentralized } -preamble {= - #include -=} - reactor Count { timer t(200 msec, 1 sec) state s: int = 0 diff --git a/test/C/src/federated/DistributedLoopedAction.lf b/test/C/src/federated/DistributedLoopedAction.lf index 0574fdb6a1..8218e73646 100644 --- a/test/C/src/federated/DistributedLoopedAction.lf +++ b/test/C/src/federated/DistributedLoopedAction.lf @@ -10,10 +10,6 @@ target C { import Sender from "../lib/LoopedActionSender.lf" -preamble {= - #include -=} - reactor Receiver( take_a_break_after: int = 10, break_interval: time = 400 msec diff --git a/test/C/src/federated/DistributedMultiportToken.lf b/test/C/src/federated/DistributedMultiportToken.lf index 0e46a0c940..28efad56af 100644 --- a/test/C/src/federated/DistributedMultiportToken.lf +++ b/test/C/src/federated/DistributedMultiportToken.lf @@ -9,7 +9,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #ifdef __cplusplus } #endif diff --git a/test/C/src/federated/DistributedNetworkOrder.lf b/test/C/src/federated/DistributedNetworkOrder.lf index caadb62c62..ef979a949d 100644 --- a/test/C/src/federated/DistributedNetworkOrder.lf +++ b/test/C/src/federated/DistributedNetworkOrder.lf @@ -17,7 +17,6 @@ preamble {= #ifdef __cplusplus extern "C" { #endif - #include #include "federate.h" #ifdef __cplusplus } diff --git a/test/C/src/federated/DistributedStopZero.lf b/test/C/src/federated/DistributedStopZero.lf index c50be29cf9..67141bc624 100644 --- a/test/C/src/federated/DistributedStopZero.lf +++ b/test/C/src/federated/DistributedStopZero.lf @@ -6,10 +6,6 @@ */ target C -preamble {= - #include -=} - reactor Sender { output out: int timer t(0, 1 usec) diff --git a/test/C/src/federated/DistributedToken.lf b/test/C/src/federated/DistributedToken.lf index 14cfeba491..1068bd5f85 100644 --- a/test/C/src/federated/DistributedToken.lf +++ b/test/C/src/federated/DistributedToken.lf @@ -20,10 +20,6 @@ target C { coordination: decentralized } -preamble {= - #include -=} - /** * Reactor that generates a sequence of messages, one per second. The message * will be a string consisting of a root string followed by a count. diff --git a/test/C/src/federated/HelloDistributed.lf b/test/C/src/federated/HelloDistributed.lf index 4f49149994..909ce53b43 100644 --- a/test/C/src/federated/HelloDistributed.lf +++ b/test/C/src/federated/HelloDistributed.lf @@ -8,7 +8,6 @@ target C preamble {= - #include #include =} diff --git a/test/C/src/federated/PingPongDistributedPhysical.lf b/test/C/src/federated/PingPongDistributedPhysical.lf index 947548f7d5..d9ba517c59 100644 --- a/test/C/src/federated/PingPongDistributedPhysical.lf +++ b/test/C/src/federated/PingPongDistributedPhysical.lf @@ -26,10 +26,6 @@ */ target C -preamble {= - #include -=} - reactor Ping(count: int = 10) { input receive: int output send: int diff --git a/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf b/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf index 429d8381cb..97fa16b016 100644 --- a/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf +++ b/test/C/src/federated/failing/DistributedNetworkOrderDecentralized.lf @@ -12,10 +12,6 @@ target C { coordination: decentralized } -preamble {= - #include -=} - reactor Sender { output out: int timer t(0, 1 msec) diff --git a/test/C/src/lib/ImportedAgain.lf b/test/C/src/lib/ImportedAgain.lf index a2c6def138..07f2cc9faa 100644 --- a/test/C/src/lib/ImportedAgain.lf +++ b/test/C/src/lib/ImportedAgain.lf @@ -2,10 +2,6 @@ // itself imports a reactor definition. target C -preamble {= - #include -=} - reactor ImportedAgain { input x: int diff --git a/test/C/src/lib/Test.lf b/test/C/src/lib/Test.lf index dfcc5c41fa..3ad7518d4e 100644 --- a/test/C/src/lib/Test.lf +++ b/test/C/src/lib/Test.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor TestDouble(expected: double[] = {1.0, 1.0, 1.0, 1.0}) { input in: double state count: int = 0 diff --git a/test/C/src/modal_models/ConvertCaseTest.lf b/test/C/src/modal_models/ConvertCaseTest.lf index ca6323b148..f02d1dfe46 100644 --- a/test/C/src/modal_models/ConvertCaseTest.lf +++ b/test/C/src/modal_models/ConvertCaseTest.lf @@ -6,10 +6,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor ResetProcessor { input discard: bool input character: char @@ -54,9 +50,7 @@ reactor Converter { input raw: char output converted: int - preamble {= - #include - =} + preamble {= =} initial mode Upper { reaction(raw) -> converted, reset(Lower) {= diff --git a/test/C/src/modal_models/Count3Modes.lf b/test/C/src/modal_models/Count3Modes.lf index 5198888fad..862915abed 100644 --- a/test/C/src/modal_models/Count3Modes.lf +++ b/test/C/src/modal_models/Count3Modes.lf @@ -4,10 +4,6 @@ target C { timeout: 2 sec } -preamble {= - #include -=} - reactor CounterCycle { input next: bool output count: int diff --git a/test/C/src/modal_models/MixedReactions.lf b/test/C/src/modal_models/MixedReactions.lf index 3e1a698dcf..78ea39c95c 100644 --- a/test/C/src/modal_models/MixedReactions.lf +++ b/test/C/src/modal_models/MixedReactions.lf @@ -7,10 +7,6 @@ target C { timeout: 110 msec } -preamble {= - #include -=} - main reactor { state x: int = 0 state first: bool = true diff --git a/test/C/src/modal_models/ModalActions.lf b/test/C/src/modal_models/ModalActions.lf index d8bcfecbbf..e687d4bafd 100644 --- a/test/C/src/modal_models/ModalActions.lf +++ b/test/C/src/modal_models/ModalActions.lf @@ -9,10 +9,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalAfter.lf b/test/C/src/modal_models/ModalAfter.lf index 5535c8c1aa..f5cc8d229e 100644 --- a/test/C/src/modal_models/ModalAfter.lf +++ b/test/C/src/modal_models/ModalAfter.lf @@ -9,10 +9,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalCycleBreaker.lf b/test/C/src/modal_models/ModalCycleBreaker.lf index 1de6dc30f4..aae727b23d 100644 --- a/test/C/src/modal_models/ModalCycleBreaker.lf +++ b/test/C/src/modal_models/ModalCycleBreaker.lf @@ -11,10 +11,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input in1: int input in2: int diff --git a/test/C/src/modal_models/ModalNestedReactions.lf b/test/C/src/modal_models/ModalNestedReactions.lf index 583d51fb9b..454acbfc75 100644 --- a/test/C/src/modal_models/ModalNestedReactions.lf +++ b/test/C/src/modal_models/ModalNestedReactions.lf @@ -7,10 +7,6 @@ target C { timeout: 2 sec } -preamble {= - #include -=} - reactor CounterCycle { input next: bool diff --git a/test/C/src/modal_models/ModalStartupShutdown.lf b/test/C/src/modal_models/ModalStartupShutdown.lf index 6ef8ce6336..d39117882a 100644 --- a/test/C/src/modal_models/ModalStartupShutdown.lf +++ b/test/C/src/modal_models/ModalStartupShutdown.lf @@ -6,10 +6,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalStateReset.lf b/test/C/src/modal_models/ModalStateReset.lf index 45261641c6..c098f088d5 100644 --- a/test/C/src/modal_models/ModalStateReset.lf +++ b/test/C/src/modal_models/ModalStateReset.lf @@ -6,10 +6,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalStateResetAuto.lf b/test/C/src/modal_models/ModalStateResetAuto.lf index 02215bca09..a82fd18212 100644 --- a/test/C/src/modal_models/ModalStateResetAuto.lf +++ b/test/C/src/modal_models/ModalStateResetAuto.lf @@ -6,10 +6,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool diff --git a/test/C/src/modal_models/ModalTimers.lf b/test/C/src/modal_models/ModalTimers.lf index ac76940da9..954a677de4 100644 --- a/test/C/src/modal_models/ModalTimers.lf +++ b/test/C/src/modal_models/ModalTimers.lf @@ -6,10 +6,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool diff --git a/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf b/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf index f5790444f5..31de4fe6bd 100644 --- a/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf +++ b/test/C/src/modal_models/MultipleOutputFeeder_2Connections.lf @@ -11,10 +11,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool output count: int diff --git a/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf b/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf index 74a5e9541b..f89073dfc1 100644 --- a/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf +++ b/test/C/src/modal_models/MultipleOutputFeeder_ReactionConnections.lf @@ -11,10 +11,6 @@ target C { import TraceTesting from "util/TraceTesting.lf" -preamble {= - #include -=} - reactor Modal { input next: bool output count: int diff --git a/test/C/src/modal_models/util/TraceTesting.lf b/test/C/src/modal_models/util/TraceTesting.lf index 247b3f1def..c63de35f2a 100644 --- a/test/C/src/modal_models/util/TraceTesting.lf +++ b/test/C/src/modal_models/util/TraceTesting.lf @@ -1,10 +1,6 @@ /** Utility reactor to record and test execution traces. */ target C -preamble {= - #include -=} - reactor TraceTesting( events_size: int = 0, trace_size: int = 0, diff --git a/test/C/src/multiport/BankIndexInitializer.lf b/test/C/src/multiport/BankIndexInitializer.lf index b039f3a5bc..e6c52e8efe 100644 --- a/test/C/src/multiport/BankIndexInitializer.lf +++ b/test/C/src/multiport/BankIndexInitializer.lf @@ -1,10 +1,7 @@ // Test bank of reactors to multiport input with id parameter in the bank. target C -preamble {= - #include - extern int table[4]; -=} +preamble {= extern int table[4]; =} reactor Source(bank_index: int = 0, value: int = 0) { preamble {= int table[] = {4, 3, 2, 1}; =} diff --git a/test/C/src/multiport/BankToBank.lf b/test/C/src/multiport/BankToBank.lf index 69f7488da0..beb3a32fa8 100644 --- a/test/C/src/multiport/BankToBank.lf +++ b/test/C/src/multiport/BankToBank.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(bank_index: int = 0) { timer t(0, 200 msec) output out: int diff --git a/test/C/src/multiport/BankToBankMultiport.lf b/test/C/src/multiport/BankToBankMultiport.lf index 116ba683d1..681538f116 100644 --- a/test/C/src/multiport/BankToBankMultiport.lf +++ b/test/C/src/multiport/BankToBankMultiport.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 1) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/BankToBankMultiportAfter.lf b/test/C/src/multiport/BankToBankMultiportAfter.lf index 67cf2d56f7..db0ff7771e 100644 --- a/test/C/src/multiport/BankToBankMultiportAfter.lf +++ b/test/C/src/multiport/BankToBankMultiportAfter.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 1) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/BankToMultiport.lf b/test/C/src/multiport/BankToMultiport.lf index 5519dd817f..f72c104df7 100644 --- a/test/C/src/multiport/BankToMultiport.lf +++ b/test/C/src/multiport/BankToMultiport.lf @@ -1,10 +1,6 @@ // Test bank of reactors to multiport input with id parameter in the bank. target C -preamble {= - #include -=} - reactor Source(bank_index: int = 0) { output out: int diff --git a/test/C/src/multiport/Broadcast.lf b/test/C/src/multiport/Broadcast.lf index 116a2c4cc1..e3471da5f6 100644 --- a/test/C/src/multiport/Broadcast.lf +++ b/test/C/src/multiport/Broadcast.lf @@ -3,10 +3,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output out: int diff --git a/test/C/src/multiport/BroadcastAfter.lf b/test/C/src/multiport/BroadcastAfter.lf index 4073df0941..c1be635e55 100644 --- a/test/C/src/multiport/BroadcastAfter.lf +++ b/test/C/src/multiport/BroadcastAfter.lf @@ -3,10 +3,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output out: int diff --git a/test/C/src/multiport/BroadcastMultipleAfter.lf b/test/C/src/multiport/BroadcastMultipleAfter.lf index b316dd92fa..97d853e4ce 100644 --- a/test/C/src/multiport/BroadcastMultipleAfter.lf +++ b/test/C/src/multiport/BroadcastMultipleAfter.lf @@ -3,10 +3,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(value: int = 42) { output out: int diff --git a/test/C/src/multiport/DualBanks.lf b/test/C/src/multiport/DualBanks.lf index d7033744df..3cb5d38887 100644 --- a/test/C/src/multiport/DualBanks.lf +++ b/test/C/src/multiport/DualBanks.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Base(bank_index: int = 0) { input I: int state received: bool = false diff --git a/test/C/src/multiport/DualBanksMultiport.lf b/test/C/src/multiport/DualBanksMultiport.lf index 52bbcc7890..a5c2120a79 100644 --- a/test/C/src/multiport/DualBanksMultiport.lf +++ b/test/C/src/multiport/DualBanksMultiport.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Base(bank_index: int = 0) { input[2] I: int state received: bool = false diff --git a/test/C/src/multiport/FullyConnected.lf b/test/C/src/multiport/FullyConnected.lf index eb166585ea..758ecf1580 100644 --- a/test/C/src/multiport/FullyConnected.lf +++ b/test/C/src/multiport/FullyConnected.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Node(num_nodes: size_t = 4, bank_index: int = 0) { input[num_nodes] in: int output out: int diff --git a/test/C/src/multiport/FullyConnectedAddressable.lf b/test/C/src/multiport/FullyConnectedAddressable.lf index 8c6f9273af..fad86bce1b 100644 --- a/test/C/src/multiport/FullyConnectedAddressable.lf +++ b/test/C/src/multiport/FullyConnectedAddressable.lf @@ -1,10 +1,6 @@ // In this pattern, each node can send direct messages to individual other nodes target C -preamble {= - #include -=} - reactor Node(num_nodes: size_t = 4, bank_index: int = 4) { input[num_nodes] in: int output[num_nodes] out: int diff --git a/test/C/src/multiport/MultiportFromBank.lf b/test/C/src/multiport/MultiportFromBank.lf index 0ed6a0ff4c..1b49786060 100644 --- a/test/C/src/multiport/MultiportFromBank.lf +++ b/test/C/src/multiport/MultiportFromBank.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(check_override: int = 0, bank_index: int = 0) { output out: int diff --git a/test/C/src/multiport/MultiportFromHierarchy.lf b/test/C/src/multiport/MultiportFromHierarchy.lf index 2bf8cbccd8..8323210946 100644 --- a/test/C/src/multiport/MultiportFromHierarchy.lf +++ b/test/C/src/multiport/MultiportFromHierarchy.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 3) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportFromReaction.lf b/test/C/src/multiport/MultiportFromReaction.lf index 77fcf01e3f..33cbfffd83 100644 --- a/test/C/src/multiport/MultiportFromReaction.lf +++ b/test/C/src/multiport/MultiportFromReaction.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Destination(width: int = 1) { state s: int = 6 input[width] in: int diff --git a/test/C/src/multiport/MultiportIn.lf b/test/C/src/multiport/MultiportIn.lf index 33338793fe..b87a91a79b 100644 --- a/test/C/src/multiport/MultiportIn.lf +++ b/test/C/src/multiport/MultiportIn.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/multiport/MultiportInParameterized.lf b/test/C/src/multiport/MultiportInParameterized.lf index fd75393f42..bf7ec93f6e 100644 --- a/test/C/src/multiport/MultiportInParameterized.lf +++ b/test/C/src/multiport/MultiportInParameterized.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { timer t(0, 200 msec) output out: int diff --git a/test/C/src/multiport/MultiportMutableInputArray.lf b/test/C/src/multiport/MultiportMutableInputArray.lf index e62b33c372..90907e4f44 100644 --- a/test/C/src/multiport/MultiportMutableInputArray.lf +++ b/test/C/src/multiport/MultiportMutableInputArray.lf @@ -4,10 +4,6 @@ // Print. It gets freed after Print is done with it. target C -preamble {= - #include -=} - reactor Source { output[2] out: int[] diff --git a/test/C/src/multiport/MultiportOut.lf b/test/C/src/multiport/MultiportOut.lf index 60f72dc64d..38365d217a 100644 --- a/test/C/src/multiport/MultiportOut.lf +++ b/test/C/src/multiport/MultiportOut.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { timer t(0, 200 msec) output[4] out: int diff --git a/test/C/src/multiport/MultiportToBank.lf b/test/C/src/multiport/MultiportToBank.lf index da2fb8ab12..86146b9818 100644 --- a/test/C/src/multiport/MultiportToBank.lf +++ b/test/C/src/multiport/MultiportToBank.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 2) { output[width] out: int // Connected to a bank of Destination reactors input dummy: int // Not connected to anything diff --git a/test/C/src/multiport/MultiportToBankAfter.lf b/test/C/src/multiport/MultiportToBankAfter.lf index a05bb14657..ba26142243 100644 --- a/test/C/src/multiport/MultiportToBankAfter.lf +++ b/test/C/src/multiport/MultiportToBankAfter.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 2) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToBankDouble.lf b/test/C/src/multiport/MultiportToBankDouble.lf index ce35789605..444f02d170 100644 --- a/test/C/src/multiport/MultiportToBankDouble.lf +++ b/test/C/src/multiport/MultiportToBankDouble.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output[3] out: int // Connected to a bank of Destination reactors diff --git a/test/C/src/multiport/MultiportToBankHierarchy.lf b/test/C/src/multiport/MultiportToBankHierarchy.lf index 519a0fa0f6..fbdc531bf0 100644 --- a/test/C/src/multiport/MultiportToBankHierarchy.lf +++ b/test/C/src/multiport/MultiportToBankHierarchy.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 2) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToHierarchy.lf b/test/C/src/multiport/MultiportToHierarchy.lf index 1e6e93f074..41ca505077 100644 --- a/test/C/src/multiport/MultiportToHierarchy.lf +++ b/test/C/src/multiport/MultiportToHierarchy.lf @@ -6,10 +6,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 2) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiport.lf b/test/C/src/multiport/MultiportToMultiport.lf index 34cb37350d..375fa080e2 100644 --- a/test/C/src/multiport/MultiportToMultiport.lf +++ b/test/C/src/multiport/MultiportToMultiport.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 1) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiport2.lf b/test/C/src/multiport/MultiportToMultiport2.lf index 3844b9646f..76858a2a86 100644 --- a/test/C/src/multiport/MultiportToMultiport2.lf +++ b/test/C/src/multiport/MultiportToMultiport2.lf @@ -1,10 +1,6 @@ // Test multiport to multiport connections. See also MultiportToMultiport. target C -preamble {= - #include -=} - reactor Source(width: int = 2) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiport2After.lf b/test/C/src/multiport/MultiportToMultiport2After.lf index 2845896ad0..49585ea1b0 100644 --- a/test/C/src/multiport/MultiportToMultiport2After.lf +++ b/test/C/src/multiport/MultiportToMultiport2After.lf @@ -1,10 +1,6 @@ // Test multiport to multiport connections. See also MultiportToMultiport. target C -preamble {= - #include -=} - reactor Source(width: int = 2) { output[width] out: int diff --git a/test/C/src/multiport/MultiportToMultiportArray.lf b/test/C/src/multiport/MultiportToMultiportArray.lf index bd79a2643d..9d86a4a522 100644 --- a/test/C/src/multiport/MultiportToMultiportArray.lf +++ b/test/C/src/multiport/MultiportToMultiportArray.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { timer t(0, 200 msec) output[2] out: int[] diff --git a/test/C/src/multiport/MultiportToMultiportParameter.lf b/test/C/src/multiport/MultiportToMultiportParameter.lf index 8ead394524..d1c96e5ddd 100644 --- a/test/C/src/multiport/MultiportToMultiportParameter.lf +++ b/test/C/src/multiport/MultiportToMultiportParameter.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 1) { timer t(0, 200 msec) output[width] out: int diff --git a/test/C/src/multiport/MultiportToPort.lf b/test/C/src/multiport/MultiportToPort.lf index a820a6c51d..1784f2503c 100644 --- a/test/C/src/multiport/MultiportToPort.lf +++ b/test/C/src/multiport/MultiportToPort.lf @@ -5,10 +5,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output[2] out: int diff --git a/test/C/src/multiport/MultiportToReaction.lf b/test/C/src/multiport/MultiportToReaction.lf index 96d2f22082..9281633079 100644 --- a/test/C/src/multiport/MultiportToReaction.lf +++ b/test/C/src/multiport/MultiportToReaction.lf @@ -4,10 +4,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source(width: int = 1) { timer t(0, 200 msec) state s: int = 0 diff --git a/test/C/src/multiport/PipelineAfter.lf b/test/C/src/multiport/PipelineAfter.lf index a32973a65c..a9f9085873 100644 --- a/test/C/src/multiport/PipelineAfter.lf +++ b/test/C/src/multiport/PipelineAfter.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor Source { output out: unsigned diff --git a/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf b/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf index 1fcc162785..917982af39 100644 --- a/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf +++ b/test/C/src/multiport/TriggerDownstreamOnlyIfPresent.lf @@ -7,10 +7,6 @@ target C { fast: true } -preamble {= - #include -=} - reactor Source { output a: int output b: int diff --git a/test/C/src/no_inlining/Count.lf b/test/C/src/no_inlining/Count.lf index 009af57489..f8fd51bec7 100644 --- a/test/C/src/no_inlining/Count.lf +++ b/test/C/src/no_inlining/Count.lf @@ -3,10 +3,6 @@ target C { files: ["../../c"] } -preamble {= - #include -=} - main reactor Count { timer t(0, 1 msec) diff --git a/test/C/src/no_inlining/CountHierarchy.lf b/test/C/src/no_inlining/CountHierarchy.lf index 8981cf1b15..771222af2f 100644 --- a/test/C/src/no_inlining/CountHierarchy.lf +++ b/test/C/src/no_inlining/CountHierarchy.lf @@ -3,10 +3,6 @@ target C { files: ["../../c"] } -preamble {= - #include -=} - reactor Timer(m: time = 0, n: time = 0) { output out: int timer t(m, n) diff --git a/test/C/src/no_inlining/MultiportToReactionNoInlining.lf b/test/C/src/no_inlining/MultiportToReactionNoInlining.lf index 2ed1e14483..3c5f18d62a 100644 --- a/test/C/src/no_inlining/MultiportToReactionNoInlining.lf +++ b/test/C/src/no_inlining/MultiportToReactionNoInlining.lf @@ -6,10 +6,6 @@ target C { files: ["../../c"] } -preamble {= - #include -=} - reactor Source(width: int = 1) { timer t(0, 200 msec) state s: int = 0 diff --git a/test/C/src/serialization/PersonProtocolBuffers.lf b/test/C/src/serialization/PersonProtocolBuffers.lf index 6e12989a46..a01243d846 100644 --- a/test/C/src/serialization/PersonProtocolBuffers.lf +++ b/test/C/src/serialization/PersonProtocolBuffers.lf @@ -23,10 +23,6 @@ target C { protobufs: Person.proto } -preamble {= - #include -=} - main reactor { reaction(startup) {= Person person = PERSON__INIT; // Macro to create the protocol buffer diff --git a/test/C/src/serialization/ProtoNoPacking.lf b/test/C/src/serialization/ProtoNoPacking.lf index 2929a67f6a..283e4feafb 100644 --- a/test/C/src/serialization/ProtoNoPacking.lf +++ b/test/C/src/serialization/ProtoNoPacking.lf @@ -22,10 +22,6 @@ target C { protobufs: [ProtoHelloWorld.proto] } -preamble {= - #include -=} - reactor SourceProto { output out: ProtoHelloWorld diff --git a/test/C/src/target/HelloWorldCCPP.lf b/test/C/src/target/HelloWorldCCPP.lf index 73f747c94a..91d1cd61d1 100644 --- a/test/C/src/target/HelloWorldCCPP.lf +++ b/test/C/src/target/HelloWorldCCPP.lf @@ -7,10 +7,6 @@ target CCpp { logging: DEBUG } -preamble {= - #include -=} - reactor HelloWorld { preamble {= #include diff --git a/test/C/src/token/TokenContainedSource.lf b/test/C/src/token/TokenContainedSource.lf index 6a2695519d..66095b8a0b 100644 --- a/test/C/src/token/TokenContainedSource.lf +++ b/test/C/src/token/TokenContainedSource.lf @@ -9,10 +9,6 @@ target C { import TokenSource from "lib/Token.lf" -preamble {= - #include -=} - main reactor(scale: int = 1) { state count: int = 0 state input_received: bool = false diff --git a/test/C/src/token/TokenContainedSourceBank.lf b/test/C/src/token/TokenContainedSourceBank.lf index baa469d0eb..615695890b 100644 --- a/test/C/src/token/TokenContainedSourceBank.lf +++ b/test/C/src/token/TokenContainedSourceBank.lf @@ -10,10 +10,6 @@ target C { import TokenSource from "lib/Token.lf" -preamble {= - #include -=} - main reactor(scale: int = 1) { state count: int = 0 state input_received: bool = false diff --git a/test/C/src/token/lib/Token.lf b/test/C/src/token/lib/Token.lf index 82e41c4cbc..7b8d2a83ee 100644 --- a/test/C/src/token/lib/Token.lf +++ b/test/C/src/token/lib/Token.lf @@ -8,7 +8,6 @@ target C { } preamble {= - #include #include "array.h" =} diff --git a/test/C/src/zephyr/HelloZephyr.lf b/test/C/src/zephyr/HelloZephyr.lf index 0768fcaa4d..2c4a98890f 100644 --- a/test/C/src/zephyr/HelloZephyr.lf +++ b/test/C/src/zephyr/HelloZephyr.lf @@ -6,10 +6,6 @@ target C { } } -preamble {= - #include -=} - main reactor { reaction(startup) {= printf("Hello World!\n"); =} } diff --git a/test/C/src/zephyr/Timer.lf b/test/C/src/zephyr/Timer.lf index ae426361bd..cac30ae9b1 100644 --- a/test/C/src/zephyr/Timer.lf +++ b/test/C/src/zephyr/Timer.lf @@ -6,10 +6,6 @@ target C { threading: false } -preamble {= - #include -=} - main reactor { timer t(0, 1 sec) diff --git a/test/C/src/zephyr/lib/Led.lf b/test/C/src/zephyr/lib/Led.lf index c006f35aad..04999cf14b 100644 --- a/test/C/src/zephyr/lib/Led.lf +++ b/test/C/src/zephyr/lib/Led.lf @@ -1,9 +1,5 @@ target C -preamble {= - #include -=} - reactor NrfLeds { preamble {= #include From 8a71df5c76f2963f86331863d0ca427945038b5b Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 31 Mar 2023 13:39:59 -0700 Subject: [PATCH 86/92] Update submodule. --- org.lflang/src/lib/c/reactor-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index 9eb95b0559..d008e46913 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit 9eb95b0559fc30d192790fd13af1891ccbf57746 +Subproject commit d008e46913b46d359e965aa9f866e1bebf975bf1 From 0bcbf621f2dde60cf06990332bc7173f84da2668 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 31 Mar 2023 15:05:49 -0700 Subject: [PATCH 87/92] Revert moving instant_t typedef --- org.lflang/src/lib/c/reactor-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index d008e46913..ac05b8ebc8 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit d008e46913b46d359e965aa9f866e1bebf975bf1 +Subproject commit ac05b8ebc8aec4d5596ade92e39429846af51d45 From a30e655f16dc6132112354e2f24d6d1b6ee6b1cb Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 31 Mar 2023 21:00:25 -0700 Subject: [PATCH 88/92] Try to pass unit tests. The error gets reported with an unexpected line number (not even in the right file) when a mistake is inserted into the type for the list of time values. I do not want to fix this right now (honestly it is the C++ compiler's fault, I do not even know how we would fix this), so instead I will try to cover it up. --- .../org/lflang/tests/compiler/LinguaFrancaValidationTest.java | 4 ++-- test/Cpp/src/NativeListsAndTimes.lf | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java index 67df93ed30..c5ead40cb7 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java @@ -1795,7 +1795,7 @@ public void testMissingModeStateResetInstance() throws Exception { String testCase = """ target C; reactor R { - state s:int(0); + state s:int = 0; } main reactor { initial mode IM { @@ -1836,7 +1836,7 @@ public void testUnspecifiedTransitionType() throws Exception { reaction(startup) -> M {==} } mode M { - reset state s:int(0); + reset state s:int = 0; } } """; diff --git a/test/Cpp/src/NativeListsAndTimes.lf b/test/Cpp/src/NativeListsAndTimes.lf index 5bf67c8fb4..f9ddfa4bd7 100644 --- a/test/Cpp/src/NativeListsAndTimes.lf +++ b/test/Cpp/src/NativeListsAndTimes.lf @@ -6,9 +6,7 @@ reactor Foo( y: time = 0, // Units are missing but not required z = 1 msec, // Type is missing but not required p: int[]{1, 2, 3, 4}, // List of integers - q: {= // list of time values - std::vector - =}{1 msec, 2 msec, 3 msec}, + q: {= std::vector =}{1 msec, 2 msec, 3 msec}, g: time[]{1 msec, 2 msec}, // List of time values g2: int[] = {} ) { From cc423c4ee5f4b05273b82c200dbccb8d2ca4efcf Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 4 Apr 2023 23:27:55 -0700 Subject: [PATCH 89/92] Revert changes in unit tests. I do not know how I accidentally put these changes here but anyway they were wrong and are the reason why the unit tests have been failing. --- .../org/lflang/tests/compiler/LinguaFrancaValidationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java index c5ead40cb7..67df93ed30 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java @@ -1795,7 +1795,7 @@ public void testMissingModeStateResetInstance() throws Exception { String testCase = """ target C; reactor R { - state s:int = 0; + state s:int(0); } main reactor { initial mode IM { @@ -1836,7 +1836,7 @@ public void testUnspecifiedTransitionType() throws Exception { reaction(startup) -> M {==} } mode M { - reset state s:int = 0; + reset state s:int(0); } } """; From c1d75e8ed71fde5827807e9882549881f86bd221 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Thu, 6 Apr 2023 09:49:31 -0700 Subject: [PATCH 90/92] Pass unit tests. The unit tests were failing for a while because a few typos were corrected in the validator but not in the validation tests. --- .../tests/compiler/LinguaFrancaValidationTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java index 67df93ed30..2820eda935 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/LinguaFrancaValidationTest.java @@ -1150,7 +1150,7 @@ private List synthesizeExamples(UnionType type, boolean correct) { */ private List synthesizeExamples(DictionaryType type, boolean correct) { List examples = new LinkedList<>(); - // Produce a set of singleton dictionaries. + // Produce a set of singleton dictionaries. // If incorrect examples are wanted, garble the key. for (DictionaryElement option : type.options) { synthesizeExamples(option.getType(), correct).forEach(it -> examples.add( @@ -1629,7 +1629,7 @@ public void testMainReactorHasHost() throws Exception { """; // TODO: Uncomment and fix test // List issues = validator.validate(parseWithoutError(testCase)); - // Assertions.assertTrue(issues.size() == 1 && + // Assertions.assertTrue(issues.size() == 1 && // issues.get(0).getMessage().contains("Cannot assign a host to reactor '") && // issues.get(0).getMessage().contains("' because it is not federated.")); } @@ -1810,7 +1810,7 @@ public void testMissingModeStateResetInstance() throws Exception { "This reactor contains state variables that are not reset upon mode entry: " + "s in R" + ".\nThe state variables are neither marked for automatic reset nor have a dedicated reset reaction. " - + "It is usafe to instatiate this reactor inside a mode entered with reset."); + + "It is unsafe to instantiate this reactor inside a mode entered with reset."); } @Test @@ -1841,11 +1841,9 @@ public void testUnspecifiedTransitionType() throws Exception { } """; validator.assertWarning(parseWithoutError(testCase), LfPackage.eINSTANCE.getReaction(), null, - "You should specifiy a transition type! " + "You should specify a transition type! " + "Reset and history transitions have different effects on this target mode. " + "Currently, a reset type is implicitly assumed."); } } - - From d452c97972f0263979d0c29e2c433e7d4ab56473 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Fri, 7 Apr 2023 17:15:13 -0700 Subject: [PATCH 91/92] Address comments from code review. --- .../src/org/lflang/generator/c/CReactionGenerator.java | 2 +- test/C/src/federated/DistributedMultiportToken.lf | 9 --------- test/C/src/modal_models/ConvertCaseTest.lf | 2 -- test/C/src/multiport/FullyConnectedAddressable.lf | 2 +- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java index ae91aac32b..100f3deaa4 100644 --- a/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java +++ b/org.lflang/src/org/lflang/generator/c/CReactionGenerator.java @@ -38,7 +38,7 @@ public class CReactionGenerator { protected static String DISABLE_REACTION_INITIALIZATION_MARKER - = "// **** Do not include initialization code in this reaction."; // FIXME: Such markers should not exist + = "// **** Do not include initialization code in this reaction."; // FIXME: Such markers should not exist (#1687) /** * Generate necessary initialization code inside the body of the reaction that belongs to reactor decl. diff --git a/test/C/src/federated/DistributedMultiportToken.lf b/test/C/src/federated/DistributedMultiportToken.lf index 28efad56af..dfb791d861 100644 --- a/test/C/src/federated/DistributedMultiportToken.lf +++ b/test/C/src/federated/DistributedMultiportToken.lf @@ -5,15 +5,6 @@ target C { coordination: centralized } -preamble {= - #ifdef __cplusplus - extern "C" { - #endif - #ifdef __cplusplus - } - #endif -=} - reactor Source { output[4] out: char* timer t(0, 200 msec) diff --git a/test/C/src/modal_models/ConvertCaseTest.lf b/test/C/src/modal_models/ConvertCaseTest.lf index f02d1dfe46..3f644eb133 100644 --- a/test/C/src/modal_models/ConvertCaseTest.lf +++ b/test/C/src/modal_models/ConvertCaseTest.lf @@ -50,8 +50,6 @@ reactor Converter { input raw: char output converted: int - preamble {= =} - initial mode Upper { reaction(raw) -> converted, reset(Lower) {= char c = raw->value; diff --git a/test/C/src/multiport/FullyConnectedAddressable.lf b/test/C/src/multiport/FullyConnectedAddressable.lf index fad86bce1b..91b0f5caac 100644 --- a/test/C/src/multiport/FullyConnectedAddressable.lf +++ b/test/C/src/multiport/FullyConnectedAddressable.lf @@ -1,7 +1,7 @@ // In this pattern, each node can send direct messages to individual other nodes target C -reactor Node(num_nodes: size_t = 4, bank_index: int = 4) { +reactor Node(num_nodes: size_t = 4, bank_index: int = 0) { input[num_nodes] in: int output[num_nodes] out: int From ec024332f6b6eccab40aa3d39f3ac7e14762890f Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 12 Apr 2023 14:35:47 -0700 Subject: [PATCH 92/92] Address CLI test failure. --- .../org/lflang/tests/cli/issue490.stderr | 24 ++++++++----------- org.lflang/src/lib/c/reactor-c | 2 +- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/org.lflang.tests/resources/org/lflang/tests/cli/issue490.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/issue490.stderr index edf3254755..fdaa4f8e0e 100644 --- a/org.lflang.tests/resources/org/lflang/tests/cli/issue490.stderr +++ b/org.lflang.tests/resources/org/lflang/tests/cli/issue490.stderr @@ -6,23 +6,19 @@ lfc: error: Name of main reactor must match the file name (or be omitted). | ^ Name of main reactor must match the file name (or be omitted). | 5 | state liss(2, 3); - -lfc: error: missing '{=' at '{' +lfc: error: no viable alternative at input '{' --> %%%PATH.lf%%%:6:22 | 5 | state liss(2, 3); 6 | reaction (startup) { - | ^ missing '{=' at '{' + | ^ no viable alternative at input '{' | 7 | print(self.liss) - -lfc: error: mismatched input '' expecting '=}' - --> %%%PATH.lf%%%:9:2 - | - 8 | } - | >>>>>>>>>>>>>> - 9 | } -10 | - | < mismatched input '' expecting '=}' -11 | - +lfc: error: no viable alternative at input '(' +--> %%%PATH.lf%%%:7:5 + | +6 | reaction (startup) { +7 | print(self.liss) + | ^^^^^ no viable alternative at input '(' + | +8 | } diff --git a/org.lflang/src/lib/c/reactor-c b/org.lflang/src/lib/c/reactor-c index ac05b8ebc8..667a5d702c 160000 --- a/org.lflang/src/lib/c/reactor-c +++ b/org.lflang/src/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit ac05b8ebc8aec4d5596ade92e39429846af51d45 +Subproject commit 667a5d702cbcd0288328417d8c632e6b5af19c04