]> git.unchartedbackwaters.co.uk Git - francis/ofc.git/commitdiff
Work around weird Fortran unary operator handling.
authorFrancis Russell <francis@unchartedbackwaters.co.uk>
Tue, 8 May 2012 18:19:49 +0000 (19:19 +0100)
committerFrancis Russell <francis@unchartedbackwaters.co.uk>
Tue, 8 May 2012 18:19:49 +0000 (19:19 +0100)
Fortran dislikes unary plus or minus on right right hand side of
an arithmetic operator.

src/ofc/codegen/FortranGenerator.scala

index 240123eca729e0eae9e04e5adcf69ae9d97770b3..86c5b07c573661bb63eca1c22e2c978dcdd98af5 100644 (file)
@@ -234,8 +234,22 @@ class FortranGenerator {
   private def buildNumericComparison(c: NumericComparison[_]) : ExpHolder =
     buildBinaryOperation(getBinaryOpInfo(c.getOperation), buildExpression(c.getLeft), buildExpression(c.getRight))
 
-  private def buildNumericOperator(o: NumericOperator[_]) : ExpHolder =
-    buildBinaryOperation(getBinaryOpInfo(o.getOperation), buildExpression(o.getLeft), buildExpression(o.getRight))
+  private def buildNumericOperator(o: NumericOperator[_]) : ExpHolder = {
+    val left = buildExpression(o.getLeft)
+    var right =  buildExpression(o.getRight)
+
+    // Fortran has stupid rules about unary negation on the right hand side of an arithmetic operator.
+    def isUnaryNegate(expression: Expression[_]) = expression match {
+      case (l: FloatLiteral) if l.getValue < 0 => true
+      case (l: IntegerLiteral) if l.getValue < 0 => true
+      case _ => false
+    }
+
+    if (isUnaryNegate(o.getRight))
+      right = ExpHolder(maxPrec, "(%s)".format(right.exp))
+
+    buildBinaryOperation(getBinaryOpInfo(o.getOperation), left, right)
+  }
 
   private def processForLoop(stat: ForLoop) {
     val index = stat.getIndex