}.toSeq.sorted
}
-class FortranGenerator {
- private var indentLevel = 0
+object FortranGenerator {
private val maxPrec = 30
- private val symbolManager = new SymbolManager
- private val buffer = scala.collection.mutable.Buffer[String]()
+
+ case class BinaryOpInfo(template: String, precedence: Int, assoc: BinaryOpInfo.Associativity)
object BinaryOpInfo {
sealed abstract class Associativity
object FUNCTION extends Associativity
}
- case class BinaryOpInfo(template: String, precedence: Int, assoc: BinaryOpInfo.Associativity)
+ private def getBinaryOpInfo(op: NumericOperations.CompareOp) : BinaryOpInfo = {
+ import NumericOperations._
+ import BinaryOpInfo._
+ op match {
+ case LT => BinaryOpInfo("%s .lt. %s", 16, LEFT)
+ case LE => BinaryOpInfo("%s .le. %s", 16, LEFT)
+ case EQ => BinaryOpInfo("%s .eq. %s", 16, LEFT)
+ case NE => BinaryOpInfo("%s .ne. %s", 16, LEFT)
+ case GT => BinaryOpInfo("%s .gt. %s", 16, LEFT)
+ case GE => BinaryOpInfo("%s .ge. %s", 16, LEFT)
+ case x => throw new UnimplementedException("Unknown comparison type in FORTRAN generator: "+x.toString)
+ }
+ }
+
+ private def getBinaryOpInfo(op: NumericOperations.FieldOp) : BinaryOpInfo = {
+ import NumericOperations._
+ import BinaryOpInfo._
+ op match {
+ case Add => BinaryOpInfo("%s + %s", 22, LEFT)
+ case Sub => BinaryOpInfo("%s - %s", 22, LEFT)
+ case Mul => BinaryOpInfo("%s * %s", 26, LEFT)
+ case Div => BinaryOpInfo("%s / %s", 26, LEFT)
+ case Mod => BinaryOpInfo("mod(%s, %s)", maxPrec, FUNCTION)
+ case x => throw new UnimplementedException("Unknown numeric operator in FORTRAN generator: "+x.toString)
+ }
+ }
+
+ private def wrapLine(line: String) : Seq[String] = {
+ // Fortran95 maximum line length is 132 characters, but let's assume people
+ // might want to indent further.
+ val maxLineLength = 120
+ val buffer = scala.collection.mutable.Buffer[String]()
+ val marginMatch = "^\\s*".r
+ val margin = marginMatch.findFirstIn(line) match {
+ case Some(string) => string
+ case _ => ""
+ }
+
+ var remaining = line.drop(margin.length)
+ while (remaining.length + margin.length > maxLineLength) {
+ val takeLength = maxLineLength - margin.length + 1
+ val nextSubLine = margin + remaining.take(takeLength) + "&"
+ remaining = "&"+remaining.drop(takeLength)
+ buffer.append(nextSubLine)
+ }
+ buffer.append(margin + remaining)
+ buffer.toSeq
+ }
+
+ private def wrapLines(lines: Seq[String]) : Seq[String] = lines.flatMap(wrapLine(_))
+}
+
+class FortranGenerator {
+ import FortranGenerator.{maxPrec, BinaryOpInfo, getBinaryOpInfo}
+
+ private var indentLevel = 0
+ private val symbolManager = new SymbolManager
+ private val buffer = scala.collection.mutable.Buffer[String]()
+
case class ExpHolder(prec: Int, exp: String) {
override def toString = exp
}
buffer.prepend("\n")
buffer.prependAll(symbolManager.getDeclarations)
- buffer.mkString("\n")
+ FortranGenerator.wrapLines(buffer).mkString("\n")
}
private def processStatement(stat: Statement) {
ExpHolder(maxPrec, name)
}
- private def getBinaryOpInfo(op: NumericOperations.CompareOp) : BinaryOpInfo = {
- import NumericOperations._
- import BinaryOpInfo._
- op match {
- case LT => BinaryOpInfo("%s .lt. %s", 16, LEFT)
- case LE => BinaryOpInfo("%s .le. %s", 16, LEFT)
- case EQ => BinaryOpInfo("%s .eq. %s", 16, LEFT)
- case NE => BinaryOpInfo("%s .ne. %s", 16, LEFT)
- case GT => BinaryOpInfo("%s .gt. %s", 16, LEFT)
- case GE => BinaryOpInfo("%s .ge. %s", 16, LEFT)
- case x => throw new UnimplementedException("Unknown comparison type in FORTRAN generator: "+x.toString)
- }
- }
-
- private def getBinaryOpInfo(op: NumericOperations.FieldOp) : BinaryOpInfo = {
- import NumericOperations._
- import BinaryOpInfo._
- op match {
- case Add => BinaryOpInfo("%s + %s", 22, LEFT)
- case Sub => BinaryOpInfo("%s - %s", 22, LEFT)
- case Mul => BinaryOpInfo("%s * %s", 26, LEFT)
- case Div => BinaryOpInfo("%s / %s", 26, LEFT)
- case Mod => BinaryOpInfo("mod(%s, %s)", maxPrec, FUNCTION)
- case x => throw new UnimplementedException("Unknown numeric operator in FORTRAN generator: "+x.toString)
- }
- }
-
private def buildBinaryOperation(opInfo: BinaryOpInfo, left: ExpHolder, right: ExpHolder) : ExpHolder = {
import BinaryOpInfo._