From bb0dbd1f41d45897c85c343f3d4ed6fe526d2763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Haye=C3=9F?= Date: Fri, 27 May 2022 13:18:15 +0200 Subject: [PATCH 01/16] Base support for multiport child references --- .../src/org/lflang/generator/rust/PortEmitter.kt | 10 ++++++++-- org.lflang/src/org/lflang/generator/rust/RustModel.kt | 5 +++-- .../org/lflang/generator/rust/RustReactorEmitter.kt | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt index 9544e8c4ab..7b922d4baa 100644 --- a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt @@ -62,8 +62,14 @@ object PortEmitter : RustEmitterBase() { val self = "&mut __self.$rustFieldName" val child = "&mut $rustChildName.$rustFieldOnChildName" - return if (isInput) "$assembler.bind_ports($self, $child)?;" - else "$assembler.bind_ports($child, $self)?;" + return if (isMultiport) { + // TODO: make bind_ports_zip take streams with IntoIterator + if (isInput) "$assembler.bind_ports_zip($self.into_iter(), $child.into_iter())?;" + else "$assembler.bind_ports_zip($child.into_iter(), $self.into_iter())?;" + } else { + if (isInput) "$assembler.bind_ports($self, $child)?;" + else "$assembler.bind_ports($child, $self)?;" + } } /** diff --git a/org.lflang/src/org/lflang/generator/rust/RustModel.kt b/org.lflang/src/org/lflang/generator/rust/RustModel.kt index 9de454ddcd..369f9ba311 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustModel.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustModel.kt @@ -182,8 +182,9 @@ data class ChildPortReference( override val lfName: Ident, override val isInput: Boolean, override val dataType: TargetCode, - override val isMultiport: Boolean + val widthSpec: TargetCode? ) : PortLike() { + override val isMultiport: Boolean get() = widthSpec != null val rustFieldOnChildName: String = lfName.escapeRustIdent() /** Sync with [NestedReactorInstance.rustLocalName]. */ @@ -528,7 +529,7 @@ object RustModelBuilder { lfName = variable.name, isInput = variable is Input, dataType = container.reactor.instantiateType(formalType, it.container.typeParms), - isMultiport = variable.isMultiport + widthSpec = variable.widthSpec.toCppCode() ) } else { components[variable.name] ?: throw UnsupportedGeneratorFeatureException( diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index dd2156172b..365e6c9f76 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -361,7 +361,7 @@ ${" | "..declareChildConnections()} } is ChildPortReference -> { if (isMultiport) { - throw UnsupportedGeneratorFeatureException("Multiport references from parent reactor") + "__assembler.new_port_bank::<$dataType>(\"$childLfName.$lfName\", $portKind, $widthSpec)?" } else { "__assembler.new_port::<$dataType>(\"$childLfName.$lfName\", $portKind)" } From 31afa58bdac2a2ac06ae6d19adedbba64f01b6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Haye=C3=9F?= Date: Mon, 30 May 2022 13:32:34 +0200 Subject: [PATCH 02/16] Port width spec might be null --- org.lflang/src/org/lflang/generator/rust/RustModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/rust/RustModel.kt b/org.lflang/src/org/lflang/generator/rust/RustModel.kt index 369f9ba311..2853ff0c0f 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustModel.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustModel.kt @@ -529,7 +529,7 @@ object RustModelBuilder { lfName = variable.name, isInput = variable is Input, dataType = container.reactor.instantiateType(formalType, it.container.typeParms), - widthSpec = variable.widthSpec.toCppCode() + widthSpec = variable.widthSpec?.toCppCode() ) } else { components[variable.name] ?: throw UnsupportedGeneratorFeatureException( From 8d885907d1891fa2a2bd8af7b358e168702fbaab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Haye=C3=9F?= Date: Wed, 1 Jun 2022 14:53:56 +0200 Subject: [PATCH 03/16] Support banks as child references --- .../org/lflang/generator/rust/PortEmitter.kt | 18 +++++++++--- .../org/lflang/generator/rust/RustModel.kt | 13 ++++++--- .../generator/rust/RustReactorEmitter.kt | 29 +++++++++++-------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt index 7b922d4baa..31fbc70215 100644 --- a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt @@ -26,6 +26,7 @@ package org.lflang.generator.rust import org.lflang.generator.TargetCode import org.lflang.generator.locationInfo +import org.lflang.generator.rust.PortEmitter.iterAllPorts import org.lflang.headAndTail import org.lflang.isBank import org.lflang.lf.Connection @@ -62,10 +63,19 @@ object PortEmitter : RustEmitterBase() { val self = "&mut __self.$rustFieldName" val child = "&mut $rustChildName.$rustFieldOnChildName" - return if (isMultiport) { - // TODO: make bind_ports_zip take streams with IntoIterator - if (isInput) "$assembler.bind_ports_zip($self.into_iter(), $child.into_iter())?;" - else "$assembler.bind_ports_zip($child.into_iter(), $self.into_iter())?;" + return if (isMultiport || isBank) { + var lhsPorts = "$child.into_iter()" + var rhsPorts = "$self.into_iter()" + + if (isBank && !isMultiport) { + lhsPorts = "unsafe_iter_bank!($rustChildName # $rustFieldOnChildName)" + } + + if (isInput) { + lhsPorts = rhsPorts.also { rhsPorts = lhsPorts } + } + + "$assembler.bind_ports_zip($lhsPorts, $rhsPorts)?;" } else { if (isInput) "$assembler.bind_ports($self, $child)?;" else "$assembler.bind_ports($child, $self)?;" diff --git a/org.lflang/src/org/lflang/generator/rust/RustModel.kt b/org.lflang/src/org/lflang/generator/rust/RustModel.kt index 2853ff0c0f..2a1b050c2a 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustModel.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustModel.kt @@ -182,9 +182,11 @@ data class ChildPortReference( override val lfName: Ident, override val isInput: Boolean, override val dataType: TargetCode, - val widthSpec: TargetCode? + val widthSpecMultiport: TargetCode?, + val widthSpecBank: TargetCode?, ) : PortLike() { - override val isMultiport: Boolean get() = widthSpec != null + override val isMultiport: Boolean get() = widthSpecMultiport != null + override val isBank: Boolean get() = widthSpecBank != null val rustFieldOnChildName: String = lfName.escapeRustIdent() /** Sync with [NestedReactorInstance.rustLocalName]. */ @@ -346,6 +348,7 @@ sealed class PortLike : ReactorComponent() { abstract val dataType: TargetCode abstract val isMultiport: Boolean + abstract val isBank: Boolean } /** @@ -360,6 +363,7 @@ data class PortData( val widthSpec: TargetCode?, ) : PortLike() { override val isMultiport: Boolean get() = widthSpec != null + override val isBank = false companion object { fun from(port: Port) = @@ -367,7 +371,7 @@ data class PortData( lfName = port.name, isInput = port.isInput, dataType = RustTypes.getTargetType(port.type), - widthSpec = port.widthSpec?.toCppCode() + widthSpec = port.widthSpec?.toCppCode(), ) } } @@ -529,7 +533,8 @@ object RustModelBuilder { lfName = variable.name, isInput = variable is Input, dataType = container.reactor.instantiateType(formalType, it.container.typeParms), - widthSpec = variable.widthSpec?.toCppCode() + widthSpecMultiport = variable.widthSpec?.toCppCode(), + widthSpecBank = container.widthSpec?.toCppCode(), ) } else { components[variable.name] ?: throw UnsupportedGeneratorFeatureException( diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index 365e6c9f76..12cf6b321b 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -337,7 +337,7 @@ ${" | "..declareChildConnections()} if (isLogical) "$rsRuntime::LogicalAction<${dataType ?: "()"}>" else "$rsRuntime::PhysicalActionRef<${dataType ?: "()"}>" is PortLike -> with(this) { - if (isMultiport) "$rsRuntime::PortBank<$dataType>" + if (isBank || isMultiport) "$rsRuntime::PortBank<$dataType>" else "$rsRuntime::Port<$dataType>" } is TimerData -> "$rsRuntime::Timer" @@ -360,8 +360,13 @@ ${" | "..declareChildConnections()} } } is ChildPortReference -> { - if (isMultiport) { - "__assembler.new_port_bank::<$dataType>(\"$childLfName.$lfName\", $portKind, $widthSpec)?" + if (isMultiport || isBank) { + val width = if (isMultiport && !isBank) { + widthSpecMultiport + } else { + widthSpecBank + } + "__assembler.new_port_bank::<$dataType>(\"$childLfName.$lfName\", $portKind, $width)?" } else { "__assembler.new_port::<$dataType>(\"$childLfName.$lfName\", $portKind)" } @@ -384,10 +389,10 @@ ${" | "..declareChildConnections()} private fun ReactorComponent.toBorrowedType(kind: DepKind): TargetCode = when (this) { is PortLike -> when { - kind == DepKind.Effects && isMultiport -> "$rsRuntime::WritablePortBank<$dataType>" // note: owned - kind == DepKind.Effects -> "$rsRuntime::WritablePort<$dataType>" // note: owned - isMultiport -> "$rsRuntime::ReadablePortBank<$dataType>" // note: owned - else -> "&$rsRuntime::ReadablePort<$dataType>" // note: a reference + kind == DepKind.Effects && (isBank || isMultiport) -> "$rsRuntime::WritablePortBank<$dataType>" // note: owned + kind == DepKind.Effects -> "$rsRuntime::WritablePort<$dataType>" // note: owned + isBank || isMultiport -> "$rsRuntime::ReadablePortBank<$dataType>" // note: owned + else -> "&$rsRuntime::ReadablePort<$dataType>" // note: a reference } is TimerData -> "&${toType()}" is ActionData -> if (isLogical && kind == DepKind.Effects) "&mut ${toType()}" else "&${toType()}" @@ -400,10 +405,10 @@ ${" | "..declareChildConnections()} private fun ReactorComponent.toBorrow(kind: DepKind): TargetCode = when (this) { is PortLike -> when { - kind == DepKind.Effects && isMultiport -> "$rsRuntime::WritablePortBank::new(&mut self.$rustFieldName)" // note: owned - kind == DepKind.Effects -> "$rsRuntime::WritablePort::new(&mut self.$rustFieldName)" // note: owned - isMultiport -> "$rsRuntime::ReadablePortBank::new(&self.$rustFieldName)" // note: owned - else -> "&$rsRuntime::ReadablePort::new(&self.$rustFieldName)" // note: a reference + kind == DepKind.Effects && (isBank || isMultiport) -> "$rsRuntime::WritablePortBank::new(&mut self.$rustFieldName)" // note: owned + kind == DepKind.Effects -> "$rsRuntime::WritablePort::new(&mut self.$rustFieldName)" // note: owned + isBank || isMultiport -> "$rsRuntime::ReadablePortBank::new(&self.$rustFieldName)" // note: owned + else -> "&$rsRuntime::ReadablePort::new(&self.$rustFieldName)" // note: a reference } is ActionData -> if (kind == DepKind.Effects) "&mut self.$rustFieldName" else "&self.$rustFieldName" is TimerData -> "&self.$rustFieldName" @@ -436,7 +441,7 @@ ${" | "..declareChildConnections()} if (isLogical) "ctx.cleanup_logical_action(&mut self.$rustFieldName);" else "ctx.cleanup_physical_action(&mut self.$rustFieldName);" is PortLike -> - if (isMultiport) "ctx.cleanup_multiport(&mut self.$rustFieldName);" + if (isBank || isMultiport) "ctx.cleanup_multiport(&mut self.$rustFieldName);" else "ctx.cleanup_port(&mut self.$rustFieldName);" else -> null } From 0a545e44258385b9c2449958e062e979c7ee288e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Haye=C3=9F?= Date: Wed, 1 Jun 2022 15:47:46 +0200 Subject: [PATCH 04/16] Add support for child refs that are banks and multiports --- org.lflang/src/org/lflang/generator/rust/PortEmitter.kt | 2 ++ .../src/org/lflang/generator/rust/RustReactorEmitter.kt | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt index 31fbc70215..c6c6f3bec9 100644 --- a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt @@ -69,6 +69,8 @@ object PortEmitter : RustEmitterBase() { if (isBank && !isMultiport) { lhsPorts = "unsafe_iter_bank!($rustChildName # $rustFieldOnChildName)" + } else if (isBank && isMultiport) { + lhsPorts = "unsafe_iter_bank!($rustChildName # ($rustFieldOnChildName)+)" } if (isInput) { diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index 12cf6b321b..0312d7b3ce 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -361,8 +361,10 @@ ${" | "..declareChildConnections()} } is ChildPortReference -> { if (isMultiport || isBank) { - val width = if (isMultiport && !isBank) { + val width = if (!isBank && isMultiport) { widthSpecMultiport + } else if (isBank && isMultiport) { + "$widthSpecBank * $widthSpecMultiport" } else { widthSpecBank } From cbff80ae685994d5b4a73788605d491e9af8645e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Haye=C3=9F?= Date: Thu, 2 Jun 2022 15:32:18 +0200 Subject: [PATCH 05/16] Inject child port refs as mutable if they are input --- org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index 0312d7b3ce..427c3c16e0 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -426,7 +426,7 @@ ${" | "..declareChildConnections()} depKind != DepKind.Effects && this in n.effects private fun ReactorComponent.isInjectedAsMut(depKind: DepKind): Boolean = - depKind == DepKind.Effects && (this is PortData || this is ActionData) + depKind == DepKind.Effects && (this is PortData || this is ActionData || (this is ChildPortReference && isInput)) /** * Whether this component may be unused in a reaction. From fbf8e86acf193d84ccdbb055da54de5f2174e152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Haye=C3=9F?= Date: Thu, 2 Jun 2022 15:34:09 +0200 Subject: [PATCH 06/16] Add WriteInputOfContainedBank unit test for Rust --- .../multiport/WriteInputOfContainedBank.lf | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 test/Rust/src/multiport/WriteInputOfContainedBank.lf diff --git a/test/Rust/src/multiport/WriteInputOfContainedBank.lf b/test/Rust/src/multiport/WriteInputOfContainedBank.lf new file mode 100644 index 0000000000..f8a0463510 --- /dev/null +++ b/test/Rust/src/multiport/WriteInputOfContainedBank.lf @@ -0,0 +1,32 @@ +// Test writing inputs to a contained reactor bank +target Rust; +reactor Contained(bank_index:usize(0)) { + state bank_index(bank_index); + + input inpt:usize; + state count:usize(0); + reaction(inpt) {= + let result = ctx.get(inpt).unwrap(); + println!("Instance {} received {}", self.bank_index, result); + if result != self.bank_index * 42 { + println!("FAILURE: expected {}", 42* self.bank_index); + std::process::exit(2); + } + self.count += 1; + =} + reaction(shutdown) {= + if self.count != 1 { + eprintln!("ERROR: One of the reactions failed to trigger."); + std::process::exit(1); + } + =} +} + +main reactor { + c = new[4] Contained(); + reaction(startup) -> c.inpt {= + for i in 0..c__inpt.len() { + ctx.set(c__inpt.get(i), i * 42); + } + =} +} From 09fb724a132bd75748a0a509494524218c2beb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Haye=C3=9F?= Date: Thu, 2 Jun 2022 15:47:32 +0200 Subject: [PATCH 07/16] Add ReadOutputOfContainedBank unit test for Rust Fails right now due to what appears to be a scheduling error --- .../multiport/ReadOutputOfContainedBank.lf | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 test/Rust/src/multiport/ReadOutputOfContainedBank.lf diff --git a/test/Rust/src/multiport/ReadOutputOfContainedBank.lf b/test/Rust/src/multiport/ReadOutputOfContainedBank.lf new file mode 100644 index 0000000000..aa9c10482f --- /dev/null +++ b/test/Rust/src/multiport/ReadOutputOfContainedBank.lf @@ -0,0 +1,56 @@ +// Test reacting to and reading outputs from a contained +// reactor bank in various permutations. +target Rust; +reactor Contained(bank_index:usize(0)) { + state bank_index(bank_index); + + output out:usize; + reaction(startup) -> out {= + ctx.set(out, 42 * self.bank_index); + =} +} + +main reactor { + c = new[4] Contained(); + state count:usize(0); + reaction(startup) c.out {= + for i in 0..c__out.len() { + let result = ctx.get(&c__out.get(i)).unwrap(); + println!("Startup reaction reading output of contained reactor: {}", result); + if result != 42 * i { + println!("FAILURE: expected {}", 42 * i); + std::process::exit(2); + } + } + self.count += 1; + =} + reaction(c.out) {= + for i in 0..c__out.len() { + let result = ctx.get(&c__out.get(i)).unwrap(); + println!("Reading output of contained reactor: {}", result); + if result != 42 * i { + println!("FAILURE: expected {}", 42 * i); + std::process::exit(2); + } + } + self.count += 1; + =} + reaction(startup, c.out) {= + for i in 0..c__out.len() { + let result = ctx.get(&c__out.get(i)).unwrap(); + println!("Alternate triggering reading output of contained reactor: {}", result); + if result != 42 * i { + println!("FAILURE: expected {}", 42 * i); + std::process::exit(2); + } + } + self.count += 1; + =} + reaction(shutdown) {= + if self.count != 3 { + println!("count: {}", self.count); + println!("ERROR: One of the reactions failed to trigger."); + std::process::exit(1); + } + =} +} From 1e47904884be4a116171c7ee51e0a093666c2779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 6 Sep 2022 17:01:52 +0200 Subject: [PATCH 08/16] Apply suggestions from code review --- org.lflang/src/org/lflang/generator/rust/RustModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/rust/RustModel.kt b/org.lflang/src/org/lflang/generator/rust/RustModel.kt index 2a1b050c2a..2d61111a0f 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustModel.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustModel.kt @@ -371,7 +371,7 @@ data class PortData( lfName = port.name, isInput = port.isInput, dataType = RustTypes.getTargetType(port.type), - widthSpec = port.widthSpec?.toCppCode(), + widthSpec = port.widthSpec?.toRustExpr(), ) } } @@ -533,8 +533,8 @@ object RustModelBuilder { lfName = variable.name, isInput = variable is Input, dataType = container.reactor.instantiateType(formalType, it.container.typeParms), - widthSpecMultiport = variable.widthSpec?.toCppCode(), - widthSpecBank = container.widthSpec?.toCppCode(), + widthSpecMultiport = variable.widthSpec?.toRustExpr(), + widthSpecBank = container.widthSpec?.toRustExpr(), ) } else { components[variable.name] ?: throw UnsupportedGeneratorFeatureException( From 12f7d35e1696820ab87d2dd45d8704b22ea525d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 7 Sep 2022 13:36:44 +0200 Subject: [PATCH 09/16] Cleanup Rust emitter --- .../org/lflang/generator/rust/PortEmitter.kt | 13 ++++---- .../org/lflang/generator/rust/RustModel.kt | 16 +++++---- .../generator/rust/RustReactorEmitter.kt | 33 ++++++++----------- .../multiport/ReadOutputOfContainedBank.lf | 29 ++++++---------- 4 files changed, 38 insertions(+), 53 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt index c6c6f3bec9..3d8da21681 100644 --- a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt @@ -26,7 +26,6 @@ package org.lflang.generator.rust import org.lflang.generator.TargetCode import org.lflang.generator.locationInfo -import org.lflang.generator.rust.PortEmitter.iterAllPorts import org.lflang.headAndTail import org.lflang.isBank import org.lflang.lf.Connection @@ -63,13 +62,13 @@ object PortEmitter : RustEmitterBase() { val self = "&mut __self.$rustFieldName" val child = "&mut $rustChildName.$rustFieldOnChildName" - return if (isMultiport || isBank) { + return if (isGeneratedAsMultiport) { var lhsPorts = "$child.into_iter()" var rhsPorts = "$self.into_iter()" - if (isBank && !isMultiport) { + if (isContainedInBank && !isMultiport) { lhsPorts = "unsafe_iter_bank!($rustChildName # $rustFieldOnChildName)" - } else if (isBank && isMultiport) { + } else if (isContainedInBank && isMultiport) { lhsPorts = "unsafe_iter_bank!($rustChildName # ($rustFieldOnChildName)+)" } @@ -109,9 +108,9 @@ object PortEmitter : RustEmitterBase() { val container: Instantiation? = container val port = PortData.from(variable as Port) - if (container?.isBank == true && port.isMultiport && isInterleaved) { + if (container?.isBank == true && port.isGeneratedAsMultiport && isInterleaved) { return "unsafe_iter_bank!(${container.name} # interleaved(${port.rustFieldName}))" - } else if (container?.isBank == true && port.isMultiport) { + } else if (container?.isBank == true && port.isGeneratedAsMultiport) { return "unsafe_iter_bank!(${container.name} # (${port.rustFieldName})+)" } else if (container?.isBank == true) { return "unsafe_iter_bank!(${container.name} # ${port.rustFieldName})" @@ -120,7 +119,7 @@ object PortEmitter : RustEmitterBase() { // todo this is missing some tests where we try to borrow several multiports from same reactor val ref = (container?.name ?: "__self") + "." + port.rustFieldName - return if (port.isMultiport) { + return if (port.isGeneratedAsMultiport) { "$ref.iter_mut()" } else { "std::iter::once(&mut $ref)" diff --git a/org.lflang/src/org/lflang/generator/rust/RustModel.kt b/org.lflang/src/org/lflang/generator/rust/RustModel.kt index 2d61111a0f..cab0a8522a 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustModel.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustModel.kt @@ -28,7 +28,6 @@ package org.lflang.generator.rust import org.lflang.* import org.lflang.TargetProperty.BuildType import org.lflang.generator.* -import org.lflang.generator.cpp.toCppCode import org.lflang.lf.* import org.lflang.lf.Timer import java.nio.file.Path @@ -183,10 +182,11 @@ data class ChildPortReference( override val isInput: Boolean, override val dataType: TargetCode, val widthSpecMultiport: TargetCode?, - val widthSpecBank: TargetCode?, + val widthSpecChild: TargetCode?, ) : PortLike() { - override val isMultiport: Boolean get() = widthSpecMultiport != null - override val isBank: Boolean get() = widthSpecBank != null + override val isMultiport: Boolean + get() = widthSpecMultiport != null + override val isContainedInBank: Boolean get() = widthSpecChild != null val rustFieldOnChildName: String = lfName.escapeRustIdent() /** Sync with [NestedReactorInstance.rustLocalName]. */ @@ -347,8 +347,10 @@ sealed class PortLike : ReactorComponent() { abstract val isInput: Boolean abstract val dataType: TargetCode + val isGeneratedAsMultiport: Boolean + get() = isMultiport || isContainedInBank abstract val isMultiport: Boolean - abstract val isBank: Boolean + abstract val isContainedInBank: Boolean } /** @@ -363,7 +365,7 @@ data class PortData( val widthSpec: TargetCode?, ) : PortLike() { override val isMultiport: Boolean get() = widthSpec != null - override val isBank = false + override val isContainedInBank = false companion object { fun from(port: Port) = @@ -534,7 +536,7 @@ object RustModelBuilder { isInput = variable is Input, dataType = container.reactor.instantiateType(formalType, it.container.typeParms), widthSpecMultiport = variable.widthSpec?.toRustExpr(), - widthSpecBank = container.widthSpec?.toRustExpr(), + widthSpecChild = container.widthSpec?.toRustExpr(), ) } else { components[variable.name] ?: throw UnsupportedGeneratorFeatureException( diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index 427c3c16e0..14929e7e67 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -28,7 +28,6 @@ import org.lflang.* import org.lflang.generator.PrependOperator import org.lflang.generator.PrependOperator.rangeTo import org.lflang.generator.TargetCode -import org.lflang.generator.UnsupportedGeneratorFeatureException /** @@ -284,7 +283,7 @@ ${" | "..declareChildConnections()} this += "__assembler.declare_triggers($rsRuntime::assembly::TriggerId::SHUTDOWN, ${n.invokerId})?;" this += n.uses.map { trigger -> "__assembler.declare_uses(${n.invokerId}, __self.${trigger.rustFieldName}.get_id())?;" } this += n.effects.filterIsInstance().map { port -> - if (port.isMultiport) { + if (port.isGeneratedAsMultiport) { "__assembler.effects_bank(${n.invokerId}, &__self.${port.rustFieldName})?;" } else { "__assembler.effects_port(${n.invokerId}, &__self.${port.rustFieldName})?;" @@ -337,7 +336,7 @@ ${" | "..declareChildConnections()} if (isLogical) "$rsRuntime::LogicalAction<${dataType ?: "()"}>" else "$rsRuntime::PhysicalActionRef<${dataType ?: "()"}>" is PortLike -> with(this) { - if (isBank || isMultiport) "$rsRuntime::PortBank<$dataType>" + if (isGeneratedAsMultiport) "$rsRuntime::PortBank<$dataType>" else "$rsRuntime::Port<$dataType>" } is TimerData -> "$rsRuntime::Timer" @@ -360,14 +359,8 @@ ${" | "..declareChildConnections()} } } is ChildPortReference -> { - if (isMultiport || isBank) { - val width = if (!isBank && isMultiport) { - widthSpecMultiport - } else if (isBank && isMultiport) { - "$widthSpecBank * $widthSpecMultiport" - } else { - widthSpecBank - } + if (isGeneratedAsMultiport) { + val width = (widthSpecMultiport ?: "1") + "*" + (widthSpecChild ?: "1") "__assembler.new_port_bank::<$dataType>(\"$childLfName.$lfName\", $portKind, $width)?" } else { "__assembler.new_port::<$dataType>(\"$childLfName.$lfName\", $portKind)" @@ -391,10 +384,10 @@ ${" | "..declareChildConnections()} private fun ReactorComponent.toBorrowedType(kind: DepKind): TargetCode = when (this) { is PortLike -> when { - kind == DepKind.Effects && (isBank || isMultiport) -> "$rsRuntime::WritablePortBank<$dataType>" // note: owned - kind == DepKind.Effects -> "$rsRuntime::WritablePort<$dataType>" // note: owned - isBank || isMultiport -> "$rsRuntime::ReadablePortBank<$dataType>" // note: owned - else -> "&$rsRuntime::ReadablePort<$dataType>" // note: a reference + kind == DepKind.Effects && isGeneratedAsMultiport -> "$rsRuntime::WritablePortBank<$dataType>" // note: owned + kind == DepKind.Effects -> "$rsRuntime::WritablePort<$dataType>" // note: owned + isGeneratedAsMultiport -> "$rsRuntime::ReadablePortBank<$dataType>" // note: owned + else -> "&$rsRuntime::ReadablePort<$dataType>" // note: a reference } is TimerData -> "&${toType()}" is ActionData -> if (isLogical && kind == DepKind.Effects) "&mut ${toType()}" else "&${toType()}" @@ -407,10 +400,10 @@ ${" | "..declareChildConnections()} private fun ReactorComponent.toBorrow(kind: DepKind): TargetCode = when (this) { is PortLike -> when { - kind == DepKind.Effects && (isBank || isMultiport) -> "$rsRuntime::WritablePortBank::new(&mut self.$rustFieldName)" // note: owned - kind == DepKind.Effects -> "$rsRuntime::WritablePort::new(&mut self.$rustFieldName)" // note: owned - isBank || isMultiport -> "$rsRuntime::ReadablePortBank::new(&self.$rustFieldName)" // note: owned - else -> "&$rsRuntime::ReadablePort::new(&self.$rustFieldName)" // note: a reference + kind == DepKind.Effects && isGeneratedAsMultiport -> "$rsRuntime::WritablePortBank::new(&mut self.$rustFieldName)" // note: owned + kind == DepKind.Effects -> "$rsRuntime::WritablePort::new(&mut self.$rustFieldName)" // note: owned + isGeneratedAsMultiport -> "$rsRuntime::ReadablePortBank::new(&self.$rustFieldName)" // note: owned + else -> "&$rsRuntime::ReadablePort::new(&self.$rustFieldName)" // note: a reference } is ActionData -> if (kind == DepKind.Effects) "&mut self.$rustFieldName" else "&self.$rustFieldName" is TimerData -> "&self.$rustFieldName" @@ -443,7 +436,7 @@ ${" | "..declareChildConnections()} if (isLogical) "ctx.cleanup_logical_action(&mut self.$rustFieldName);" else "ctx.cleanup_physical_action(&mut self.$rustFieldName);" is PortLike -> - if (isBank || isMultiport) "ctx.cleanup_multiport(&mut self.$rustFieldName);" + if (isGeneratedAsMultiport) "ctx.cleanup_multiport(&mut self.$rustFieldName);" else "ctx.cleanup_port(&mut self.$rustFieldName);" else -> null } diff --git a/test/Rust/src/multiport/ReadOutputOfContainedBank.lf b/test/Rust/src/multiport/ReadOutputOfContainedBank.lf index aa9c10482f..f6c3b8efb2 100644 --- a/test/Rust/src/multiport/ReadOutputOfContainedBank.lf +++ b/test/Rust/src/multiport/ReadOutputOfContainedBank.lf @@ -4,7 +4,7 @@ target Rust; reactor Contained(bank_index:usize(0)) { state bank_index(bank_index); - output out:usize; + output out: usize; reaction(startup) -> out {= ctx.set(out, 42 * self.bank_index); =} @@ -12,45 +12,36 @@ reactor Contained(bank_index:usize(0)) { main reactor { c = new[4] Contained(); - state count:usize(0); + state count: usize(0); reaction(startup) c.out {= for i in 0..c__out.len() { let result = ctx.get(&c__out.get(i)).unwrap(); println!("Startup reaction reading output of contained reactor: {}", result); - if result != 42 * i { - println!("FAILURE: expected {}", 42 * i); - std::process::exit(2); - } + assert_eq!(result, 42 * i); } self.count += 1; =} + reaction(c.out) {= for i in 0..c__out.len() { let result = ctx.get(&c__out.get(i)).unwrap(); println!("Reading output of contained reactor: {}", result); - if result != 42 * i { - println!("FAILURE: expected {}", 42 * i); - std::process::exit(2); - } + assert_eq!(result, 42 * i); } self.count += 1; =} + reaction(startup, c.out) {= for i in 0..c__out.len() { let result = ctx.get(&c__out.get(i)).unwrap(); println!("Alternate triggering reading output of contained reactor: {}", result); - if result != 42 * i { - println!("FAILURE: expected {}", 42 * i); - std::process::exit(2); - } + assert_eq!(result, 42 * i); } self.count += 1; =} + reaction(shutdown) {= - if self.count != 3 { - println!("count: {}", self.count); - println!("ERROR: One of the reactions failed to trigger."); - std::process::exit(1); - } + assert_eq!(self.count, 3); + println!("success"); =} } From b36ea09ae3db665a0b483d6086ad86c84928321f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 7 Sep 2022 15:00:58 +0200 Subject: [PATCH 10/16] Propagate width of child banks A new struct with extra parameters is added as construction parameters to reactors. References to child banks use this instead of recomputing the width. --- .../org/lflang/generator/rust/RustModel.kt | 2 + .../generator/rust/RustReactorEmitter.kt | 49 +++++++++++++++++-- test/Rust/src/multiport/WidthWithParameter.lf | 15 ++++++ 3 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 test/Rust/src/multiport/WidthWithParameter.lf diff --git a/org.lflang/src/org/lflang/generator/rust/RustModel.kt b/org.lflang/src/org/lflang/generator/rust/RustModel.kt index cab0a8522a..4c11d4bf0f 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustModel.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustModel.kt @@ -191,6 +191,8 @@ data class ChildPortReference( /** Sync with [NestedReactorInstance.rustLocalName]. */ val rustChildName: TargetCode = childLfName.escapeRustIdent() + + val widthParamName: TargetCode = (rustFieldName + "__width").escapeRustIdent() } /** diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index 14929e7e67..3284aed4b9 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -46,6 +46,8 @@ object RustReactorEmitter : RustEmitterBase() { val typeParams = typeParamList.map { it.targetCode }.angle() val typeArgs = typeParamList.map { it.lfName }.angle() + val privateParams = reactor.extraConstructionParams; + with(reactor.names) { with(PrependOperator) { """ @@ -83,6 +85,10 @@ ${" | "..ctorParams.joinWithCommasLn { "${it.lfName.escapeRust | ) -> Self { | Self { __phantom: std::marker::PhantomData, ${ctorParams.joinWithCommas { it.lfName.escapeRustIdent() }} } | } + |} + | + |struct $privateParamStruct { +${" | "..privateParams.joinWithCommasLn { "${it.ident.escapeRustIdent()}: ${it.type}" }} |} | |//------------------------// @@ -98,7 +104,8 @@ ${" | "..otherComponents.joinWithCommasLn { it.toStructField() }} | #[inline] | fn user_assemble(__assembler: &mut $rsRuntime::assembly::ComponentCreator, | __id: $rsRuntime::ReactorId, - | __params: $paramStructName$typeArgs) -> $rsRuntime::assembly::AssemblyResult { + | __params: $paramStructName$typeArgs, + | __more_params: $privateParamStruct) -> $rsRuntime::assembly::AssemblyResult { | let $ctorParamsDeconstructor = __params; | | let __impl = { @@ -173,9 +180,15 @@ ${" | "..otherComponents.mapNotNull { it.cleanupAction() }.jo "__ctx.with_child::<$type, _>(\"$lfName\", $params, |mut __ctx, $rustLocalName| {" } + val portRefs = this.portReferences + return buildString { for (inst in nestedInstances) { append(inst.childDeclaration()).append("\n") + // if we refer to some port of the child as a bank, we need to surface its width here + portRefs.filter { it.childLfName == inst.lfName && it.isGeneratedAsMultiport }.forEach { + append("let ").append(it.widthParamName).append(" = ").append(it.childLfName).append(".").append(it.rustFieldOnChildName).append(".len();\n") + } } append(assembleSelf).append("\n") @@ -199,9 +212,13 @@ ${" | "..otherComponents.mapNotNull { it.cleanupAction() }.jo val pattern = reactionIds.joinToString(prefix = "[", separator = ", ", postfix = "]") val debugLabelArray = debugLabels.joinToString(", ", "[", "]") + val privateParamsCtor = extraConstructionParams.joinWithCommas(prefix = "$privateParamStruct {", postfix = "}") { + it.ident.escapeRustIdent() + } + return """ |__ctx.assemble_self( - | |cc, id| Self::user_assemble(cc, id, $ctorParamsDeconstructor), + | |cc, id| Self::user_assemble(cc, id, $ctorParamsDeconstructor, $privateParamsCtor), | // number of non-synthetic reactions | ${reactions.size}, | // reaction debug labels @@ -360,8 +377,7 @@ ${" | "..declareChildConnections()} } is ChildPortReference -> { if (isGeneratedAsMultiport) { - val width = (widthSpecMultiport ?: "1") + "*" + (widthSpecChild ?: "1") - "__assembler.new_port_bank::<$dataType>(\"$childLfName.$lfName\", $portKind, $width)?" + "__assembler.new_port_bank::<$dataType>(\"$childLfName.$lfName\", $portKind, $privateParamsVarName.$widthParamName)?" } else { "__assembler.new_port::<$dataType>(\"$childLfName.$lfName\", $portKind)" } @@ -477,5 +493,30 @@ ${" | "..body} } } + private val ReactorInfo.extraConstructionParams: List + get() { + val result = mutableListOf() + + for (ref in this.portReferences) { + if (ref.isGeneratedAsMultiport) { + result += PrivateParamSpec( + ident = ref.widthParamName, + type = "usize", + initialValue = ref.rustChildName + "." + ref.rustFieldOnChildName + ".len()" + ) + } + } + + return result + } + + private data class PrivateParamSpec( + val ident: String, + val type: TargetCode, + val initialValue: TargetCode + ) + + private const val privateParamStruct: String = "PrivateParams" + private const val privateParamsVarName = "__more_params" } diff --git a/test/Rust/src/multiport/WidthWithParameter.lf b/test/Rust/src/multiport/WidthWithParameter.lf new file mode 100644 index 0000000000..93addf8566 --- /dev/null +++ b/test/Rust/src/multiport/WidthWithParameter.lf @@ -0,0 +1,15 @@ +target Rust; + +reactor Some(value: usize(30)) { + output[value] finished: unit; +} + +main reactor { + + some = new Some(value=20); + + reaction (some.finished) {= + println!("Works?"); + =} + +} From eb93cd12e21a0b2bc61fdbf4e11b60718542875f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 7 Sep 2022 15:30:25 +0200 Subject: [PATCH 11/16] Fix tests --- .../generator/rust/RustReactorEmitter.kt | 35 +++++++++++++------ test/Rust/src/multiport/WidthWithParameter.lf | 8 ++++- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index 3284aed4b9..6145aa1fe9 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -105,7 +105,7 @@ ${" | "..otherComponents.joinWithCommasLn { it.toStructField() }} | fn user_assemble(__assembler: &mut $rsRuntime::assembly::ComponentCreator, | __id: $rsRuntime::ReactorId, | __params: $paramStructName$typeArgs, - | __more_params: $privateParamStruct) -> $rsRuntime::assembly::AssemblyResult { + | $privateParamsVarName: $privateParamStruct) -> $rsRuntime::assembly::AssemblyResult { | let $ctorParamsDeconstructor = __params; | | let __impl = { @@ -181,14 +181,25 @@ ${" | "..otherComponents.mapNotNull { it.cleanupAction() }.jo } val portRefs = this.portReferences + fun NestedReactorInstance.portWidthDecls(): List = + // if we refer to some port of the child as a bank, we need to surface its width here + portRefs.filter { it.childLfName == this.lfName && it.isGeneratedAsMultiport }.map { + val portWidthExpr = if (it.isMultiport) "${it.childLfName}.${it.rustFieldOnChildName}.len()" + else "1" // that's a single port + + // if we're in a bank, the total length is the sum + val sumExpr = + if (it.isContainedInBank) "${it.childLfName}.iter().map(|${it.childLfName}| $portWidthExpr).sum()" + else portWidthExpr + + "let ${it.widthParamName} = $sumExpr;" + } + return buildString { for (inst in nestedInstances) { append(inst.childDeclaration()).append("\n") - // if we refer to some port of the child as a bank, we need to surface its width here - portRefs.filter { it.childLfName == inst.lfName && it.isGeneratedAsMultiport }.forEach { - append("let ").append(it.widthParamName).append(" = ").append(it.childLfName).append(".").append(it.rustFieldOnChildName).append(".len();\n") - } + inst.portWidthDecls().joinTo(this, "\n").append("\n") } append(assembleSelf).append("\n") @@ -212,7 +223,7 @@ ${" | "..otherComponents.mapNotNull { it.cleanupAction() }.jo val pattern = reactionIds.joinToString(prefix = "[", separator = ", ", postfix = "]") val debugLabelArray = debugLabels.joinToString(", ", "[", "]") - val privateParamsCtor = extraConstructionParams.joinWithCommas(prefix = "$privateParamStruct {", postfix = "}") { + val privateParamsCtor = extraConstructionParams.joinWithCommas(prefix = "$privateParamStruct { ", postfix = " }") { it.ident.escapeRustIdent() } @@ -493,6 +504,12 @@ ${" | "..body} } } + /** + * A list of parameters that are required for construction + * but are of internal use to the generator. + * The widths of port banks referred to by a reactor are + * saved in here, so that we use the actual runtime value. + */ private val ReactorInfo.extraConstructionParams: List get() { val result = mutableListOf() @@ -501,8 +518,7 @@ ${" | "..body} if (ref.isGeneratedAsMultiport) { result += PrivateParamSpec( ident = ref.widthParamName, - type = "usize", - initialValue = ref.rustChildName + "." + ref.rustFieldOnChildName + ".len()" + type = "usize" ) } } @@ -512,8 +528,7 @@ ${" | "..body} private data class PrivateParamSpec( val ident: String, - val type: TargetCode, - val initialValue: TargetCode + val type: TargetCode ) private const val privateParamStruct: String = "PrivateParams" diff --git a/test/Rust/src/multiport/WidthWithParameter.lf b/test/Rust/src/multiport/WidthWithParameter.lf index 93addf8566..fc109c7056 100644 --- a/test/Rust/src/multiport/WidthWithParameter.lf +++ b/test/Rust/src/multiport/WidthWithParameter.lf @@ -2,6 +2,12 @@ target Rust; reactor Some(value: usize(30)) { output[value] finished: unit; + + reaction(startup) -> finished {= + for p in finished { + ctx.set(p, ()); + } + =} } main reactor { @@ -9,7 +15,7 @@ main reactor { some = new Some(value=20); reaction (some.finished) {= - println!("Works?"); + println!("success"); =} } From 03df0fa06471bedd0ec08f8a4e68d7486b2f0e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 9 Sep 2022 15:42:38 +0200 Subject: [PATCH 12/16] Format tests --- .../lflang/tests/compiler/RoundTripTests.java | 18 +++++++------ .../multiport/ReadOutputOfContainedBank.lf | 25 ++++++++++--------- test/Rust/src/multiport/WidthWithParameter.lf | 12 +++------ .../multiport/WriteInputOfContainedBank.lf | 16 +++++++----- 4 files changed, 37 insertions(+), 34 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 9aa8bfef24..b842a5f9fa 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/RoundTripTests.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/RoundTripTests.java @@ -1,5 +1,10 @@ package org.lflang.tests.compiler; +import static java.util.Collections.emptyList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; @@ -46,16 +51,13 @@ public void roundTripTest() throws Exception { private void run(Path file) throws Exception { Model originalModel = parse(file); - Assertions.assertTrue(originalModel.eResource().getErrors().isEmpty()); + assertThat(originalModel.eResource().getErrors(), equalTo(emptyList())); // TODO: Check that the output is a fixed point final int smallLineLength = 20; final String squishedTestCase = FormattingUtils.render(originalModel, smallLineLength); final Model resultingModel = getResultingModel(file, squishedTestCase); Assertions.assertNotNull(resultingModel); - if (!resultingModel.eResource().getErrors().isEmpty()) { - resultingModel.eResource().getErrors().forEach(System.err::println); - Assertions.assertTrue(resultingModel.eResource().getErrors().isEmpty()); - } + assertThat(resultingModel.eResource().getErrors(), equalTo(emptyList())); if (!new IsEqual(originalModel).doSwitch(resultingModel)) { System.out.printf( "The following is what %s looks like after applying formatting with the preferred line " @@ -71,9 +73,9 @@ private void run(Path file) throws Exception { } final String normalTestCase = FormattingUtils.render(originalModel); try { - Assertions.assertEquals( - Files.readString(file).replaceAll("\\r\\n?", "\n"), - normalTestCase + assertEquals( + normalTestCase, + Files.readString(file).replaceAll("\\r\\n?", "\n") ); } catch (AssertionFailedError e) { System.err.printf( diff --git a/test/Rust/src/multiport/ReadOutputOfContainedBank.lf b/test/Rust/src/multiport/ReadOutputOfContainedBank.lf index f6c3b8efb2..970c743a7e 100644 --- a/test/Rust/src/multiport/ReadOutputOfContainedBank.lf +++ b/test/Rust/src/multiport/ReadOutputOfContainedBank.lf @@ -1,18 +1,19 @@ -// Test reacting to and reading outputs from a contained -// reactor bank in various permutations. -target Rust; -reactor Contained(bank_index:usize(0)) { - state bank_index(bank_index); - - output out: usize; - reaction(startup) -> out {= - ctx.set(out, 42 * self.bank_index); - =} +// Test reacting to and reading outputs from a contained reactor bank in various +// permutations. +target Rust + +reactor Contained(bank_index: usize(0)) { + state bank_index(bank_index) + + output out: usize + + reaction(startup) -> out {= ctx.set(out, 42 * self.bank_index); =} } main reactor { - c = new[4] Contained(); - state count: usize(0); + c = new[4] Contained() + state count: usize(0) + reaction(startup) c.out {= for i in 0..c__out.len() { let result = ctx.get(&c__out.get(i)).unwrap(); diff --git a/test/Rust/src/multiport/WidthWithParameter.lf b/test/Rust/src/multiport/WidthWithParameter.lf index fc109c7056..e32f67bec5 100644 --- a/test/Rust/src/multiport/WidthWithParameter.lf +++ b/test/Rust/src/multiport/WidthWithParameter.lf @@ -1,7 +1,7 @@ -target Rust; +target Rust reactor Some(value: usize(30)) { - output[value] finished: unit; + output[value] finished: unit reaction(startup) -> finished {= for p in finished { @@ -11,11 +11,7 @@ reactor Some(value: usize(30)) { } main reactor { + some = new Some(value = 20) - some = new Some(value=20); - - reaction (some.finished) {= - println!("success"); - =} - + reaction(some.finished) {= println!("success"); =} } diff --git a/test/Rust/src/multiport/WriteInputOfContainedBank.lf b/test/Rust/src/multiport/WriteInputOfContainedBank.lf index f8a0463510..ab7cbee438 100644 --- a/test/Rust/src/multiport/WriteInputOfContainedBank.lf +++ b/test/Rust/src/multiport/WriteInputOfContainedBank.lf @@ -1,10 +1,12 @@ // Test writing inputs to a contained reactor bank -target Rust; -reactor Contained(bank_index:usize(0)) { - state bank_index(bank_index); +target Rust + +reactor Contained(bank_index: usize(0)) { + state bank_index(bank_index) + + input inpt: usize + state count: usize(0) - input inpt:usize; - state count:usize(0); reaction(inpt) {= let result = ctx.get(inpt).unwrap(); println!("Instance {} received {}", self.bank_index, result); @@ -14,6 +16,7 @@ reactor Contained(bank_index:usize(0)) { } self.count += 1; =} + reaction(shutdown) {= if self.count != 1 { eprintln!("ERROR: One of the reactions failed to trigger."); @@ -23,7 +26,8 @@ reactor Contained(bank_index:usize(0)) { } main reactor { - c = new[4] Contained(); + c = new[4] Contained() + reaction(startup) -> c.inpt {= for i in 0..c__inpt.len() { ctx.set(c__inpt.get(i), i * 42); From 54798683ce0f23fb952cc52ca6ad8587ca1eb105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 25 Nov 2022 17:20:48 +0100 Subject: [PATCH 13/16] Fixes to accomodate latest rust runtime --- org.lflang/src/lib/rs/reactor-rs | 2 +- org.lflang/src/org/lflang/generator/rust/PortEmitter.kt | 4 ++-- .../src/org/lflang/generator/rust/RustReactorEmitter.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/org.lflang/src/lib/rs/reactor-rs b/org.lflang/src/lib/rs/reactor-rs index bef9d10abd..7c66cce63f 160000 --- a/org.lflang/src/lib/rs/reactor-rs +++ b/org.lflang/src/lib/rs/reactor-rs @@ -1 +1 @@ -Subproject commit bef9d10abde77dc95336cba8cda18032070aba15 +Subproject commit 7c66cce63fdf041e6c3b5f32e0b50a5dc32b647e diff --git a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt index 3d8da21681..5567b7b12c 100644 --- a/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/PortEmitter.kt @@ -63,8 +63,8 @@ object PortEmitter : RustEmitterBase() { val child = "&mut $rustChildName.$rustFieldOnChildName" return if (isGeneratedAsMultiport) { - var lhsPorts = "$child.into_iter()" - var rhsPorts = "$self.into_iter()" + var lhsPorts = "$child.iter_mut()" + var rhsPorts = "$self.iter_mut()" if (isContainedInBank && !isMultiport) { lhsPorts = "unsafe_iter_bank!($rustChildName # $rustFieldOnChildName)" diff --git a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt index 8b93f25796..46be14327e 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustReactorEmitter.kt @@ -388,7 +388,7 @@ ${" | "..declareChildConnections()} } is ChildPortReference -> { if (isGeneratedAsMultiport) { - "__assembler.new_port_bank::<$dataType>(\"$childLfName.$lfName\", $portKind, $privateParamsVarName.$widthParamName)?" + "__assembler.new_multiport::<$dataType>(\"$childLfName.$lfName\", $portKind, $privateParamsVarName.$widthParamName)?" } else { "__assembler.new_port::<$dataType>(\"$childLfName.$lfName\", $portKind)" } From 97a55fc4fa7bf7cdc96cac68a9bf4041c2847043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 12 Dec 2022 14:42:12 +0100 Subject: [PATCH 14/16] Bump runtime --- org.lflang/src/lib/rs/reactor-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/lib/rs/reactor-rs b/org.lflang/src/lib/rs/reactor-rs index 7c66cce63f..4d6c781a14 160000 --- a/org.lflang/src/lib/rs/reactor-rs +++ b/org.lflang/src/lib/rs/reactor-rs @@ -1 +1 @@ -Subproject commit 7c66cce63fdf041e6c3b5f32e0b50a5dc32b647e +Subproject commit 4d6c781a14fdf512ae336caf5947f6645bcb40e5 From d53542a4696622c366cefc72bb36edd1cb2a2a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 5 Jan 2023 14:33:08 +0100 Subject: [PATCH 15/16] Bump rust rt --- org.lflang/src/lib/rs/reactor-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/lib/rs/reactor-rs b/org.lflang/src/lib/rs/reactor-rs index 4d6c781a14..98991f3c3c 160000 --- a/org.lflang/src/lib/rs/reactor-rs +++ b/org.lflang/src/lib/rs/reactor-rs @@ -1 +1 @@ -Subproject commit 4d6c781a14fdf512ae336caf5947f6645bcb40e5 +Subproject commit 98991f3c3ce360cfc67511103bb58511f6faba06 From bc931775ee4cb67d7e63dd7da507c64be353a156 Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Mon, 9 Jan 2023 13:26:57 +0100 Subject: [PATCH 16/16] bumb rust runtime version to current main branch --- org.lflang/src/lib/rs/runtime-version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/lib/rs/runtime-version.properties b/org.lflang/src/lib/rs/runtime-version.properties index 40b186ddbc..66b91bb698 100644 --- a/org.lflang/src/lib/rs/runtime-version.properties +++ b/org.lflang/src/lib/rs/runtime-version.properties @@ -1 +1 @@ -rs = 4d6c781a14fdf512ae336caf5947f6645bcb40e5 +rs = 98991f3c3ce360cfc67511103bb58511f6faba06