Add unary plus operator, +int
Implements: https://github.com/bazelbuild/starlark/issues/20#issuecomment-456647994
Closes #8890.
PiperOrigin-RevId: 258388687
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index 13cc21c..dfb82d6 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -673,6 +673,13 @@
UnaryOperatorExpression minus = new UnaryOperatorExpression(TokenKind.MINUS, expr);
return setLocation(minus, start, expr);
}
+ case PLUS:
+ {
+ nextToken();
+ Expression expr = parsePrimaryWithSuffix();
+ UnaryOperatorExpression plus = new UnaryOperatorExpression(TokenKind.PLUS, expr);
+ return setLocation(plus, start, expr);
+ }
default:
{
syntaxError("expected expression");
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
index 7341708..b16a07f 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
@@ -19,7 +19,7 @@
/** A UnaryOperatorExpression represents a unary operator expression, 'op x'. */
public final class UnaryOperatorExpression extends Expression {
- private final TokenKind op; // NOT or MINUS
+ private final TokenKind op; // NOT, MINUS or PLUS
private final Expression x;
public UnaryOperatorExpression(TokenKind op, Expression x) {
@@ -75,6 +75,14 @@
// Fails for -MIN_INT.
throw new EvalException(loc, e.getMessage());
}
+ case PLUS:
+ if (!(value instanceof Integer)) {
+ throw new EvalException(
+ loc,
+ String.format(
+ "unsupported operand type for +: '%s'", EvalUtils.getDataTypeName(value)));
+ }
+ return value;
default:
throw new AssertionError("Unsupported unary operator: " + op);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
index e72f01b..9e2d211 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
@@ -137,7 +137,7 @@
" srcs = libs,",
" includes = [ abi + opt_level + '/include' ])");
assertThat(buildFile.containsErrors()).isTrue();
- assertContainsError("syntax error at '+': expected expression");
+ assertContainsError("syntax error at '*': expected expression");
assertThat(buildFile.exec(env, getEventHandler())).isFalse();
MoreAsserts.assertDoesNotContainEvent(getEventCollector(), "$error$");
// This message should not be printed anymore.
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
index cfc9641..bc4d8cc 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
@@ -838,22 +838,23 @@
@Test
public void testParserRecovery() throws Exception {
setFailFast(false);
- List<Statement> statements = parseFileForSkylark(
- "def foo():",
- " a = 2 for 4", // parse error
- " b = [3, 4]",
- "",
- "d = 4 ada", // parse error
- "",
- "def bar():",
- " a = [3, 4]",
- " b = 2 + + 5", // parse error
- "");
+ List<Statement> statements =
+ parseFileForSkylark(
+ "def foo():",
+ " a = 2 for 4", // parse error
+ " b = [3, 4]",
+ "",
+ "d = 4 ada", // parse error
+ "",
+ "def bar():",
+ " a = [3, 4]",
+ " b = 2 * * 5", // parse error
+ "");
assertThat(getEventCollector()).hasSize(3);
assertContainsError("syntax error at 'for': expected newline");
assertContainsError("syntax error at 'ada': expected newline");
- assertContainsError("syntax error at '+': expected expression");
+ assertContainsError("syntax error at '*': expected expression");
assertThat(statements).hasSize(3);
}
@@ -872,8 +873,8 @@
@Test
public void testParserContainsErrors() throws Exception {
setFailFast(false);
- parseFile("+");
- assertContainsError("syntax error at '+'");
+ parseFile("*");
+ assertContainsError("syntax error at '*'");
}
@Test
diff --git a/src/test/starlark/testdata/int.sky b/src/test/starlark/testdata/int.sky
index 3bc2105..91212da 100644
--- a/src/test/starlark/testdata/int.sky
+++ b/src/test/starlark/testdata/int.sky
@@ -60,6 +60,15 @@
compound()
+
+# unary operators
+
+assert_eq(+4, 4)
+assert_eq(-4, -4)
+assert_eq(++4, 4)
+assert_eq(+-4, -4)
+assert_eq(-+-4, 4)
+
---
1 // 0 ### integer division by zero
---