generate necessary parenthesis in composite expressions
This updates the language model to write parenthesis for expressions
that need them. E.g., ( 1 + 2 ) * 3.
There are two parts to the solution. Firstly, every expression is
assigned a precedence. The precedence levels are defined from:
http://www.tech-uofm.info/spring_2011/TECH1211/Precedence_Table.pdf
This table ranks all expressions and also specifies the directional
associativity. At this point only the ranking is used.
The second part of the solution is to change the #write functions for
all places where expressions are written within expressions. For
example, in a BinaryOperation, both the left-hand side and right-hand
side are written within the containing binary operation.
At each of these points, the target expression's precedence is compared
with the precedence of the containing expression. The inner expression
is wrapped with parenthesis where needed.
Finally, some convenience functions are provided to implement this
functionality.
I've updated the test suite with some targetted tests. Existing test
cases are unaffected.
Change-Id: Icdab76b78f1bc91a2f186d21cd321b0dafea71e6
Signed-off-by: Andrew Eidsness <andrewe@jfront.com>
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp.test/src/org/eclipse/papyrusrt/codegen/lang/cpp/test/ExpressionTest.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp.test/src/org/eclipse/papyrusrt/codegen/lang/cpp/test/ExpressionTest.java
index 91e9498..034e268 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp.test/src/org/eclipse/papyrusrt/codegen/lang/cpp/test/ExpressionTest.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp.test/src/org/eclipse/papyrusrt/codegen/lang/cpp/test/ExpressionTest.java
@@ -12,15 +12,19 @@
import org.eclipse.papyrusrt.codegen.lang.cpp.Expression;
import org.eclipse.papyrusrt.codegen.lang.cpp.element.Constructor;
import org.eclipse.papyrusrt.codegen.lang.cpp.element.CppClass;
+import org.eclipse.papyrusrt.codegen.lang.cpp.element.MemberFunction;
import org.eclipse.papyrusrt.codegen.lang.cpp.element.Parameter;
import org.eclipse.papyrusrt.codegen.lang.cpp.element.PrimitiveType;
import org.eclipse.papyrusrt.codegen.lang.cpp.element.Variable;
+import org.eclipse.papyrusrt.codegen.lang.cpp.expr.BinaryOperation;
+import org.eclipse.papyrusrt.codegen.lang.cpp.expr.CastExpr;
import org.eclipse.papyrusrt.codegen.lang.cpp.expr.CharacterLiteral;
import org.eclipse.papyrusrt.codegen.lang.cpp.expr.ConditionalOperator;
import org.eclipse.papyrusrt.codegen.lang.cpp.expr.ConstructorCall;
import org.eclipse.papyrusrt.codegen.lang.cpp.expr.DeleteExpr;
import org.eclipse.papyrusrt.codegen.lang.cpp.expr.ElementAccess;
import org.eclipse.papyrusrt.codegen.lang.cpp.expr.IntegralLiteral;
+import org.eclipse.papyrusrt.codegen.lang.cpp.expr.MemberFunctionCall;
import org.eclipse.papyrusrt.codegen.lang.cpp.expr.NewExpr;
import org.eclipse.papyrusrt.codegen.lang.cpp.test.util.LangCppBaseTest;
import org.junit.FixMethodOrder;
@@ -75,4 +79,43 @@
assertDefnFormattedAs(
"1 ? 'a' : 'b'" );
}
+
+ @Test
+ public void test04_paren()
+ {
+ assertTrue(
+ new BinaryOperation(
+ new IntegralLiteral( 3 ),
+ BinaryOperation.Operator.MULTIPLY,
+ new BinaryOperation(
+ new IntegralLiteral( 1 ),
+ BinaryOperation.Operator.ADD,
+ new IntegralLiteral( 2 ) ) )
+ .write( out.defn() ) );
+ assertTrue( out.defn().newline() );
+ assertTrue(
+ new BinaryOperation(
+ new IntegralLiteral( 3 ),
+ BinaryOperation.Operator.ADD,
+ new BinaryOperation(
+ new IntegralLiteral( 1 ),
+ BinaryOperation.Operator.MULTIPLY,
+ new IntegralLiteral( 2 ) ) )
+ .write( out.defn() ) );
+ assertTrue( out.defn().newline() );
+
+ // E.g., ( (UMLRTInSignal & )msg.signal ).decode( &rts_decodeInfo, (void *)&rtdata, NULL );
+ Variable var = new Variable( PrimitiveType.INT, "var" );
+ MemberFunction func = new MemberFunction( PrimitiveType.VOID, "func" );
+ MemberFunctionCall call
+ = new MemberFunctionCall(
+ new CastExpr( PrimitiveType.BOOL, new ElementAccess( var ) ),
+ func );
+ assertTrue( call.write( out.defn() ) );
+
+ assertDefnFormattedAs(
+ "3 * ( 1 + 2 )",
+ "3 + 1 * 2",
+ "( (bool)var ).func()" );
+ }
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/Expression.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/Expression.java
index ec73adb..5031586 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/Expression.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/Expression.java
@@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.papyrusrt.codegen.lang.cpp;
+import org.eclipse.papyrusrt.codegen.lang.cpp.internal.CppFormatter;
/**
* Expressions are the leaf for nearly all code.
@@ -35,15 +36,38 @@
* Levels of precedence will be specified in order and grouped by category. The
* C++11 spec says that order is not defined but can be derived from the syntax.
*/
- public Precedence getPrecedence() { return Precedence.Default; }
+ public abstract Precedence getPrecedence();// { return Precedence.Default; }
public static enum Precedence
{
- // TODO derive levels of precedence
- Default;
+ // From http://en.cppreference.com/w/cpp/language/operator_precedence
+ Default,
+ Precedence01, Precedence02, Precedence03, Precedence04,
+ Precedence05, Precedence06, Precedence07, Precedence08,
+ Precedence09, Precedence10, Precedence11, Precedence12,
+ Precedence13, Precedence14, Precedence15, Precedence16,
+ Precedence17,
+ Lowest;
public boolean needsParens( Precedence neighbour )
{
- return false; // this < neighbour
+ if( this == Default
+ || neighbour == Default )
+ return false;
+
+ return ordinal() > neighbour.ordinal();
}
}
+
+ @Override
+ public boolean write( CppFormatter fmt )
+ {
+ return false;
+ }
+
+ public boolean write( CppFormatter fmt, Expression containingExpr )
+ {
+ return containingExpr == null
+ ? write( fmt )
+ : fmt.write( this, getPrecedence().needsParens( containingExpr.getPrecedence() ) );
+ }
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/element/OffsetOf.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/element/OffsetOf.java
index 8420237..0530e83 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/element/OffsetOf.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/element/OffsetOf.java
@@ -22,13 +22,14 @@
// TODO This should be the member element, not just the string name. There isn't
// currently a way to get that Member, because it is a private class within
// CppClass.
- public OffsetOf( CppClass cls,String memberName )
+ public OffsetOf( CppClass cls, String memberName )
{
this.cls = cls;
this.memberName = memberName;
}
@Override protected Type createType() { return StandardLibrary.size_t; }
+ @Override public Precedence getPrecedence() { return Precedence.Lowest; }
@Override
public boolean addDependencies( DependencyList deps )
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AbstractFunctionCall.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AbstractFunctionCall.java
index 3e66ed2..4e61383 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AbstractFunctionCall.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AbstractFunctionCall.java
@@ -27,6 +27,8 @@
public void addArgument( Expression arg ) { arguments.add( arg ); }
public boolean hasArguments() { return ! arguments.isEmpty(); }
+ @Override public Precedence getPrecedence() { return Precedence.Precedence02; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AddressOfExpr.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AddressOfExpr.java
index f080b8e..2a6c2eb 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AddressOfExpr.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/AddressOfExpr.java
@@ -27,6 +27,8 @@
return expr.getType().ptr();
}
+ @Override public Precedence getPrecedence() { return Precedence.Precedence03; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -38,6 +40,6 @@
public boolean write( CppFormatter fmt )
{
return fmt.write( '&' )
- && expr.write( fmt );
+ && expr.write( fmt, this );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BinaryOperation.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BinaryOperation.java
index 7c6f1aa..347b68f 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BinaryOperation.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BinaryOperation.java
@@ -27,12 +27,17 @@
public static enum Operator
{
- ASSIGN( '=' ),
- ADD( '+' ), SUBTRACT( '-' ), MULTIPLY( '*' ), DIVIDE( '/' ),
- BITWISE_OR( '|' ), BITWISE_AND( '&' );
+ ASSIGN( '=', Precedence.Precedence15 ),
+ ADD( '+', Precedence.Precedence06 ),
+ SUBTRACT( '-', Precedence.Precedence06 ),
+ MULTIPLY( '*', Precedence.Precedence05 ),
+ DIVIDE( '/', Precedence.Precedence05 ),
+ BITWISE_OR( '|', Precedence.Precedence12 ),
+ BITWISE_AND( '&', Precedence.Precedence10 );
- private Operator( char token ) { this.token = token; }
+ private Operator( char token, Precedence precedence ) { this.token = token; this.precedence = precedence; }
private final char token;
+ public final Precedence precedence;
public boolean write( CppFormatter fmt )
{
@@ -46,6 +51,8 @@
return lhs.getType();
}
+ @Override public Precedence getPrecedence() { return operator.precedence; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -56,10 +63,10 @@
@Override
public boolean write( CppFormatter fmt )
{
- return lhs.write( fmt )
+ return lhs.write( fmt, this )
&& fmt.space()
&& operator.write( fmt )
&& fmt.space()
- && rhs.write( fmt );
+ && rhs.write( fmt, this );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BlockInitializer.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BlockInitializer.java
index 2d072d6..6005b47 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BlockInitializer.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/BlockInitializer.java
@@ -32,6 +32,8 @@
@Override protected Type createType() { return type; }
+ @Override public Precedence getPrecedence() { return Precedence.Default; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/CastExpr.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/CastExpr.java
index 7bc51e1..8322d01 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/CastExpr.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/CastExpr.java
@@ -29,6 +29,8 @@
return targetType;
}
+ @Override public Precedence getPrecedence() { return Precedence.Precedence03; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -42,6 +44,6 @@
return fmt.write( '(' )
&& targetType.write( fmt, null )
&& fmt.write( ')' )
- && expr.write( fmt );
+ && expr.write( fmt, this );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ConditionalOperator.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ConditionalOperator.java
index da4307f..70a01f1 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ConditionalOperator.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ConditionalOperator.java
@@ -33,6 +33,8 @@
return expr2.getType();
}
+ @Override public Precedence getPrecedence() { return Precedence.Precedence15; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -44,14 +46,14 @@
@Override
public boolean write( CppFormatter fmt )
{
- return expr1.write( fmt )
+ return expr1.write( fmt, this )
&& fmt.space()
&& fmt.write( '?' )
&& fmt.space()
- && expr2.write( fmt )
+ && expr2.write( fmt, this )
&& fmt.space()
&& fmt.write( ':' )
&& fmt.space()
- && expr3.write( fmt );
+ && expr3.write( fmt, this );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DeleteExpr.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DeleteExpr.java
index 1396b56..1663b81 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DeleteExpr.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DeleteExpr.java
@@ -25,6 +25,8 @@
return PrimitiveType.VOID;
}
+ @Override public Precedence getPrecedence() { return Precedence.Precedence03; }
+
/**
* A delete expression introduces no dependencies of its own.
*/
@@ -35,6 +37,6 @@
{
return fmt.write( "delete" )
&& fmt.space()
- && expr.write( fmt );
+ && expr.write( fmt, this );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DereferenceExpr.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DereferenceExpr.java
index b1eb84c..ee8c6a0 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DereferenceExpr.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/DereferenceExpr.java
@@ -27,6 +27,8 @@
return expr.getType().dereference();
}
+ @Override public Precedence getPrecedence() { return Precedence.Precedence03; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -38,6 +40,6 @@
public boolean write( CppFormatter fmt )
{
return fmt.write( '*' )
- && expr.write( fmt );
+ && expr.write( fmt, this );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ElementAccess.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ElementAccess.java
index fc58f05..b3b976d 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ElementAccess.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ElementAccess.java
@@ -32,6 +32,8 @@
return element.getType();
}
+ @Override public Precedence getPrecedence() { return Precedence.Default; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ExpressionBlob.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ExpressionBlob.java
index b839309..5f3ead3 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ExpressionBlob.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/ExpressionBlob.java
@@ -41,6 +41,10 @@
return PrimitiveType.VOID;
}
+ // An expression blob should always be evaluated on it's own, which means that it
+ // should always have parenthesis.
+ @Override public Precedence getPrecedence() { return Precedence.Lowest; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/IndexExpr.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/IndexExpr.java
index 70cef4a..3aca73a 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/IndexExpr.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/IndexExpr.java
@@ -29,6 +29,8 @@
return array.getType().dereference();
}
+ @Override public Precedence getPrecedence() { return Precedence.Precedence02; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -40,7 +42,7 @@
@Override
public boolean write( CppFormatter fmt )
{
- return array.write( fmt )
+ return array.write( fmt, this )
&& fmt.write( '[' )
&& index.write( fmt )
&& fmt.write( ']' );
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Literal.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Literal.java
index 32b07de..58a7651 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Literal.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Literal.java
@@ -29,6 +29,8 @@
return type;
}
+ @Override public Precedence getPrecedence() { return Precedence.Default; }
+
// Literals never introduce dependencies.
@Override public boolean addDependencies( DependencyList deps ) { return true; }
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/LogicalComparison.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/LogicalComparison.java
index af58a73..c7011cf 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/LogicalComparison.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/LogicalComparison.java
@@ -28,15 +28,20 @@
public static enum Operator
{
- AND( "&&" ), OR( "||" ),
+ AND( "&&", Precedence.Precedence13 ),
+ OR( "||", Precedence.Precedence14 ),
- LESS_THAN( "<" ), GREATER_THAN( ">" ),
- LESS_THAN_EQUAL( "<=" ), GREATER_THAN_EQUAL( ">=" ),
+ LESS_THAN( "<", Precedence.Precedence08 ),
+ GREATER_THAN( ">", Precedence.Precedence08 ),
+ LESS_THAN_EQUAL( "<=", Precedence.Precedence08 ),
+ GREATER_THAN_EQUAL( ">=", Precedence.Precedence08 ),
- EQUIVALENT( "==" ), NOT_EQUIVALENT( "!=" );
+ EQUIVALENT( "==", Precedence.Precedence09 ),
+ NOT_EQUIVALENT( "!=", Precedence.Precedence09 );
- private Operator( String token ) { this.token = token; }
+ private Operator( String token, Precedence precedence ) { this.token = token; this.precedence = precedence; }
private final String token;
+ public final Precedence precedence;
public boolean write( CppFormatter fmt )
{
@@ -50,6 +55,8 @@
return PrimitiveType.BOOL;
}
+ @Override public Precedence getPrecedence() { return operator.precedence; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -60,10 +67,10 @@
@Override
public boolean write( CppFormatter fmt )
{
- return lhs.write( fmt )
+ return lhs.write( fmt, this )
&& fmt.space()
&& operator.write( fmt )
&& fmt.space()
- && rhs.write( fmt );
+ && rhs.write( fmt, this );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberAccess.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberAccess.java
index c3a90e8..849d8d8 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberAccess.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberAccess.java
@@ -29,10 +29,11 @@
}
@Override protected Type createType() { return impl.createType(); }
+ @Override public Precedence getPrecedence() { return Precedence.Precedence02; }
@Override public boolean addDependencies( DependencyList deps ) { return impl.addDependencies( deps ); }
@Override public boolean write( CppFormatter fmt ) { return impl.write( fmt ); }
- private static class NonStaticAccess extends ElementAccess
+ private class NonStaticAccess extends ElementAccess
{
private final Expression container;
@@ -54,7 +55,7 @@
@Override
public boolean write( CppFormatter fmt )
{
- return container.write( fmt )
+ return container.write( fmt, MemberAccess.this )
&& fmt.write( container.getType().isIndirect() ? "->" : "." )
&& super.write( fmt );
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberFunctionCall.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberFunctionCall.java
index b91a95d..eaa139e 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberFunctionCall.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/MemberFunctionCall.java
@@ -53,7 +53,7 @@
public boolean write( CppFormatter fmt );
}
- private static class Expr implements Impl
+ private class Expr implements Impl
{
private final Expression receiver;
@@ -68,7 +68,7 @@
@Override
public boolean write( CppFormatter fmt )
{
- return receiver.write( fmt )
+ return receiver.write( fmt, MemberFunctionCall.this )
&& fmt.write( receiver.getType().isIndirect() ? "->" : "." );
}
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/NewExpr.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/NewExpr.java
index 6caea51..578a71f 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/NewExpr.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/NewExpr.java
@@ -19,6 +19,7 @@
public NewExpr( ConstructorCall call ) { this.call = call; }
@Override protected Type createType() { return call.createType().ptr(); }
+ @Override public Precedence getPrecedence() { return Precedence.Precedence03; }
@Override public boolean addDependencies( DependencyList deps ) { return call.addDependencies( deps ); }
@Override
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Sizeof.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Sizeof.java
index c5ccfbc..8811fa2 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Sizeof.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/Sizeof.java
@@ -34,6 +34,7 @@
return PrimitiveType.UINT;
}
+ @Override public Precedence getPrecedence() { return Precedence.Default; }
@Override public boolean addDependencies( DependencyList deps ) { return impl.addDependencies( deps ); }
@Override public boolean write( CppFormatter fmt ) { return impl.write( fmt ); }
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/UnaryOperation.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/UnaryOperation.java
index 38ab2d0..572b8de 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/UnaryOperation.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/expr/UnaryOperation.java
@@ -26,22 +26,26 @@
public static enum Operator
{
- PRE_INCREMENT( "++", true ), PRE_DECREMENT( "--", true ),
- POST_INCREMENT( "++" ), POST_DECREMENT( "--" ),
+ PRE_INCREMENT( "++", Precedence.Precedence03, true ),
+ PRE_DECREMENT( "--", Precedence.Precedence03, true ),
+ POST_INCREMENT( "++", Precedence.Precedence02 ),
+ POST_DECREMENT( "--", Precedence.Precedence02 ),
- LOGICAL_NOT( "!", true, true, true ),
- BITWISE_NOT( "~", true );
+ LOGICAL_NOT( "!", Precedence.Precedence03, true, true, true ),
+ BITWISE_NOT( "~", Precedence.Precedence03, true );
+ public final Precedence precedence;
public final boolean before;
public final boolean separator;
public final boolean boolean_op;
- private Operator( String syntax ) { this( syntax, false ); }
- private Operator( String syntax, boolean before ) { this( syntax, before, false ); }
- private Operator( String syntax, boolean before, boolean separator ) { this( syntax, before, separator, false ); }
- private Operator( String syntax, boolean before, boolean separator, boolean boolean_op )
+ private Operator( String syntax, Precedence p ) { this( syntax, p, false ); }
+ private Operator( String syntax, Precedence p, boolean before ) { this( syntax, p, before, false ); }
+ private Operator( String syntax, Precedence p, boolean before, boolean separator ) { this( syntax, p, before, separator, false ); }
+ private Operator( String syntax, Precedence p, boolean before, boolean separator, boolean boolean_op )
{
this.syntax = syntax;
+ this.precedence = p;
this.before = before;
this.separator = separator;
this.boolean_op = boolean_op;
@@ -61,6 +65,8 @@
return operator.boolean_op ? PrimitiveType.BOOL : expr.getType();
}
+ @Override public Precedence getPrecedence() { return operator.precedence; }
+
@Override
public boolean addDependencies( DependencyList deps )
{
@@ -73,9 +79,9 @@
if( operator.before )
return fmt.write( operator.syntax )
&& ( ! operator.separator || fmt.space() )
- && expr.write( fmt );
+ && expr.write( fmt, this );
- return expr.write( fmt )
+ return expr.write( fmt, this )
&& ( ! operator.separator || fmt.space() )
&& fmt.write( operator.syntax );
}
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/internal/CppFormatter.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/internal/CppFormatter.java
index 21e4d1a..e88d0e1 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/internal/CppFormatter.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/internal/CppFormatter.java
@@ -10,6 +10,7 @@
import java.io.ByteArrayOutputStream;
import java.util.Stack;
+import org.eclipse.papyrusrt.codegen.lang.cpp.IGeneratable;
import org.eclipse.papyrusrt.codegen.lang.cpp.Name;
import org.eclipse.papyrusrt.codegen.lang.io.CodeFormatter;
import org.eclipse.papyrusrt.codegen.lang.io.ComparisonStream;
@@ -49,6 +50,13 @@
return name.writeQualified( this, context.isEmpty() ? null : context.peek() );
}
+ public boolean write( IGeneratable gen, boolean withParen )
+ {
+ return ( ! withParen || ( write( '(' ) && space() ) )
+ && gen.write( this )
+ && ( ! withParen || ( space() && write( ')' ) ) );
+ }
+
/**
* Create and return a formatter that will write to the given memory-based output
* stream. Mostly for the test suite.
diff --git a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/stmt/SwitchStatement.java b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/stmt/SwitchStatement.java
index c3af3c4..02f5d3c 100644
--- a/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/stmt/SwitchStatement.java
+++ b/codegen/org.eclipse.papyrusrt.codegen.lang.cpp/src/org/eclipse/papyrusrt/codegen/lang/cpp/stmt/SwitchStatement.java
@@ -47,9 +47,11 @@
@Override
public boolean write( CppFormatter fmt )
{
- if( ! fmt.write( "switch( " )
+ if( ! fmt.write( "switch(" )
+ || ! fmt.space()
|| ! condition.write( fmt )
- || ! fmt.writeLn( " )" )
+ || ! fmt.space()
+ || ! fmt.writeLn( ')' )
|| ! fmt.openBrace()
|| ! fmt.decIndent() )
return false;