summaryrefslogtreecommitdiff
path: root/src/test/java/org/zwobble
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-07-18 10:26:25 +0100
committerMichael Williamson <mike@zwobble.org>2026-07-18 10:26:25 +0100
commit25851fc06ab5b2271fb12ee35c5c181c1f9258aa (patch)
tree9515cc4a956834db59cb287189384dfe9bd9e591 /src/test/java/org/zwobble
parent3ea197f9f1deec604e99f2bf2292acd3fc7d3ac7 (diff)
Implement precedence in Rust writer
Diffstat (limited to 'src/test/java/org/zwobble')
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java97
1 files changed, 70 insertions, 27 deletions
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java
index 862d08b..4279f49 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java
@@ -403,7 +403,7 @@ public class RustWriterTests {
.withLengthOperand(RustIntegerLiteral.arbitrary().withValue(47))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("[42; 47]"));
}
@@ -418,7 +418,7 @@ public class RustWriterTests {
.withRight(RustPath.of("y"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("x + y"));
}
@@ -431,7 +431,7 @@ public class RustWriterTests {
.withRight(RustPath.of("y"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("x == y"));
}
@@ -444,7 +444,7 @@ public class RustWriterTests {
.withRight(RustPath.of("y"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("x != y"));
}
@@ -455,7 +455,7 @@ public class RustWriterTests {
public void blockExpressionWithNoStatementsAndNoFinalOperand() throws IOException {
var rust = RustBlockExpression.arbitrary().build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("""
{
@@ -473,7 +473,7 @@ public class RustWriterTests {
)
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("""
{
@@ -488,7 +488,7 @@ public class RustWriterTests {
.withFinalOperand(RustBoolLiteral.arbitrary().withValue(true))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("""
{
@@ -508,7 +508,7 @@ public class RustWriterTests {
.withFinalOperand(RustBoolLiteral.arbitrary().withValue(true))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("""
{
@@ -524,7 +524,7 @@ public class RustWriterTests {
public void trueLiteral() throws IOException {
var rust = RustBoolLiteral.arbitrary().withValue(true).build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("true"));
}
@@ -533,7 +533,7 @@ public class RustWriterTests {
public void falseLiteral() throws IOException {
var rust = RustBoolLiteral.arbitrary().withValue(false).build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("false"));
}
@@ -546,7 +546,7 @@ public class RustWriterTests {
.withFunction(RustPath.of("f"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("f()"));
}
@@ -559,7 +559,7 @@ public class RustWriterTests {
.addArg(RustPath.of("y"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("f(x, y)"));
}
@@ -573,7 +573,7 @@ public class RustWriterTests {
.withFieldName(RustIdentifier.of("y"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("x.y"));
}
@@ -588,7 +588,7 @@ public class RustWriterTests {
.withIfFalse(RustBlockExpression.arbitrary().withFinalOperand(RustPath.of("c")))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("""
if a {
@@ -604,7 +604,7 @@ public class RustWriterTests {
public void integerLiteralWithoutExplicitType() throws IOException {
var rust = RustIntegerLiteral.arbitrary().withValue(123).build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("123"));
}
@@ -616,7 +616,7 @@ public class RustWriterTests {
.withType(RustIdentifier.of("i32"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("123i32"));
}
@@ -630,7 +630,7 @@ public class RustWriterTests {
.withOperand(RustPath.of("x"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("&x"));
}
@@ -642,7 +642,7 @@ public class RustWriterTests {
.withOperand(RustPath.of("x"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("&mut x"));
}
@@ -654,7 +654,7 @@ public class RustWriterTests {
.withOperand(RustPath.of("x"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("*x"));
}
@@ -667,7 +667,7 @@ public class RustWriterTests {
.withStructPath(RustPath.of("A"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("A {}"));
}
@@ -688,7 +688,7 @@ public class RustWriterTests {
)
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("X { a: b, c: d }"));
}
@@ -701,7 +701,7 @@ public class RustWriterTests {
.withOperand(RustPath.of("a"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("a?"));
}
@@ -712,7 +712,7 @@ public class RustWriterTests {
public void tupleExpressionUnit() throws IOException {
var rust = RustTupleExpression.arbitrary().build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("()"));
}
@@ -723,7 +723,7 @@ public class RustWriterTests {
.addElement(RustPath.of("a"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("(a,)"));
}
@@ -736,11 +736,54 @@ public class RustWriterTests {
.addElement(RustPath.of("c"))
.build();
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("(a, b, c)"));
}
+ // === Precedence handling ===
+
+ @Test
+ public void whenSubExpressionHasLowerPrecedenceThenSubExpressionIsParenthesized() throws IOException {
+ var rust = RustBinaryExpression.arbitrary()
+ .withOperator(RustBinaryOperator.ADD)
+ .withLeft(
+ RustBinaryExpression.arbitrary()
+ .withOperator(RustBinaryOperator.EQUAL)
+ .withLeft(RustPath.of("x"))
+ .withRight(RustPath.of("y"))
+ )
+ .withRight(RustPath.of("z"))
+ .build();
+
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
+
+ assertThat(string, equalTo("(x == y) + z"));
+ }
+
+ @Test
+ public void whenSubExpressionsOfLeftAssociativeBinaryOperationHaveSamePrecedenceThenRightExpressionIsParenthesized() throws IOException {
+ var rust = RustBinaryExpression.arbitrary()
+ .withOperator(RustBinaryOperator.ADD)
+ .withLeft(
+ RustBinaryExpression.arbitrary()
+ .withOperator(RustBinaryOperator.ADD)
+ .withLeft(RustPath.of("a"))
+ .withRight(RustPath.of("b"))
+ )
+ .withRight(
+ RustBinaryExpression.arbitrary()
+ .withOperator(RustBinaryOperator.ADD)
+ .withLeft(RustPath.of("c"))
+ .withRight(RustPath.of("d"))
+ )
+ .build();
+
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
+
+ assertThat(string, equalTo("a + b + (c + d)"));
+ }
+
// == Types ==
@Test
@@ -815,7 +858,7 @@ public class RustWriterTests {
public void pathSegmentsAreSeparatedByDoubleColons() throws IOException {
var rust = RustPath.of("std", "string", "String");
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("std::string::String"));
}
@@ -825,7 +868,7 @@ public class RustWriterTests {
var rust = RustPath.of("std", "collections", "HashMap")
.withArgs(List.of(RustPath.of("i32"), RustPath.of("f64")));
- var string = write(writer -> writer.writeExpression(rust));
+ var string = write(writer -> writer.writeTopLevelExpression(rust));
assertThat(string, equalTo("std::collections::HashMap::<i32, f64>"));
}