From c9649e30e8f804b797d151a642c00d45958bb2b5 Mon Sep 17 00:00:00 2001 From: depetrol Date: Fri, 4 Oct 2024 17:09:41 -0700 Subject: [PATCH 1/8] feat: forever time literal --- .../main/java/org/lflang/LinguaFranca.xtext | 6 ++++- .../main/java/org/lflang/ast/ASTUtils.java | 26 +++++++++++++++++++ .../org/lflang/generator/TargetTypes.java | 2 ++ test/Python/src/federated/Dataflow.lf | 10 +++---- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index ba45b3bd0c..11275cc82f 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -392,8 +392,12 @@ SignedInt: INT | NEGINT ; +Forever: + 'FOREVER' | 'forever' +; + Literal: - STRING | CHAR_LIT | SignedFloat | SignedInt | Boolean + STRING | CHAR_LIT | SignedFloat | SignedInt | Boolean | Forever ; Boolean: diff --git a/core/src/main/java/org/lflang/ast/ASTUtils.java b/core/src/main/java/org/lflang/ast/ASTUtils.java index 4f4f843fd3..5f2d3dd526 100644 --- a/core/src/main/java/org/lflang/ast/ASTUtils.java +++ b/core/src/main/java/org/lflang/ast/ASTUtils.java @@ -944,6 +944,17 @@ public static boolean isZero(String literal) { return false; } + /** + * Report whether the given literal is forever or not. + * + * @param literal AST node to inspect. + * @return True if the given literal denotes the constant {@code FOREVER} or {@code forever}, false otherwise. + */ + public static boolean isForever(String literal) { + return literal != null && (literal.equals("FOREVER") || literal.equals("forever")); + } + + /** * Report whether the given expression is zero or not. * @@ -957,6 +968,19 @@ public static boolean isZero(Expression expr) { return false; } + /** + * Report whether the given expression is forever or not. + * + * @param expr AST node to inspect. + * @return True if the given value denotes the constant {@code FOREVER} or {@code forever}, false otherwise. + */ + public static boolean isForever(Expression expr) { + if (expr instanceof Literal) { + return isForever(((Literal) expr).getLiteral()); + } + return false; + } + /** * Report whether the given string literal is an integer number or not. * @@ -1137,6 +1161,8 @@ public static TimeValue getLiteralTimeValue(Expression expr) { return toTimeValue((Time) expr); } else if (expr instanceof Literal && isZero(((Literal) expr).getLiteral())) { return TimeValue.ZERO; + } else if (expr instanceof Literal && isForever(((Literal) expr).getLiteral())) { + return TimeValue.MAX_VALUE; } else { return null; } diff --git a/core/src/main/java/org/lflang/generator/TargetTypes.java b/core/src/main/java/org/lflang/generator/TargetTypes.java index 86bad63818..4291cdc45e 100644 --- a/core/src/main/java/org/lflang/generator/TargetTypes.java +++ b/core/src/main/java/org/lflang/generator/TargetTypes.java @@ -176,6 +176,8 @@ default String getTargetInitializer(Initializer init, Type type) { default String getTargetExpr(Expression expr, InferredType type) { if (ASTUtils.isZero(expr) && type != null && type.isTime) { return getTargetTimeExpr(TimeValue.ZERO); + } else if (ASTUtils.isForever(expr) && type != null && type.isTime) { + return getTargetTimeExpr(TimeValue.MAX_VALUE); } else if (expr instanceof ParameterReference) { return getTargetParamRef((ParameterReference) expr, type); } else if (expr instanceof Time) { diff --git a/test/Python/src/federated/Dataflow.lf b/test/Python/src/federated/Dataflow.lf index 4d33235af2..0daac98a6e 100644 --- a/test/Python/src/federated/Dataflow.lf +++ b/test/Python/src/federated/Dataflow.lf @@ -6,7 +6,7 @@ preamble {= import time =} -reactor Client(STP_offset = {= FOREVER =}) { +reactor Client(STP_offset = FOREVER) { input server_message output client_message @@ -24,13 +24,13 @@ reactor Client(STP_offset = {= FOREVER =}) { request_stop() # Need to unconditionally produce output or downstream could lock up waiting for it. client_message.set(val) - =} STP(10 s) {= + =} STP(FOREVER) {= print("Client STP Violated!") exit(1) =} } -reactor Server(STP_offset = {= FOREVER =}) { +reactor Server(STP_offset = FOREVER) { output server_message input client_message1 input client_message2 @@ -51,13 +51,13 @@ reactor Server(STP_offset = {= FOREVER =}) { request_stop() # Need to unconditionally produce output or downstream could lock up waiting for it. server_message.set(val) - =} STP(10 s) {= + =} STP(FOREVER) {= print("Server STP Violated!") exit(1) =} } -federated reactor(STP_offset = {= FOREVER =}) { +federated reactor(STP_offset = FOREVER) { client1 = new Client() client2 = new Client() server = new Server() From aea3135a2b1a59480f3729bccfe5b706773655f3 Mon Sep 17 00:00:00 2001 From: depetrol Date: Fri, 4 Oct 2024 17:13:07 -0700 Subject: [PATCH 2/8] change STP to STA and STAA --- core/src/main/java/org/lflang/ast/ASTUtils.java | 9 +++++---- test/Python/src/federated/Dataflow.lf | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/lflang/ast/ASTUtils.java b/core/src/main/java/org/lflang/ast/ASTUtils.java index 5f2d3dd526..a7e1c80595 100644 --- a/core/src/main/java/org/lflang/ast/ASTUtils.java +++ b/core/src/main/java/org/lflang/ast/ASTUtils.java @@ -948,13 +948,13 @@ public static boolean isZero(String literal) { * Report whether the given literal is forever or not. * * @param literal AST node to inspect. - * @return True if the given literal denotes the constant {@code FOREVER} or {@code forever}, false otherwise. + * @return True if the given literal denotes the constant {@code FOREVER} or {@code forever}, + * false otherwise. */ public static boolean isForever(String literal) { - return literal != null && (literal.equals("FOREVER") || literal.equals("forever")); + return literal != null && (literal.equals("FOREVER") || literal.equals("forever")); } - /** * Report whether the given expression is zero or not. * @@ -972,7 +972,8 @@ public static boolean isZero(Expression expr) { * Report whether the given expression is forever or not. * * @param expr AST node to inspect. - * @return True if the given value denotes the constant {@code FOREVER} or {@code forever}, false otherwise. + * @return True if the given value denotes the constant {@code FOREVER} or {@code forever}, false + * otherwise. */ public static boolean isForever(Expression expr) { if (expr instanceof Literal) { diff --git a/test/Python/src/federated/Dataflow.lf b/test/Python/src/federated/Dataflow.lf index 0daac98a6e..892af49649 100644 --- a/test/Python/src/federated/Dataflow.lf +++ b/test/Python/src/federated/Dataflow.lf @@ -6,7 +6,7 @@ preamble {= import time =} -reactor Client(STP_offset = FOREVER) { +reactor Client(STA=FOREVER) { input server_message output client_message @@ -25,12 +25,12 @@ reactor Client(STP_offset = FOREVER) { # Need to unconditionally produce output or downstream could lock up waiting for it. client_message.set(val) =} STP(FOREVER) {= - print("Client STP Violated!") + print("Client STAA Violated!") exit(1) =} } -reactor Server(STP_offset = FOREVER) { +reactor Server(STA=FOREVER) { output server_message input client_message1 input client_message2 @@ -52,12 +52,12 @@ reactor Server(STP_offset = FOREVER) { # Need to unconditionally produce output or downstream could lock up waiting for it. server_message.set(val) =} STP(FOREVER) {= - print("Server STP Violated!") + print("Server STAA Violated!") exit(1) =} } -federated reactor(STP_offset = FOREVER) { +federated reactor(STA=FOREVER) { client1 = new Client() client2 = new Client() server = new Server() From 460eb50f0937f3c51b09feccbc21b7be7fa55262 Mon Sep 17 00:00:00 2001 From: Depetrol Date: Sun, 6 Oct 2024 22:52:13 -0700 Subject: [PATCH 3/8] only lowercase forever literal --- core/src/main/java/org/lflang/LinguaFranca.xtext | 2 +- core/src/main/java/org/lflang/ast/ASTUtils.java | 8 +++----- test/Python/src/federated/Dataflow.lf | 10 +++++----- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index 11275cc82f..b3421a37be 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -393,7 +393,7 @@ SignedInt: ; Forever: - 'FOREVER' | 'forever' + 'forever' ; Literal: diff --git a/core/src/main/java/org/lflang/ast/ASTUtils.java b/core/src/main/java/org/lflang/ast/ASTUtils.java index a7e1c80595..24be720870 100644 --- a/core/src/main/java/org/lflang/ast/ASTUtils.java +++ b/core/src/main/java/org/lflang/ast/ASTUtils.java @@ -948,11 +948,10 @@ public static boolean isZero(String literal) { * Report whether the given literal is forever or not. * * @param literal AST node to inspect. - * @return True if the given literal denotes the constant {@code FOREVER} or {@code forever}, - * false otherwise. + * @return True if the given literal denotes the constant {@code forever}, false otherwise. */ public static boolean isForever(String literal) { - return literal != null && (literal.equals("FOREVER") || literal.equals("forever")); + return literal != null && literal.equals("forever"); } /** @@ -972,8 +971,7 @@ public static boolean isZero(Expression expr) { * Report whether the given expression is forever or not. * * @param expr AST node to inspect. - * @return True if the given value denotes the constant {@code FOREVER} or {@code forever}, false - * otherwise. + * @return True if the given value denotes the constant {@code forever}, false otherwise. */ public static boolean isForever(Expression expr) { if (expr instanceof Literal) { diff --git a/test/Python/src/federated/Dataflow.lf b/test/Python/src/federated/Dataflow.lf index 892af49649..fb6625abde 100644 --- a/test/Python/src/federated/Dataflow.lf +++ b/test/Python/src/federated/Dataflow.lf @@ -6,7 +6,7 @@ preamble {= import time =} -reactor Client(STA=FOREVER) { +reactor Client(STA=forever) { input server_message output client_message @@ -24,13 +24,13 @@ reactor Client(STA=FOREVER) { request_stop() # Need to unconditionally produce output or downstream could lock up waiting for it. client_message.set(val) - =} STP(FOREVER) {= + =} STP(forever) {= print("Client STAA Violated!") exit(1) =} } -reactor Server(STA=FOREVER) { +reactor Server(STA=forever) { output server_message input client_message1 input client_message2 @@ -51,13 +51,13 @@ reactor Server(STA=FOREVER) { request_stop() # Need to unconditionally produce output or downstream could lock up waiting for it. server_message.set(val) - =} STP(FOREVER) {= + =} STP(forever) {= print("Server STAA Violated!") exit(1) =} } -federated reactor(STA=FOREVER) { +federated reactor(STA=forever) { client1 = new Client() client2 = new Client() server = new Server() From b29f02991a07fad64eb78c7de54206556b44854e Mon Sep 17 00:00:00 2001 From: depetrol Date: Mon, 7 Oct 2024 10:10:02 -0700 Subject: [PATCH 4/8] fix --- core/src/main/java/org/lflang/generator/TargetTypes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/lflang/generator/TargetTypes.java b/core/src/main/java/org/lflang/generator/TargetTypes.java index 4291cdc45e..24ef724283 100644 --- a/core/src/main/java/org/lflang/generator/TargetTypes.java +++ b/core/src/main/java/org/lflang/generator/TargetTypes.java @@ -176,7 +176,7 @@ default String getTargetInitializer(Initializer init, Type type) { default String getTargetExpr(Expression expr, InferredType type) { if (ASTUtils.isZero(expr) && type != null && type.isTime) { return getTargetTimeExpr(TimeValue.ZERO); - } else if (ASTUtils.isForever(expr) && type != null && type.isTime) { + } else if (ASTUtils.isForever(expr) && type != null) { return getTargetTimeExpr(TimeValue.MAX_VALUE); } else if (expr instanceof ParameterReference) { return getTargetParamRef((ParameterReference) expr, type); From 36b6922ce0a2b9b34229ac801c3723f8f5bbf236 Mon Sep 17 00:00:00 2001 From: Depetrol Date: Mon, 7 Oct 2024 22:16:35 -0700 Subject: [PATCH 5/8] fix: add forever to token --- core/src/main/java/org/lflang/LinguaFranca.xtext | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index b3421a37be..5aa9b1b51c 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -525,7 +525,7 @@ Token: 'startup' | 'shutdown' | 'after' | 'deadline' | 'mutation' | 'preamble' | 'new' | 'federated' | 'at' | 'as' | 'from' | 'widthof' | 'const' | 'method' | 'interleaved' | 'mode' | 'initial' | 'reset' | 'history' | 'watchdog' | - 'extends' | + 'extends' | 'forever' | // Other terminals NEGINT | TRUE | FALSE | From c04cc4026f3133f1e7627599adff0f5ab4fa0fcc Mon Sep 17 00:00:00 2001 From: Depetrol Date: Mon, 7 Oct 2024 22:47:53 -0700 Subject: [PATCH 6/8] feat: introduce never time literal --- .../main/java/org/lflang/LinguaFranca.xtext | 10 ++++--- core/src/main/java/org/lflang/TimeValue.java | 3 +++ .../main/java/org/lflang/ast/ASTUtils.java | 26 +++++++++++++++++++ .../org/lflang/generator/TargetTypes.java | 3 +++ .../org/lflang/validation/LFValidator.java | 8 ++++++ test/C/src/LastTimeDefer.lf | 8 +----- test/C/src/LastTimeDrop.lf | 8 +----- test/C/src/LastTimeReplace.lf | 8 +----- 8 files changed, 50 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index 5aa9b1b51c..1cbfa9d282 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -339,7 +339,7 @@ ParameterReference: ; Time: - (interval=INT unit=TimeUnit) + (interval=INT unit=TimeUnit) | Forever | Never ; Port: @@ -396,8 +396,12 @@ Forever: 'forever' ; +Never: + 'never' +; + Literal: - STRING | CHAR_LIT | SignedFloat | SignedInt | Boolean | Forever + STRING | CHAR_LIT | SignedFloat | SignedInt | Boolean | Forever | Never ; Boolean: @@ -525,7 +529,7 @@ Token: 'startup' | 'shutdown' | 'after' | 'deadline' | 'mutation' | 'preamble' | 'new' | 'federated' | 'at' | 'as' | 'from' | 'widthof' | 'const' | 'method' | 'interleaved' | 'mode' | 'initial' | 'reset' | 'history' | 'watchdog' | - 'extends' | 'forever' | + 'extends' | 'forever' | 'never' | // Other terminals NEGINT | TRUE | FALSE | diff --git a/core/src/main/java/org/lflang/TimeValue.java b/core/src/main/java/org/lflang/TimeValue.java index f393544c5a..832e9c754b 100644 --- a/core/src/main/java/org/lflang/TimeValue.java +++ b/core/src/main/java/org/lflang/TimeValue.java @@ -36,6 +36,9 @@ public final class TimeValue implements Comparable { /** The maximum value of this type. This is approximately equal to 292 years. */ public static final TimeValue MAX_VALUE = new TimeValue(Long.MAX_VALUE, TimeUnit.NANO); + /** The minimum value of this type. */ + public static final TimeValue MIN_VALUE = new TimeValue(Long.MIN_VALUE, TimeUnit.NANO); + /** A time value equal to zero. */ public static final TimeValue ZERO = new TimeValue(0, null); diff --git a/core/src/main/java/org/lflang/ast/ASTUtils.java b/core/src/main/java/org/lflang/ast/ASTUtils.java index 24be720870..a7cb5eefa3 100644 --- a/core/src/main/java/org/lflang/ast/ASTUtils.java +++ b/core/src/main/java/org/lflang/ast/ASTUtils.java @@ -954,6 +954,17 @@ public static boolean isForever(String literal) { return literal != null && literal.equals("forever"); } + + /** + * Report whether the given literal is never or not. + * + * @param literal AST node to inspect. + * @return True if the given literal denotes the constant {@code never}, false otherwise. + */ + public static boolean isNever(String literal) { + return literal != null && literal.equals("never"); + } + /** * Report whether the given expression is zero or not. * @@ -980,6 +991,19 @@ public static boolean isForever(Expression expr) { return false; } + /** + * Report whether the given expression is never or not. + * + * @param expr AST node to inspect. + * @return True if the given value denotes the constant {@code never}, false otherwise. + */ + public static boolean isNever(Expression expr) { + if (expr instanceof Literal) { + return isNever(((Literal) expr).getLiteral()); + } + return false; + } + /** * Report whether the given string literal is an integer number or not. * @@ -1162,6 +1186,8 @@ public static TimeValue getLiteralTimeValue(Expression expr) { return TimeValue.ZERO; } else if (expr instanceof Literal && isForever(((Literal) expr).getLiteral())) { return TimeValue.MAX_VALUE; + } else if (expr instanceof Literal && isNever(((Literal) expr).getLiteral())) { + return TimeValue.MIN_VALUE; } else { return null; } diff --git a/core/src/main/java/org/lflang/generator/TargetTypes.java b/core/src/main/java/org/lflang/generator/TargetTypes.java index 24ef724283..59e2570047 100644 --- a/core/src/main/java/org/lflang/generator/TargetTypes.java +++ b/core/src/main/java/org/lflang/generator/TargetTypes.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.stream.Collectors; + import org.lflang.InferredType; import org.lflang.TimeValue; import org.lflang.ast.ASTUtils; @@ -178,6 +179,8 @@ default String getTargetExpr(Expression expr, InferredType type) { return getTargetTimeExpr(TimeValue.ZERO); } else if (ASTUtils.isForever(expr) && type != null) { return getTargetTimeExpr(TimeValue.MAX_VALUE); + } else if (ASTUtils.isNever(expr) && type != null) { + return getTargetTimeExpr(TimeValue.MIN_VALUE); } else if (expr instanceof ParameterReference) { return getTargetParamRef((ParameterReference) expr, type); } else if (expr instanceof Time) { diff --git a/core/src/main/java/org/lflang/validation/LFValidator.java b/core/src/main/java/org/lflang/validation/LFValidator.java index 4c5f87fc6a..eb721cf032 100644 --- a/core/src/main/java/org/lflang/validation/LFValidator.java +++ b/core/src/main/java/org/lflang/validation/LFValidator.java @@ -1594,6 +1594,14 @@ private void checkExpressionIsTime(Expression value, EStructuralFeature feature) return; } + if (ASTUtils.isForever(((Literal) value).getLiteral())) { + return; + } + + if (ASTUtils.isNever(((Literal) value).getLiteral())) { + return; + } + if (ASTUtils.isInteger(((Literal) value).getLiteral())) { error("Missing time unit.", feature); return; diff --git a/test/C/src/LastTimeDefer.lf b/test/C/src/LastTimeDefer.lf index 2509a5e896..65001bdc9c 100644 --- a/test/C/src/LastTimeDefer.lf +++ b/test/C/src/LastTimeDefer.lf @@ -9,13 +9,7 @@ main reactor { logical action a(1 ms, 300 ms): int state c: int = 0 state c2: int = 0 // For expected values. - state last: time = 0 - - reaction(startup) {= - // Unfortunately, a time state variable cannot be initialized with NEVER. - // So we do that here. - self->last = NEVER; - =} + state last: time = never reaction(t) -> a {= tag_t now = lf_tag(); diff --git a/test/C/src/LastTimeDrop.lf b/test/C/src/LastTimeDrop.lf index 2862ac75f0..5cfc7c2ad2 100644 --- a/test/C/src/LastTimeDrop.lf +++ b/test/C/src/LastTimeDrop.lf @@ -8,13 +8,7 @@ main reactor { timer t(0, 100 ms) logical action a(1 ms, 300 ms, "drop"): int state c: int = 0 - state last: time = 0 - - reaction(startup) {= - // Unfortunately, a time state variable cannot be initialized with NEVER. - // So we do that here. - self->last = NEVER; - =} + state last: time = never reaction(t) -> a {= tag_t now = lf_tag(); diff --git a/test/C/src/LastTimeReplace.lf b/test/C/src/LastTimeReplace.lf index 0d44bb58b5..51b29f972a 100644 --- a/test/C/src/LastTimeReplace.lf +++ b/test/C/src/LastTimeReplace.lf @@ -8,13 +8,7 @@ main reactor { timer t(0, 100 ms) logical action a(1 ms, 300 ms, "replace"): int state c: int = 0 - state last: time = 0 - - reaction(startup) {= - // Unfortunately, a time state variable cannot be initialized with NEVER. - // So we do that here. - self->last = NEVER; - =} + state last: time = never reaction(t) -> a {= tag_t now = lf_tag(); From eceb36708c13142eeee30388e94af6dc825ec540 Mon Sep 17 00:00:00 2001 From: Depetrol Date: Mon, 7 Oct 2024 23:04:33 -0700 Subject: [PATCH 7/8] feat: allow FOREVER and NEVER --- core/src/main/java/org/lflang/LinguaFranca.xtext | 8 ++++---- core/src/main/java/org/lflang/ast/ASTUtils.java | 15 ++++++++------- .../java/org/lflang/generator/TargetTypes.java | 3 +-- .../C/src/modal_models/BanksCount3ModesComplex.lf | 6 +++--- test/C/src/modal_models/ModalNestedReactions.lf | 8 ++++---- .../src/modal_models/BanksCount3ModesComplex.lf | 6 +++--- .../src/modal_models/ModalNestedReactions.lf | 8 ++++---- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index 1cbfa9d282..09401074a6 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -339,7 +339,7 @@ ParameterReference: ; Time: - (interval=INT unit=TimeUnit) | Forever | Never + (interval=INT unit=TimeUnit) ; Port: @@ -393,11 +393,11 @@ SignedInt: ; Forever: - 'forever' + 'forever' | 'FOREVER' ; Never: - 'never' + 'never' | 'NEVER' ; Literal: @@ -529,7 +529,7 @@ Token: 'startup' | 'shutdown' | 'after' | 'deadline' | 'mutation' | 'preamble' | 'new' | 'federated' | 'at' | 'as' | 'from' | 'widthof' | 'const' | 'method' | 'interleaved' | 'mode' | 'initial' | 'reset' | 'history' | 'watchdog' | - 'extends' | 'forever' | 'never' | + 'extends' | 'forever' | 'FOREVER' | 'never' | 'NEVER' | // Other terminals NEGINT | TRUE | FALSE | diff --git a/core/src/main/java/org/lflang/ast/ASTUtils.java b/core/src/main/java/org/lflang/ast/ASTUtils.java index a7cb5eefa3..5cd0be1129 100644 --- a/core/src/main/java/org/lflang/ast/ASTUtils.java +++ b/core/src/main/java/org/lflang/ast/ASTUtils.java @@ -948,23 +948,24 @@ public static boolean isZero(String literal) { * Report whether the given literal is forever or not. * * @param literal AST node to inspect. - * @return True if the given literal denotes the constant {@code forever}, false otherwise. + * @return True if the given literal denotes the constant {@code forever} or {@code FOREVER}, + * false otherwise. */ public static boolean isForever(String literal) { - return literal != null && literal.equals("forever"); + return literal != null && (literal.equals("forever") || literal.equals("FOREVER")); } - /** * Report whether the given literal is never or not. * * @param literal AST node to inspect. - * @return True if the given literal denotes the constant {@code never}, false otherwise. + * @return True if the given literal denotes the constant {@code never} or {@code NEVER}, false + * otherwise. */ public static boolean isNever(String literal) { - return literal != null && literal.equals("never"); + return literal != null && (literal.equals("never") || literal.equals("NEVER")); } - + /** * Report whether the given expression is zero or not. * @@ -1187,7 +1188,7 @@ public static TimeValue getLiteralTimeValue(Expression expr) { } else if (expr instanceof Literal && isForever(((Literal) expr).getLiteral())) { return TimeValue.MAX_VALUE; } else if (expr instanceof Literal && isNever(((Literal) expr).getLiteral())) { - return TimeValue.MIN_VALUE; + return TimeValue.MIN_VALUE; } else { return null; } diff --git a/core/src/main/java/org/lflang/generator/TargetTypes.java b/core/src/main/java/org/lflang/generator/TargetTypes.java index 59e2570047..42d3e62064 100644 --- a/core/src/main/java/org/lflang/generator/TargetTypes.java +++ b/core/src/main/java/org/lflang/generator/TargetTypes.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.stream.Collectors; - import org.lflang.InferredType; import org.lflang.TimeValue; import org.lflang.ast.ASTUtils; @@ -180,7 +179,7 @@ default String getTargetExpr(Expression expr, InferredType type) { } else if (ASTUtils.isForever(expr) && type != null) { return getTargetTimeExpr(TimeValue.MAX_VALUE); } else if (ASTUtils.isNever(expr) && type != null) { - return getTargetTimeExpr(TimeValue.MIN_VALUE); + return getTargetTimeExpr(TimeValue.MIN_VALUE); } else if (expr instanceof ParameterReference) { return getTargetParamRef((ParameterReference) expr, type); } else if (expr instanceof Time) { diff --git a/test/C/src/modal_models/BanksCount3ModesComplex.lf b/test/C/src/modal_models/BanksCount3ModesComplex.lf index 48774e0b80..1385573be0 100644 --- a/test/C/src/modal_models/BanksCount3ModesComplex.lf +++ b/test/C/src/modal_models/BanksCount3ModesComplex.lf @@ -12,7 +12,7 @@ reactor MetaCounter { output[2] always: int output[2] mode1: int output[2] mode2: int - output[2] never: int + output[2] neverp: int outer_counters = new[2] CounterCycle() (next)+ -> outer_counters.next @@ -46,7 +46,7 @@ reactor MetaCounter { mode3_counters = new[2] CounterCycle() (next)+ -> mode3_counters.next - mode3_counters.count -> never + mode3_counters.count -> neverp } } @@ -72,7 +72,7 @@ main reactor { 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) - counters.always, counters.mode1, counters.mode2, counters.never -> test.events + counters.always, counters.mode1, counters.mode2, counters.neverp -> test.events // Trigger reaction(stepper) -> counters.next {= diff --git a/test/C/src/modal_models/ModalNestedReactions.lf b/test/C/src/modal_models/ModalNestedReactions.lf index 88bb61c8bb..90b04674ce 100644 --- a/test/C/src/modal_models/ModalNestedReactions.lf +++ b/test/C/src/modal_models/ModalNestedReactions.lf @@ -9,7 +9,7 @@ reactor CounterCycle { output count: int output only_in_two: bool - output never: int + output neverp: int initial mode One { reaction(next) -> count, reset(Two) {= @@ -29,8 +29,8 @@ reactor CounterCycle { } mode Three { - reaction(next) -> never {= - lf_set(never, true); + reaction(next) -> neverp {= + lf_set(neverp, true); =} } } @@ -69,7 +69,7 @@ main reactor { } =} - reaction(counter.never) {= + reaction(counter.neverp) {= printf("ERROR: Detected output from unreachable mode.\n"); exit(4); =} diff --git a/test/Python/src/modal_models/BanksCount3ModesComplex.lf b/test/Python/src/modal_models/BanksCount3ModesComplex.lf index 77b8461861..fde46b539c 100644 --- a/test/Python/src/modal_models/BanksCount3ModesComplex.lf +++ b/test/Python/src/modal_models/BanksCount3ModesComplex.lf @@ -12,7 +12,7 @@ reactor MetaCounter { output[2] always output[2] mode1 output[2] mode2 - output[2] never + output[2] neverp outer_counters = new[2] CounterCycle() (next)+ -> outer_counters.next @@ -46,7 +46,7 @@ reactor MetaCounter { mode3_counters = new[2] CounterCycle() (next)+ -> mode3_counters.next - mode3_counters.count -> never + mode3_counters.count -> neverp } } @@ -69,7 +69,7 @@ main reactor { 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) - counters.always, counters.mode1, counters.mode2, counters.never -> test.events + counters.always, counters.mode1, counters.mode2, counters.neverp -> test.events # Trigger reaction(stepper) -> counters.next {= diff --git a/test/Python/src/modal_models/ModalNestedReactions.lf b/test/Python/src/modal_models/ModalNestedReactions.lf index a3b89c997a..5ce8f1b529 100644 --- a/test/Python/src/modal_models/ModalNestedReactions.lf +++ b/test/Python/src/modal_models/ModalNestedReactions.lf @@ -9,7 +9,7 @@ reactor CounterCycle { output count output only_in_two - output never + output neverp initial mode One { reaction(next) -> count, reset(Two) {= @@ -29,8 +29,8 @@ reactor CounterCycle { } mode Three { - reaction(next) -> never {= - never.set(True) + reaction(next) -> neverp {= + neverp.set(True) =} } } @@ -68,7 +68,7 @@ main reactor { exit(3) =} - reaction(counter.never) {= + reaction(counter.neverp) {= sys.stderr.write("ERROR: Detected output from unreachable mode.\n") exit(4) =} From de7723cec2f73d46c532094158cfd04c0c5e23fd Mon Sep 17 00:00:00 2001 From: Depetrol Date: Tue, 8 Oct 2024 08:49:42 -0700 Subject: [PATCH 8/8] revert allow FOREVER and NEVER --- core/src/main/java/org/lflang/LinguaFranca.xtext | 6 +++--- core/src/main/java/org/lflang/ast/ASTUtils.java | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index 09401074a6..103224e23c 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -393,11 +393,11 @@ SignedInt: ; Forever: - 'forever' | 'FOREVER' + 'forever' ; Never: - 'never' | 'NEVER' + 'never' ; Literal: @@ -529,7 +529,7 @@ Token: 'startup' | 'shutdown' | 'after' | 'deadline' | 'mutation' | 'preamble' | 'new' | 'federated' | 'at' | 'as' | 'from' | 'widthof' | 'const' | 'method' | 'interleaved' | 'mode' | 'initial' | 'reset' | 'history' | 'watchdog' | - 'extends' | 'forever' | 'FOREVER' | 'never' | 'NEVER' | + 'extends' | 'forever' | 'never' | // Other terminals NEGINT | TRUE | FALSE | diff --git a/core/src/main/java/org/lflang/ast/ASTUtils.java b/core/src/main/java/org/lflang/ast/ASTUtils.java index 5cd0be1129..7e55e3cabc 100644 --- a/core/src/main/java/org/lflang/ast/ASTUtils.java +++ b/core/src/main/java/org/lflang/ast/ASTUtils.java @@ -948,22 +948,20 @@ public static boolean isZero(String literal) { * Report whether the given literal is forever or not. * * @param literal AST node to inspect. - * @return True if the given literal denotes the constant {@code forever} or {@code FOREVER}, - * false otherwise. + * @return True if the given literal denotes the constant {@code forever}, false otherwise. */ public static boolean isForever(String literal) { - return literal != null && (literal.equals("forever") || literal.equals("FOREVER")); + return literal != null && literal.equals("forever"); } /** * Report whether the given literal is never or not. * * @param literal AST node to inspect. - * @return True if the given literal denotes the constant {@code never} or {@code NEVER}, false - * otherwise. + * @return True if the given literal denotes the constant {@code never}, false otherwise. */ public static boolean isNever(String literal) { - return literal != null && (literal.equals("never") || literal.equals("NEVER")); + return literal != null && literal.equals("never"); } /**