Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Equals initializer syntax #1580

Merged
merged 60 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
89505d9
Add equals initializer syntax
oowekyala Feb 1, 2023
b9e5f52
Update formatter
oowekyala Feb 1, 2023
5021ab5
Add deprecation warning
oowekyala Feb 1, 2023
2c00c20
Format Rust tests
oowekyala Feb 1, 2023
436ab1f
Turn off validator warnings in LFC
oowekyala Feb 1, 2023
4e41dee
Format remaining test files
oowekyala Feb 1, 2023
99fdf82
Format remaining tests
oowekyala Feb 1, 2023
bd7522a
Improve warning
oowekyala Feb 2, 2023
bf3ad07
Format C++ tests
oowekyala Feb 2, 2023
2270109
Codegen C++ assignment differently
oowekyala Feb 2, 2023
78eacad
Probably fix C++ gen
oowekyala Feb 2, 2023
1485833
Fix some problems
oowekyala Feb 3, 2023
cd1bafe
Merge branch 'master' into clem.new-equals-initializers
oowekyala Feb 15, 2023
67e545e
Fix C++ paren initializers
oowekyala Feb 15, 2023
09ba2d1
Format
oowekyala Feb 15, 2023
cdf8450
Merge branch 'master' into clem.new-equals-initializers
oowekyala Feb 20, 2023
753ec48
Format tests
oowekyala Feb 20, 2023
a5d4b7a
Merge branch 'master' into clem.new-equals-initializers
oowekyala Feb 28, 2023
2eb7412
Add braced list expression
oowekyala Mar 1, 2023
93063cb
Improve CTypes and cleanup GeneratorBase
oowekyala Mar 1, 2023
437d89e
Add an expression visitor
oowekyala Mar 2, 2023
fd7f18e
Merge branch 'master' into clem.new-equals-initializers
oowekyala Mar 2, 2023
1be1651
Fix build
oowekyala Mar 2, 2023
346a00e
Merge branch 'master' into clem.new-equals-initializers
oowekyala Mar 10, 2023
5909324
Better error message for RoundTripTests
oowekyala Mar 10, 2023
e3b9622
Make LFF ignore errors
oowekyala Mar 10, 2023
fbed653
Change formatter
oowekyala Mar 13, 2023
294c3d0
Doc
oowekyala Mar 13, 2023
3752f25
Merge branch 'master' into clem.new-equals-initializers
oowekyala Mar 13, 2023
0e4ccf4
Fix NPE
oowekyala Mar 13, 2023
d20706a
Fix python using C boolean literals
oowekyala Mar 13, 2023
6a56de7
enable move construction of the parameter struct
cmnrd Mar 14, 2023
36d6926
add C++ test using the different initializer syntax options
cmnrd Mar 14, 2023
3a5015a
do not omit empty initializes when formatting
cmnrd Mar 14, 2023
2c4d21f
make sure empty braces are inserted in the generated code
cmnrd Mar 14, 2023
897a5f6
Merge remote-tracking branch 'origin/master' into clem.new-equals-ini…
oowekyala Mar 14, 2023
4b4f428
Add tests for empty lists
oowekyala Mar 14, 2023
90f2e3f
Fix errors with empty lists
oowekyala Mar 14, 2023
e43a51f
update C++ test
cmnrd Mar 14, 2023
088dab0
formatting
cmnrd Mar 14, 2023
2b7326f
implement isEqual for BracedListExpression
cmnrd Mar 14, 2023
c6eeb70
formatting
cmnrd Mar 14, 2023
8363483
Format
oowekyala Mar 14, 2023
c4f4540
respect parameter assignments in C
cmnrd Mar 15, 2023
06617d1
also respect parameter assignment in Python
cmnrd Mar 15, 2023
ebdb0b3
fix python names
cmnrd Mar 15, 2023
fb2b57d
Cleanup in ParameterInstance
oowekyala Mar 15, 2023
2df3c8f
Further cleanup
oowekyala Mar 15, 2023
a4baf3f
Merge remote-tracking branch 'origin/master' into clem.new-equals-ini…
oowekyala Mar 15, 2023
8cc6fec
Cleanup
oowekyala Mar 15, 2023
80b0d5f
Fix C test
oowekyala Mar 15, 2023
ae346b1
Revert a change
oowekyala Mar 16, 2023
b9d8ab8
Merge branch 'master' into clem.new-equals-initializers
oowekyala Mar 16, 2023
e8162ee
Merge branch 'master' into clem.new-equals-initializers
cmnrd Mar 18, 2023
2341c55
Fix toText for synthetic nodes
oowekyala Mar 18, 2023
e982955
Merge branch 'master' into clem.new-equals-initializers
oowekyala Mar 22, 2023
8a130e4
fix C tests (hopefully) for good
cmnrd Mar 24, 2023
b594f91
Don't use C23 syntax in test
cmnrd Mar 27, 2023
a9798d9
fix C test once more and apply formatting
cmnrd Mar 27, 2023
63d2fa0
Fix comment
cmnrd Mar 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void testSimple() {

@Test
public void testAssignments() {
assertIsFormatted(
assertFormatsTo(
"""
target C

Expand All @@ -43,6 +43,15 @@ public void testAssignments() {
input in: int
state last_invoked: tag_t({= NEVER_TAG_INITIALIZER =})
}
""",
"""
target C

reactor Destination {
input ok: bool
input in: int
state last_invoked: tag_t = {= NEVER_TAG_INITIALIZER =}
}
"""
);
}
Expand All @@ -56,16 +65,34 @@ public void testState() {
reactor Destination {
state one_init: tag_t( {= NEVER_TAG_INITIALIZER =})
state no_init: tag_t
state list_init(1,2)
state list_init(1,2) // this syntax is deprecated
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
}
""",
"""
target Python

reactor Destination {
state one_init: tag_t = {= NEVER_TAG_INITIALIZER =}
state no_init: tag_t
state list_init(1, 2) # this syntax is deprecated
petervdonovan marked this conversation as resolved.
Show resolved Hide resolved
}
"""
);
}

@Test
public void testCppInits() {
assertIsFormatted(
"""
target Cpp

reactor Destination {
state one_init: tag_t({= NEVER_TAG_INITIALIZER =})
state no_init: tag_t
state list_init(1, 2)
state assign: int = 0
state paren: int(0)
state brace: std::vector<int>{1, 2}
state paren_list: std::vector<int>(1, 2)
}
"""
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void testLet() throws Exception {
));

Assertions.assertNotNull(model);
final var ctypes = new CTypes(new DefaultErrorReporter());
final var ctypes = CTypes.getInstance();
final var resource = model.eResource();
final var transformation = new DelayedConnectionTransformation(new CDelayBodyGenerator(ctypes), ctypes, resource, true, true);
transformation.applyTransformation(ASTUtils.getAllReactors(resource));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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.fail;

import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -28,11 +29,15 @@
public class RoundTripTests {

@Test
public void roundTripTest() throws Exception {
public void roundTripTest() {
for (Target target : Target.values()) {
for (TestCategory category : TestCategory.values()) {
for (LFTest test : TestRegistry.getRegisteredTests(target, category, false)) {
run(test.getSrcPath());
try {
run(test.getSrcPath());
} catch (Throwable thrown) {
fail("Test case " + test.getSrcPath() + " failed", thrown);
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions org.lflang/src/org/lflang/ASTUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ public static boolean changeTargetName(Resource resource, String newTargetName)
return true;
}

/**
* Return the target of the file in which the given node lives.
*/
public static Target getTarget(EObject object) {
TargetDecl targetDecl = targetDecl(object.eResource());
return Target.fromDecl(targetDecl);
}

/**
* Add a new target property to the given resource.
*
Expand Down
19 changes: 14 additions & 5 deletions org.lflang/src/org/lflang/LinguaFranca.xtext
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ TargetDecl:
Initializer:
parens?='(' (exprs+=Expression (',' exprs+=Expression)* (trailingComma?=',')?)? ')'
| braces?='{' (exprs+=Expression (',' exprs+=Expression)* (trailingComma?=',')?)? '}'
// | assign?='=' exprs+=Expression // todo later
| assign?='=' exprs+=Expression
;


Expand Down Expand Up @@ -285,13 +285,15 @@ VarRefOrModeTransition returns VarRef:

Assignment:
lhs=[Parameter]
(equals='=')? rhs=AssignmentInitializer
rhs=AssignmentInitializer
;

// TODO Only allow = based parameter assignment
AssignmentInitializer returns Initializer:
exprs+=Expression
| parens?='(' (exprs+=Expression (',' exprs+=Expression)* (trailingComma?=',')?)? ')'
assign?='=' exprs+=Expression
// these syntaxes are legacy and now deprecated
// todo remove in future version.
| '='? parens?='(' (exprs+=Expression (',' exprs+=Expression)* (trailingComma?=',')?)? ')'
// note: the previous syntax `= { expr* }` is now parsed as a BracedListExpression
| braces?='{' (exprs+=Expression (',' exprs+=Expression)* (trailingComma?=',')?)? '}'
;

Expand All @@ -310,6 +312,13 @@ Expression:
| Time
| ParameterReference
| {CodeExpr} code=Code
| BracedListExpression
;

// A list of expressions within braces.
// In C/C++, this is an array initializer, struct initializer, or std::initializer_list.
BracedListExpression:
'{' ( items+=Expression (',' items+=Expression)* )? ','? '}'
;

ParameterReference:
Expand Down
18 changes: 15 additions & 3 deletions org.lflang/src/org/lflang/Target.java
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,7 @@ public boolean supportsMultiports() {
* on constants).
*/
public boolean supportsParameterizedWidths() {
return switch (this) {
case C, CCPP, CPP, Python, Rust, TS -> true;
};
return true;
}

/**
Expand All @@ -502,6 +500,20 @@ public boolean buildsUsingDocker() {
};
}

/**
* Whether the target requires using an equal sign to assign a defaul value to a parameter,
cmnrd marked this conversation as resolved.
Show resolved Hide resolved
* or initialize a state variable. All targets mandate an equal sign when passing
* arguments to a reactor constructor call, regardless of this method.
*/
public boolean mandatesEqualsInitializers() {
return this != CPP;
}

/** Allow expressions of the form {@code {a, b, c}}. */
public boolean allowsBracedListExpressions() {
return this == C || this == CCPP || this == CPP;
}

/**
* Return a string that demarcates the beginning of a single-line comment.
*/
Expand Down
1 change: 0 additions & 1 deletion org.lflang/src/org/lflang/ast/IsEqual.java
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,6 @@ public Boolean caseVarRef(VarRef object) {
public Boolean caseAssignment(Assignment object) {
return new ComparisonMachine<>(object, Assignment.class)
.equivalent(Assignment::getLhs)
.equalAsObjects(Assignment::getEquals)
.equivalent(Assignment::getRhs)
.conclusion;
}
Expand Down
43 changes: 35 additions & 8 deletions org.lflang/src/org/lflang/ast/ToLf.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import org.lflang.ASTUtils;
import org.lflang.Target;
import org.lflang.ast.MalleableString.Builder;
import org.lflang.ast.MalleableString.Joiner;
import org.lflang.lf.Action;
Expand All @@ -29,6 +30,7 @@
import org.lflang.lf.Assignment;
import org.lflang.lf.AttrParm;
import org.lflang.lf.Attribute;
import org.lflang.lf.BracedListExpression;
import org.lflang.lf.BuiltinTriggerRef;
import org.lflang.lf.Code;
import org.lflang.lf.CodeExpr;
Expand All @@ -46,6 +48,7 @@
import org.lflang.lf.Instantiation;
import org.lflang.lf.KeyValuePair;
import org.lflang.lf.KeyValuePairs;
import org.lflang.lf.LfFactory;
import org.lflang.lf.Literal;
import org.lflang.lf.Method;
import org.lflang.lf.MethodArgument;
Expand Down Expand Up @@ -757,14 +760,26 @@ public MalleableString caseSerializer(Serializer object) {
@Override
public MalleableString caseKeyValuePairs(KeyValuePairs object) {
// {KeyValuePairs} '{' (pairs+=KeyValuePair (',' (pairs+=KeyValuePair))* ','?)? '}'
if (object.getPairs().isEmpty()) return MalleableString.anyOf("");
if (object.getPairs().isEmpty()) {
return MalleableString.anyOf("");
}
return new Builder()
.append("{\n")
.append(list(",\n", "", "\n", true, true, object.getPairs()).indent())
.append("}")
.get();
}

@Override
public MalleableString caseBracedListExpression(BracedListExpression object) {
if (object.getItems().isEmpty()) {
return MalleableString.anyOf("{}");
}
// Note that this strips the trailing comma. There is no way
// to implement trailing commas with the current set of list() methods AFAIU.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This not a problem for brace lists in C/C++, but it might become a problem for tuples in Python. That is a problem for another day though...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true. I'm not sure it makes sense to add a dedicated syntax for Python tuples anyway... It sounds like it would be rarely used.

return list(", ", "{ ", " }", false, false, object.getItems());
oowekyala marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public MalleableString caseKeyValuePair(KeyValuePair object) {
// name=Kebab ':' value=Element
Expand Down Expand Up @@ -819,9 +834,6 @@ public MalleableString caseAssignment(Assignment object) {
// ));
Builder msb = new Builder();
msb.append(object.getLhs().getName());
if (object.getEquals() != null) {
msb.append(" = ");
}
msb.append(initializer(object.getRhs(), false));
return msb.get();
}
Expand All @@ -831,21 +843,36 @@ public MalleableString caseInitializer(Initializer object) {
return initializer(object, false);
}

private boolean shouldOutputAsAssignment(Initializer init) {
oowekyala marked this conversation as resolved.
Show resolved Hide resolved
return init.isAssign()
|| init.getExprs().size() == 1 && ASTUtils.getTarget(init).mandatesEqualsInitializers();
}

private MalleableString initializer(Initializer init, boolean nothingIfEmpty) {
if (init == null) {
return MalleableString.anyOf("");
}
if (shouldOutputAsAssignment(init)) {
Expression expr = ASTUtils.asSingleExpr(init);
Objects.requireNonNull(expr);
return new Builder().append(" = ").append(doSwitch(expr)).get();
}
if (ASTUtils.getTarget(init) == Target.C) {
// This turns C array initializers into a braced expression.
// C++ variants are not converted.
BracedListExpression list = LfFactory.eINSTANCE.createBracedListExpression();
list.getItems().addAll(init.getExprs());
return new Builder().append(" = ").append(doSwitch(list)).get();
}
String prefix;
String suffix;
if (init.isBraces()) {
prefix = "{";
suffix = "}";
} else if (init.isParens()) {
} else {
assert init.isParens();
prefix = "(";
suffix = ")";
} else {
// unparenthesized parameter assignment.
prefix = suffix = "";
}
return list(", ", prefix, suffix, nothingIfEmpty, false, init.getExprs());
}
Expand Down
6 changes: 6 additions & 0 deletions org.lflang/src/org/lflang/ast/ToText.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.lflang.ASTUtils;
import org.lflang.lf.ArraySpec;
import org.lflang.lf.BracedListExpression;
import org.lflang.lf.Code;
import org.lflang.lf.CodeExpr;
import org.lflang.lf.Host;
Expand Down Expand Up @@ -78,6 +79,11 @@ public String caseCode(Code code) {
return "";
}

@Override
public String caseBracedListExpression(BracedListExpression object) {
return ToLf.instance.caseBracedListExpression(object).toString();
}

@Override
public String caseHost(Host host) {
return ToLf.instance.caseHost(host).toString();
Expand Down
16 changes: 10 additions & 6 deletions org.lflang/src/org/lflang/cli/Lff.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ private void formatSingleFile(Path path, Path inputRoot, Path outputRoot) {
if (verbose) {
reporter.printInfo("Skipped " + path + ": not an LF file");
}
return;
return;
}
validateResource(resource);

Expand All @@ -163,24 +163,28 @@ private void formatSingleFile(Path path, Path inputRoot, Path outputRoot) {
FileUtil.writeToFile(formattedFileContents, outputPath, true);
} catch (IOException e) {
if (e instanceof FileAlreadyExistsException) {
// Only happens if a subdirectory is named with
// Only happens if a subdirectory is named with
// ".lf" at the end.
reporter.printFatalErrorAndExit(
"Error writing to "
+ outputPath
+ ": file already exists. Make sure that no file or"
+ ": file already exists. Make sure that no file or"
+ " directory within provided input paths have the"
+ " same relative paths.");
}
}
}

exitIfCollectedErrors();
issueCollector.getAllIssues().forEach(reporter::printIssue);
// Only errors are printed. Warnings are not helpful for LFF
// and since they don't prevent the file from being formatted,
// the position of the issue may be wrong in the formatted file.
// issueCollector.getAllIssues().forEach(reporter::printIssue);
if (verbose) {
String msg = "Formatted " + io.getWd().relativize(path);
if (path != outputPath) msg +=
" -> " + io.getWd().relativize(outputPath);
if (path != outputPath) {
msg += " -> " + io.getWd().relativize(outputPath);
}
reporter.printInfo(msg);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1187,12 +1187,11 @@ private String createParameterLabel(ParameterInstance param) {
b.append(param.getName());
String t = param.type.toOriginalText();
if (!StringExtensions.isNullOrEmpty(t)) {
b.append(":").append(t);
b.append(": ").append(t);
}
if (!IterableExtensions.isNullOrEmpty(param.getInitialValue())) {
b.append("(");
b.append(" = ");
b.append(IterableExtensions.join(param.getInitialValue(), ", ", ASTUtils::toOriginalText));
b.append(")");
}
return b.toString();
}
Expand Down
Loading