From 8d430c39361608c31245dda0dda3b78e232d9b43 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Fri, 6 Dec 2024 16:32:47 -0800 Subject: [PATCH 1/6] Add preliminary support for bodyless reactions --- examples/zephyr/hello_lf/CMakeLists.txt | 2 +- .../generator/uc/UcReactionGenerator.kt | 136 +++++++++++++++--- .../lflang/generator/uc/UcReactorGenerator.kt | 2 + test/lf/src/Bodiless.lf | 9 ++ test/lf/src/lib/bodiless.c | 5 + test/lf/src/lib/bodiless.cmake | 1 + 6 files changed, 132 insertions(+), 23 deletions(-) create mode 100644 test/lf/src/Bodiless.lf create mode 100644 test/lf/src/lib/bodiless.c create mode 100644 test/lf/src/lib/bodiless.cmake diff --git a/examples/zephyr/hello_lf/CMakeLists.txt b/examples/zephyr/hello_lf/CMakeLists.txt index 0fba35c1..5d829ebf 100644 --- a/examples/zephyr/hello_lf/CMakeLists.txt +++ b/examples/zephyr/hello_lf/CMakeLists.txt @@ -6,6 +6,6 @@ set(PLATFORM "ZEPHYR" CACHE STRING "Set platform to Zephyr") include(src-gen/HelloLF/CMakeLists.txt) add_subdirectory(${REACTOR_UC_PATH}) -target_sources(app PRIVATE main.c ${LF_SOURCES}) +target_sources(app PRIVATE main.c ${LFC_GEN_SOURCES}) target_link_libraries(app PRIVATE reactor-uc) target_include_directories(app PRIVATE ${LF_INCLUDE_DIRS}) diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt index 9d3a853c..fff67871 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt @@ -24,25 +24,26 @@ class UcReactionGenerator(private val reactor: Reactor) { return idx } - - private val Reaction.ctorDeadlineArg get() = if (deadline != null) ", ${deadline.delay.toCCode()}" else "" - + private val Reaction.innerBodyName + get() = "${reactor.codeType}_${codeName}" + private val Reaction.innerDeadlineHandlerName + get() = "${reactor.codeType}_${codeName}_deadline_handler" private val Reaction.allUncontainedTriggers get() = triggers.filterNot { it.isEffectOf(this) || it.isContainedRef } private val Reaction.allUncontainedEffects get() = effects.filterNot { it.isContainedRef } private val Reaction.allUncontainedSources get() = sources.filterNot { it.isContainedRef } - private val Reaction.allContainedEffects get() = effects.filter { it.isContainedRef } private val Reaction.allContainedTriggers get() = triggers.filter { !it.isEffectOf(this) && it.isContainedRef } private val Reaction.allContainedSources get() = sources.filter { !it.isEffectOf(this) && it.isContainedRef } - + private val Reaction.allVariableReferences get() = (effects + sources + triggers.mapNotNull { it as? VarRef }).distinct() + private val Reaction.allReferencedContainers get() = allVariableReferences.mapNotNull { it.container }.distinct() private val reactionsWithDeadline = reactor.allReactions.filter {it.deadline != null} // Calculate the total number of effects, considering that we might write to @@ -79,6 +80,33 @@ class UcReactionGenerator(private val reactor: Reactor) { private fun TriggerRef.isEffectOf(reaction: Reaction): Boolean = this is VarRef && isEffectOf(reaction) + private fun Reaction.getInnerParameters(): List = + allUncontainedTriggers.map { + "const ${it.codeType} *${it.name} ${if (it is Input && it.isMultiport) ", size_t ${it.name}_width" else ""}" + } + allUncontainedSources.map { + "const ${it.codeType} *${it.name} ${if (it is Input && it.isMultiport) ", size_t ${it.name}_width" else ""}" + } + allUncontainedEffects.map { + "${it.codeType} *${it.name} ${if (it is Output && it.isMultiport) ", size_t ${it.name}_width" else ""}" + } + allReferencedContainers.map { + "${getContainedStructName(this, it)} ${it.name} ${if (it.isBank) ", size_t ${it.name}_width" else ""}" + } + + private val TriggerRef.codeType + get() = when { + this is BuiltinTriggerRef && this.type == BuiltinTrigger.STARTUP -> "${reactor.codeType}_Startup" + this is BuiltinTriggerRef && this.type == BuiltinTrigger.SHUTDOWN -> "${reactor.codeType}_Shutdown" + this is VarRef -> codeType + else -> AssertionError("Unexpected trigger type") + } + + private val VarRef.codeType + get() = + when (val variable = this.variable) { + is Timer -> "${reactor.codeType}_Timer" + is Action -> "${reactor.codeType}_Action" + is Port -> "${reactor.codeType}_Port" + else -> throw AssertionError("Unexpected variable type") + } private val TriggerRef.scope get() = when { this is BuiltinTriggerRef && this.type == BuiltinTrigger.STARTUP -> "LF_SCOPE_STARTUP(${reactor.codeType});" @@ -110,6 +138,9 @@ class UcReactionGenerator(private val reactor: Reactor) { reaction.effects.any { name == it.name && container?.name == it.container?.name } + private fun getContainedStructName(reaction: Reaction, inst: Instantiation) = + "${reactor.codeType}_${reaction.codeName}_${inst.name}" + private fun registerPortSource(varRef: VarRef, port: Port, reaction: Reaction) = if (varRef.container != null) { (0..(varRef.container.width-1)).toList().joinToString(separator = "\n") { @@ -201,6 +232,39 @@ class UcReactionGenerator(private val reactor: Reactor) { postfix = "\n" ) { generateReactionBody(it) } + fun generateReactionInnerBodyDeclarations() = + reactor.allReactions.joinToString( + separator = "\n", + prefix = "// Reaction inner bodies\n", + postfix = "\n" + ) { "${generateReactionInnerBodyDeclaration(it)};" } + + fun generateReactionInnerArgumentStructs() = + reactor.allReactions.joinToString( + separator = "\n", + prefix = "// Contained reactor argument structs\n", + postfix = "\n" + ) { + generateReactionInnerArgumentStructs(it) + } + + fun generateReactionInnerArgumentStructs(reaction: Reaction) = + reaction.allContainedEffectsTriggersAndSources.toList() + .joinToString(separator = "\n") { + if (it.first.width > 1) { + generateContainedBankStructDeclaration(reaction, it.second, it.first) + } else { + generateContainedReactorStructDeclaration(reaction, it.second, it.first) + } + } + + fun generateReactionInnerBodies() = + reactor.allReactions.joinToString( + separator = "\n", + prefix = "// Reaction inner bodies\n", + postfix = "\n" + ) { generateReactionInnerBodyDefinition(it) } + fun generateReactionDeadlineHandlers() = reactionsWithDeadline.joinToString( separator = "\n", @@ -217,6 +281,35 @@ class UcReactionGenerator(private val reactor: Reactor) { """.trimMargin() } + private fun generateReactionInnerBodyDeclaration(reaction: Reaction) = with(PrependOperator) { + "void ${reaction.innerBodyName}(${reactor.codeType} *self, Environment *env ${reaction.getInnerParameters().joinToString(prefix = ",")})" + } + + private fun generateReactionInnerBodyDefinition(reaction: Reaction): String { + if (reaction.code == null) return "" + + with(PrependOperator) { + return """| + |${generateReactionInnerBodyDeclaration(reaction)} { + | // User written reaction body + ${"| "..reaction.code.toText()} + |} + """.trimMargin() + } + } + + private fun generateReactionInnerBodyCall(reaction: Reaction): String { + with(reaction) { + val parameters = allUncontainedTriggers.map { "${it.name} ${if (it is Input && it.isMultiport) ", ${it.name}_width" else ""}"} + + allUncontainedSources.map { "${it.name} ${if (it is Input && it.isMultiport) ", ${it.name}_width" else ""}"} + + allUncontainedEffects.map { "${it.name} ${if (it is Output && it.isMultiport) ", ${it.name}_width" else ""}"} + + allReferencedContainers.map { + "${it.name} ${if (it.isBank) ", ${it.name}_width" else ""}" + } + return "${innerBodyName}(self, env ${parameters.joinToString(prefix = ",")});" + } + } + private fun generateReactionDeadlineHandler(reaction: Reaction) = with(PrependOperator) { """ |LF_DEFINE_REACTION_DEADLINE_HANDLER(${reactor.codeType}, ${reaction.codeName}) { @@ -231,8 +324,8 @@ class UcReactionGenerator(private val reactor: Reactor) { """ |LF_DEFINE_REACTION_BODY(${reactor.codeType}, ${reaction.codeName}) { ${"| "..generateReactionScope(reaction)} - | // Start of user-witten reaction deadline handler - ${"| "..reaction.code.toText()} + | // Call reaction inner body + ${"| "..generateReactionInnerBodyCall(reaction)} |} """.trimMargin() } @@ -253,7 +346,6 @@ class UcReactionGenerator(private val reactor: Reactor) { """.trimMargin() } - private fun generateContainedTriggerFieldInit(instName: String, trigger: VarRef) = if (trigger.variable.isMultiport) { generateContainedMultiportTriggerFieldInit(instName, "&self->${trigger.container.name}[0]", trigger, trigger.variable as Port) @@ -268,25 +360,25 @@ class UcReactionGenerator(private val reactor: Reactor) { "${instName}[i].${trigger.name} = &self->${trigger.container.name}[i].${trigger.name};" } - // FIXME: This must also consider multiports and banks - private fun generateContainedReactorScope(triggers: List, inst: Instantiation) = with(PrependOperator) { + private fun generateContainedReactorDefinition(reaction: Reaction, triggers: List, inst: Instantiation) = with(PrependOperator) { """| |// Generated struct providing access to ports of child reactor `${inst.name}` - |struct _${inst.reactor.codeType}_${inst.name} { + |typedef struct { ${"| "..triggers.joinToString(separator = "\n") { generateContainedTriggerInScope(it) }} - |}; - |struct _${inst.reactor.codeType}_${inst.name} ${inst.name}; - ${"|"..triggers.joinToString(separator = "\n") {generateContainedTriggerFieldInit("${inst.name}", it)}} + |} ${getContainedStructName(reaction, inst)}; """.trimMargin() } - private fun generateContainedBankScope(triggers: List, inst: Instantiation) = with(PrependOperator) { + private fun generateContainedReactorStructDeclaration(reaction: Reaction, triggers: List, inst: Instantiation) = with(PrependOperator) { """| - |// Generated struct providing access to ports of child reactor `${inst.name}` - |struct _${inst.reactor.codeType}_${inst.name} { - ${"| "..triggers.joinToString { generateContainedTriggerInScope(it) }} - |}; - |struct _${inst.reactor.codeType}_${inst.name} ${inst.name}[${inst.width}]; + | ${getContainedStructName(reaction, inst)} ${inst.name}; + ${"|"..triggers.joinToString(separator = "\n") {generateContainedTriggerFieldInit("${inst.name}", it)}} + """.trimMargin() + } + + private fun generateContainedBankStructDeclaration(reaction: Reaction, triggers: List, inst: Instantiation) = with(PrependOperator) { + """ + |${getContainedStructName(reaction, inst)} ${inst.name}[${inst.width}]; |size_t ${inst.name}_width = ${inst.width}; |for (int i = 0; i<${inst.width}; i++) { ${"| "..triggers.joinToString(separator = "\n") {generateContainedBankTriggerFieldInit( "${inst.name}", it)}} @@ -302,9 +394,9 @@ class UcReactionGenerator(private val reactor: Reactor) { reaction.allContainedEffectsTriggersAndSources.toList() .joinToString(separator = "\n") { if (it.first.width > 1) { - generateContainedBankScope(it.second, it.first) + generateContainedBankStructDeclaration(reaction, it.second, it.first) } else { - generateContainedReactorScope(it.second, it.first) + generateContainedReactorStructDeclaration(reaction, it.second, it.first) } } diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt index 58186f52..2bd6f628 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt @@ -154,6 +154,7 @@ class UcReactorGenerator(private val reactor: Reactor, private val fileConfig: U | ${" |"..instances.generateIncludes()} ${" |"..reactions.generateSelfStructs()} + ${" |"..reactions.generateReactionInnerArgumentStructs()} ${" |"..timers.generateSelfStructs()} ${" |"..actions.generateSelfStructs()} ${" |"..ports.generateSelfStructs()} @@ -162,6 +163,7 @@ class UcReactorGenerator(private val reactor: Reactor, private val fileConfig: U ${" |"..generateReactorStruct()} | |${generateReactorCtorSignature()}; + ${" |"..reactions.generateReactionInnerBodyDeclarations()} | |#endif // ${reactor.includeGuard} """.trimMargin() diff --git a/test/lf/src/Bodiless.lf b/test/lf/src/Bodiless.lf new file mode 100644 index 00000000..2332f6bf --- /dev/null +++ b/test/lf/src/Bodiless.lf @@ -0,0 +1,9 @@ +target uC { + platform: Native, + cmake-include: "./lib/bodiless.cmake", +} + + +main reactor { + reaction hello(startup) +} \ No newline at end of file diff --git a/test/lf/src/lib/bodiless.c b/test/lf/src/lib/bodiless.c new file mode 100644 index 00000000..5daa32d1 --- /dev/null +++ b/test/lf/src/lib/bodiless.c @@ -0,0 +1,5 @@ +#include "Bodiless/Bodiless.h" + +void Reactor_Bodiless_hello(Reactor_Bodiless *self, Environment *env, const Reactor_Bodiless_Startup *startup) { + printf("Hello, World!\n"); +} \ No newline at end of file diff --git a/test/lf/src/lib/bodiless.cmake b/test/lf/src/lib/bodiless.cmake new file mode 100644 index 00000000..930c4de7 --- /dev/null +++ b/test/lf/src/lib/bodiless.cmake @@ -0,0 +1 @@ +target_sources(${LF_MAIN_TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/bodiless.c) \ No newline at end of file From 295a62803f4fd515a3fd579e02716180566b6aee Mon Sep 17 00:00:00 2001 From: erlingrj Date: Fri, 6 Dec 2024 18:27:51 -0800 Subject: [PATCH 2/6] Fixes --- include/reactor-uc/macros.h | 28 +++++-- .../generator/uc/UcReactionGenerator.kt | 77 ++++++++++++------- .../lflang/generator/uc/UcReactorGenerator.kt | 1 + test/lf/src/{Bodiless.lf => Bodyless.lf} | 2 +- test/lf/src/lib/{bodiless.c => bodyless.c} | 0 .../lib/{bodiless.cmake => bodyless.cmake} | 2 +- 6 files changed, 75 insertions(+), 35 deletions(-) rename test/lf/src/{Bodiless.lf => Bodyless.lf} (65%) rename test/lf/src/lib/{bodiless.c => bodyless.c} (100%) rename test/lf/src/lib/{bodiless.cmake => bodyless.cmake} (82%) diff --git a/include/reactor-uc/macros.h b/include/reactor-uc/macros.h index 2ca83b78..bb10448c 100644 --- a/include/reactor-uc/macros.h +++ b/include/reactor-uc/macros.h @@ -397,19 +397,27 @@ self->_triggers[_triggers_idx++] = (Trigger *)&self->ActionName; \ ReactorName##_##ActionName##_ctor(&self->ActionName, &self->super, MinDelay) -#define LF_SCOPE_ACTION(ReactorName, ActionName) \ +#define LF_SCOPE_ACTION_TRIGGER(ReactorName, ActionName) \ + const ReactorName##_##ActionName *ActionName = &self->ActionName; \ + (void)ActionName; + +#define LF_SCOPE_ACTION_EFFECT(ReactorName, ActionName) \ ReactorName##_##ActionName *ActionName = &self->ActionName; \ (void)ActionName; #define LF_SCOPE_TIMER(ReactorName, TimerName) \ - ReactorName##_##TimerName *TimerName = &self->TimerName; \ + const ReactorName##_##TimerName *TimerName = &self->TimerName; \ (void)TimerName; -#define LF_SCOPE_PORT(ReactorName, PortName) \ +#define LF_SCOPE_PORT_TRIGGER(ReactorName, PortName) \ + const ReactorName##_##PortName *PortName = &self->PortName[0]; \ + (void)PortName; + +#define LF_SCOPE_PORT_EFFECT(ReactorName, PortName) \ ReactorName##_##PortName *PortName = &self->PortName[0]; \ (void)PortName; -#define LF_SCOPE_MULTIPORT(ReactorName, PortName) \ +#define LF_SCOPE_MULTIPORT_EFFECT(ReactorName, PortName) \ size_t PortName##_width = sizeof(self->PortName) / sizeof(self->PortName[0]); \ ReactorName##_##PortName *PortName[PortName##_width]; \ for (int i = 0; i < PortName##_width; i++) { \ @@ -417,6 +425,14 @@ } \ (void)PortName; +#define LF_SCOPE_MULTIPORT_TRIGGER(ReactorName, PortName) \ + size_t PortName##_width = sizeof(self->PortName) / sizeof(self->PortName[0]); \ + const ReactorName##_##PortName *PortName[PortName##_width]; \ + for (int i = 0; i < PortName##_width; i++) { \ + PortName[i] = &self->PortName[i]; \ + } \ + (void)PortName; + #define LF_SCOPE_SELF(ReactorName) \ ReactorName *self = (ReactorName *)_self->parent; \ (void)self; @@ -426,11 +442,11 @@ (void)env; #define LF_SCOPE_STARTUP(ReactorName) \ - ReactorName##_Startup *startup = &self->startup; \ + const ReactorName##_Startup *startup = &self->startup; \ (void)startup; #define LF_SCOPE_SHUTDOWN(ReactorName) \ - ReactorName##_Shutdown *shutdown = &self->shutdown; \ + const ReactorName##_Shutdown *shutdown = &self->shutdown; \ (void)shutdown; #define LF_DEFINE_LOGICAL_CONNECTION_STRUCT(ParentName, ConnName, DownstreamSize) \ diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt index fff67871..d2cb6a5a 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactionGenerator.kt @@ -82,13 +82,29 @@ class UcReactionGenerator(private val reactor: Reactor) { private fun Reaction.getInnerParameters(): List = allUncontainedTriggers.map { - "const ${it.codeType} *${it.name} ${if (it is Input && it.isMultiport) ", size_t ${it.name}_width" else ""}" + if (it is VarRef && it.variable is Port && it.variable.isMultiport) { + "const ${it.codeType} *${it.name}[], size_t ${it.name}_width" + } else { + "const ${it.codeType} *${it.name}" + } } + allUncontainedSources.map { - "const ${it.codeType} *${it.name} ${if (it is Input && it.isMultiport) ", size_t ${it.name}_width" else ""}" + if (it.variable is Port && it.variable.isMultiport) { + "const ${it.codeType} *${it.name}[], size_t ${it.name}_width" + } else { + "const ${it.codeType} *${it.name}" + } } + allUncontainedEffects.map { - "${it.codeType} *${it.name} ${if (it is Output && it.isMultiport) ", size_t ${it.name}_width" else ""}" + if (it.variable is Port && it.variable.isMultiport) { + "${it.codeType} *${it.name}[], size_t ${it.name}_width" + } else { + "${it.codeType} *${it.name}" + } } + allReferencedContainers.map { - "${getContainedStructName(this, it)} ${it.name} ${if (it.isBank) ", size_t ${it.name}_width" else ""}" + if (it.isBank) { + "${getContainedStructName(this, it)} ${it.name}[], size_t ${it.name}_width" + } else { + "${getContainedStructName(this, it)} ${it.name}" + } } private val TriggerRef.codeType @@ -100,31 +116,41 @@ class UcReactionGenerator(private val reactor: Reactor) { } private val VarRef.codeType - get() = - when (val variable = this.variable) { - is Timer -> "${reactor.codeType}_Timer" - is Action -> "${reactor.codeType}_Action" - is Port -> "${reactor.codeType}_Port" - else -> throw AssertionError("Unexpected variable type") - } - private val TriggerRef.scope + get() = "${reactor.codeType}_${name}" + + private val TriggerRef.scopeTrigger get() = when { this is BuiltinTriggerRef && this.type == BuiltinTrigger.STARTUP -> "LF_SCOPE_STARTUP(${reactor.codeType});" this is BuiltinTriggerRef && this.type == BuiltinTrigger.SHUTDOWN -> "LF_SCOPE_SHUTDOWN(${reactor.codeType});" - this is VarRef -> scope + this is VarRef -> scopeTrigger else -> AssertionError("Unexpected trigger type") } - private val VarRef.scope + private val VarRef.scopeTrigger get() = when (val variable = this.variable) { is Timer -> "LF_SCOPE_TIMER(${reactor.codeType}, ${name});" - is Action -> "LF_SCOPE_ACTION(${reactor.codeType}, ${name});" + is Action -> "LF_SCOPE_ACTION_TRIGGER(${reactor.codeType}, ${name});" is Port -> { if (variable.width > 1) { - "LF_SCOPE_MULTIPORT(${reactor.codeType}, ${name});" + "LF_SCOPE_MULTIPORT_TRIGGER(${reactor.codeType}, ${name});" } else { - "LF_SCOPE_PORT(${reactor.codeType}, ${name});" + "LF_SCOPE_PORT_TRIGGER(${reactor.codeType}, ${name});" + } + } + else -> throw AssertionError("Unexpected variable type") + } + + private val VarRef.scopeEffect + get() = + when (val variable = this.variable) { + is Timer -> "LF_SCOPE_TIMER(${reactor.codeType}, ${name});" + is Action -> "LF_SCOPE_ACTION_EFFECT(${reactor.codeType}, ${name});" + is Port -> { + if (variable.width > 1) { + "LF_SCOPE_MULTIPORT_EFFECT(${reactor.codeType}, ${name});" + } else { + "LF_SCOPE_PORT_EFFECT(${reactor.codeType}, ${name});" } } else -> throw AssertionError("Unexpected variable type") @@ -251,11 +277,7 @@ class UcReactionGenerator(private val reactor: Reactor) { fun generateReactionInnerArgumentStructs(reaction: Reaction) = reaction.allContainedEffectsTriggersAndSources.toList() .joinToString(separator = "\n") { - if (it.first.width > 1) { - generateContainedBankStructDeclaration(reaction, it.second, it.first) - } else { - generateContainedReactorStructDeclaration(reaction, it.second, it.first) - } + generateContainedReactorDefinition(reaction, it.second, it.first) } fun generateReactionInnerBodies() = @@ -300,9 +322,9 @@ class UcReactionGenerator(private val reactor: Reactor) { private fun generateReactionInnerBodyCall(reaction: Reaction): String { with(reaction) { - val parameters = allUncontainedTriggers.map { "${it.name} ${if (it is Input && it.isMultiport) ", ${it.name}_width" else ""}"} + - allUncontainedSources.map { "${it.name} ${if (it is Input && it.isMultiport) ", ${it.name}_width" else ""}"} + - allUncontainedEffects.map { "${it.name} ${if (it is Output && it.isMultiport) ", ${it.name}_width" else ""}"} + + val parameters = allUncontainedTriggers.map { "${it.name} ${if (it is VarRef && it.variable is Input && it.variable.isMultiport) ", ${it.name}_width" else ""}"} + + allUncontainedSources.map { "${it.name} ${if (it.variable is Input && it.variable.isMultiport) ", ${it.name}_width" else ""}"} + + allUncontainedEffects.map { "${it.name} ${if (it.variable is Output && it.variable.isMultiport) ", ${it.name}_width" else ""}"} + allReferencedContainers.map { "${it.name} ${if (it.isBank) ", ${it.name}_width" else ""}" } @@ -387,8 +409,9 @@ class UcReactionGenerator(private val reactor: Reactor) { } private fun generateTriggersEffectsAndSourcesInScope(reaction: Reaction) = - reaction.allUncontainedTriggers.plus(reaction.allUncontainedEffects).plus(reaction.allUncontainedSources) - .joinToString(separator = "\n") { with(PrependOperator) { it.scope.toString() } } + reaction.allUncontainedTriggers.plus(reaction.allUncontainedSources).filter{it !in reaction.allUncontainedEffects}.distinct().joinToString(prefix = "\n", separator = "\n", postfix="\n"){ + it.scopeTrigger.toString() + } + reaction.allUncontainedEffects.joinToString(separator = "\n") { with(PrependOperator) { it.scopeEffect.toString() } } private fun generateContainedTriggersAndSourcesInScope(reaction: Reaction) = reaction.allContainedEffectsTriggersAndSources.toList() diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt index 2bd6f628..01363306 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt @@ -174,6 +174,7 @@ class UcReactorGenerator(private val reactor: Reactor, private val fileConfig: U |#include "${headerFile}" ${" |"..generateReactorPrivatePreamble()} ${" |"..reactions.generateReactionBodies()} + ${" |"..reactions.generateReactionInnerBodies()} ${" |"..reactions.generateReactionDeadlineHandlers()} ${" |"..reactions.generateReactionCtors()} ${" |"..actions.generateCtors()} diff --git a/test/lf/src/Bodiless.lf b/test/lf/src/Bodyless.lf similarity index 65% rename from test/lf/src/Bodiless.lf rename to test/lf/src/Bodyless.lf index 2332f6bf..69a8268b 100644 --- a/test/lf/src/Bodiless.lf +++ b/test/lf/src/Bodyless.lf @@ -1,6 +1,6 @@ target uC { platform: Native, - cmake-include: "./lib/bodiless.cmake", + cmake-include: "./lib/bodyless.cmake", } diff --git a/test/lf/src/lib/bodiless.c b/test/lf/src/lib/bodyless.c similarity index 100% rename from test/lf/src/lib/bodiless.c rename to test/lf/src/lib/bodyless.c diff --git a/test/lf/src/lib/bodiless.cmake b/test/lf/src/lib/bodyless.cmake similarity index 82% rename from test/lf/src/lib/bodiless.cmake rename to test/lf/src/lib/bodyless.cmake index 930c4de7..fbf6faed 100644 --- a/test/lf/src/lib/bodiless.cmake +++ b/test/lf/src/lib/bodyless.cmake @@ -1 +1 @@ -target_sources(${LF_MAIN_TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/bodiless.c) \ No newline at end of file +target_sources(${LF_MAIN_TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/bodyless.c) \ No newline at end of file From 320a9aa7d33d72243654b3ac9ad78d6b3f0f22d0 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Fri, 6 Dec 2024 20:05:11 -0800 Subject: [PATCH 3/6] Update for new SCOPE macros --- examples/posix/federated/receiver.c | 2 +- examples/posix/federated/sender.c | 2 +- examples/zephyr/basic_federated/federated_sender/src/sender.c | 2 +- test/unit/action_empty_test.c | 2 +- test/unit/action_microstep_test.c | 2 +- test/unit/action_overwrite_test.c | 2 +- test/unit/action_test.c | 2 +- test/unit/delayed_conn_test.c | 4 ++-- test/unit/port_test.c | 4 ++-- test/unit/request_shutdown_test.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/posix/federated/receiver.c b/examples/posix/federated/receiver.c index 8b4c235e..8d77e022 100644 --- a/examples/posix/federated/receiver.c +++ b/examples/posix/federated/receiver.c @@ -35,7 +35,7 @@ typedef struct { LF_DEFINE_REACTION_BODY(Receiver, r) { LF_SCOPE_SELF(Receiver); LF_SCOPE_ENV(); - LF_SCOPE_PORT(Receiver, in); + LF_SCOPE_PORT_TRIGGER(Receiver, in); printf("Input triggered @ %" PRId64 " with %s size %d\n", env->get_elapsed_logical_time(env), in->value.msg, in->value.size); } diff --git a/examples/posix/federated/sender.c b/examples/posix/federated/sender.c index 5a2bcefe..88512f67 100644 --- a/examples/posix/federated/sender.c +++ b/examples/posix/federated/sender.c @@ -39,7 +39,7 @@ typedef struct { LF_DEFINE_REACTION_BODY(Sender, r) { LF_SCOPE_SELF(Sender); LF_SCOPE_ENV(); - LF_SCOPE_PORT(Sender, out); + LF_SCOPE_PORT_EFFECT(Sender, out); printf("Timer triggered @ %" PRId64 "\n", env->get_elapsed_logical_time(env)); msg_t val; diff --git a/examples/zephyr/basic_federated/federated_sender/src/sender.c b/examples/zephyr/basic_federated/federated_sender/src/sender.c index 024dec6c..cd149eab 100644 --- a/examples/zephyr/basic_federated/federated_sender/src/sender.c +++ b/examples/zephyr/basic_federated/federated_sender/src/sender.c @@ -77,7 +77,7 @@ typedef struct { LF_DEFINE_REACTION_BODY(Sender, r) { LF_SCOPE_SELF(Sender); LF_SCOPE_ENV(); - LF_SCOPE_PORT(Sender, out); + LF_SCOPE_PORT_EFFECT(Sender, out); gpio_pin_toggle_dt(&led); printf("Reaction triggered @ %" PRId64 " (%" PRId64 "), %" PRId64 ")\n", env->get_elapsed_logical_time(env), env->get_logical_time(env), env->get_physical_time(env)); diff --git a/test/unit/action_empty_test.c b/test/unit/action_empty_test.c index 12d24290..62cd7bb8 100644 --- a/test/unit/action_empty_test.c +++ b/test/unit/action_empty_test.c @@ -6,7 +6,7 @@ LF_DEFINE_REACTION_BODY(ActionLib, reaction) { LF_SCOPE_SELF(ActionLib); LF_SCOPE_ENV(); - LF_SCOPE_ACTION(ActionLib, act); + LF_SCOPE_ACTION_EFFECT(ActionLib, act); TEST_ASSERT_EQUAL(env->get_elapsed_logical_time(env)/MSEC(1), self->cnt); lf_schedule(act, MSEC(1)); self->cnt++; diff --git a/test/unit/action_microstep_test.c b/test/unit/action_microstep_test.c index b00d93d8..16baf49a 100644 --- a/test/unit/action_microstep_test.c +++ b/test/unit/action_microstep_test.c @@ -6,7 +6,7 @@ LF_DEFINE_REACTION_BODY(ActionLib, reaction) { LF_SCOPE_SELF(ActionLib); LF_SCOPE_ENV(); - LF_SCOPE_ACTION(ActionLib, act); + LF_SCOPE_ACTION_EFFECT(ActionLib, act); if (self->cnt == 0) { TEST_ASSERT_EQUAL(lf_is_present(act), false); diff --git a/test/unit/action_overwrite_test.c b/test/unit/action_overwrite_test.c index bdeb5666..50bdccd5 100644 --- a/test/unit/action_overwrite_test.c +++ b/test/unit/action_overwrite_test.c @@ -7,7 +7,7 @@ LF_DEFINE_REACTION_BODY(ActionLib, reaction) { LF_SCOPE_SELF(ActionLib); LF_SCOPE_ENV(); - LF_SCOPE_ACTION(ActionLib, act); + LF_SCOPE_ACTION_EFFECT(ActionLib, act); if (self->cnt == 0) { TEST_ASSERT_EQUAL(lf_is_present(act), false); diff --git a/test/unit/action_test.c b/test/unit/action_test.c index d3473569..37e644f5 100644 --- a/test/unit/action_test.c +++ b/test/unit/action_test.c @@ -5,7 +5,7 @@ LF_DEFINE_REACTION_BODY(ActionLib, reaction) { LF_SCOPE_SELF(ActionLib); - LF_SCOPE_ACTION(ActionLib, act); + LF_SCOPE_ACTION_EFFECT(ActionLib, act); if (self->cnt == 0) { // First triggering is from startup reaction, and action should be false. diff --git a/test/unit/delayed_conn_test.c b/test/unit/delayed_conn_test.c index f359c085..1fdddc67 100644 --- a/test/unit/delayed_conn_test.c +++ b/test/unit/delayed_conn_test.c @@ -22,7 +22,7 @@ typedef struct { LF_DEFINE_REACTION_BODY(Sender, r_sender) { LF_SCOPE_SELF(Sender); LF_SCOPE_ENV(); - LF_SCOPE_PORT(Sender, out); + LF_SCOPE_PORT_EFFECT(Sender, out); // printf("Timer triggered @ %ld\n", env->get_elapsed_logical_time(env)); lf_set(out, env->get_elapsed_logical_time(env)); } @@ -55,7 +55,7 @@ typedef struct { LF_DEFINE_REACTION_BODY(Receiver, r_recv) { LF_SCOPE_SELF(Receiver); LF_SCOPE_ENV(); - LF_SCOPE_PORT(Receiver, in); + LF_SCOPE_PORT_TRIGGER(Receiver, in); printf("Input triggered @ %ld with %ld\n", env->get_elapsed_logical_time(env), in->value); TEST_ASSERT_EQUAL(in->value + MSEC(15), env->get_elapsed_logical_time(env)); diff --git a/test/unit/port_test.c b/test/unit/port_test.c index 52bbfb8d..c7e51117 100644 --- a/test/unit/port_test.c +++ b/test/unit/port_test.c @@ -22,7 +22,7 @@ typedef struct { LF_DEFINE_REACTION_BODY(Sender, r_sender) { LF_SCOPE_SELF(Sender); LF_SCOPE_ENV(); - LF_SCOPE_PORT(Sender, out); + LF_SCOPE_PORT_EFFECT(Sender, out); // printf("Timer triggered @ %ld\n", env->get_elapsed_logical_time(env)); lf_set(out, env->get_elapsed_logical_time(env)); } @@ -54,7 +54,7 @@ typedef struct { LF_DEFINE_REACTION_BODY(Receiver, r_recv) { LF_SCOPE_SELF(Receiver); LF_SCOPE_ENV(); - LF_SCOPE_PORT(Receiver, in); + LF_SCOPE_PORT_TRIGGER(Receiver, in); printf("Input triggered @ %ld with %ld\n", env->get_elapsed_logical_time(env), in->value); TEST_ASSERT_EQUAL(in->value, env->get_elapsed_logical_time(env)); diff --git a/test/unit/request_shutdown_test.c b/test/unit/request_shutdown_test.c index b2ae7987..d3aa430d 100644 --- a/test/unit/request_shutdown_test.c +++ b/test/unit/request_shutdown_test.c @@ -5,7 +5,7 @@ LF_DEFINE_REACTION_BODY(ActionLib, reaction) { LF_SCOPE_SELF(ActionLib); LF_SCOPE_ENV(); - LF_SCOPE_ACTION(ActionLib, act); + LF_SCOPE_ACTION_EFFECT(ActionLib, act); if (env->get_elapsed_logical_time(env) == MSEC(1)) { TEST_ASSERT_EQUAL(2, self->cnt); From f211a775dddae9cdd76d1b076dc3aab8842d69e6 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Fri, 6 Dec 2024 20:15:08 -0800 Subject: [PATCH 4/6] Fix --- test/lf/src/lib/bodyless.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lf/src/lib/bodyless.c b/test/lf/src/lib/bodyless.c index 5daa32d1..bc1f0f49 100644 --- a/test/lf/src/lib/bodyless.c +++ b/test/lf/src/lib/bodyless.c @@ -1,4 +1,4 @@ -#include "Bodiless/Bodiless.h" +#include "Bodyless/Bodyless.h" void Reactor_Bodiless_hello(Reactor_Bodiless *self, Environment *env, const Reactor_Bodiless_Startup *startup) { printf("Hello, World!\n"); From 1fe6c4ac7956a0081823eb33f47a0ae071316388 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Sun, 8 Dec 2024 11:45:19 -0800 Subject: [PATCH 5/6] Typos --- test/lf/src/lib/bodyless.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lf/src/lib/bodyless.c b/test/lf/src/lib/bodyless.c index bc1f0f49..0a4447ab 100644 --- a/test/lf/src/lib/bodyless.c +++ b/test/lf/src/lib/bodyless.c @@ -1,5 +1,5 @@ #include "Bodyless/Bodyless.h" -void Reactor_Bodiless_hello(Reactor_Bodiless *self, Environment *env, const Reactor_Bodiless_Startup *startup) { +void Reactor_Bodyless_hello(Reactor_Bodyless *self, Environment *env, const Reactor_Bodyless_Startup *startup) { printf("Hello, World!\n"); } \ No newline at end of file From a26f4d7a8a26c28c9ac3242269e1beb12acc8eb5 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Mon, 9 Dec 2024 09:59:48 -0800 Subject: [PATCH 6/6] FIx --- .../kotlin/org/lflang/generator/uc/UcReactorGenerator.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt index 01363306..3f0879c7 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt @@ -49,13 +49,13 @@ class UcReactorGenerator(private val reactor: Reactor, private val fileConfig: U fun generateReactorPrivatePreamble() = reactor.allPreambles.joinToString(prefix= "// Private preambles\n", separator = "\n", postfix = "\n") { it.code.toText()} + private val Reactor.includeGuard + get(): String = "LFC_GEN_${name.uppercase()}_H" + companion object { val Reactor.codeType get(): String = "Reactor_$name" - val Reactor.includeGuard - get(): String = "LFC_GEN_${name.uppercase()}_H" - val Reactor.hasStartup get(): Boolean = allReactions.filter { it.triggers.filter { it is BuiltinTriggerRef && it.type == BuiltinTrigger.STARTUP }.isNotEmpty()