def getName = name
}
- val symbols = mutable.Map[VarSymbol[_], SymbolInfo]()
- val names = mutable.Set[String]()
+ private val symbols = mutable.Map[VarSymbol[_ <: Type], SymbolInfo]()
+ private val names = mutable.Set[String]()
private def createNewName(sym: VarSymbol[_]) : String = {
@tailrec
}
}
- def getName(sym: VarSymbol[_]) =
+ def getName(sym: VarSymbol[_ <: Type]) =
symbols.get(sym) match {
case None => throw new LogicError("Unknown symbol (missing declaration?): "+sym.toString)
case Some(info) => info.getName
}
+
+ def getDeclarations : Seq[String] = {
+ for ((sym, info) <- symbols) yield
+ sym.getType.getFortranAttributes.mkString(", ") + " :: " + info.getName
+ }.toSeq.sorted
}
class FortranGenerator {
- var indentLevel = 0
- val maxPrec = 30
- val symbolManager = new SymbolManager
- val buffer = scala.collection.mutable.Buffer[String]()
+ private var indentLevel = 0
+ private val maxPrec = 30
+ private val symbolManager = new SymbolManager
+ private val buffer = scala.collection.mutable.Buffer[String]()
object BinaryOpInfo {
sealed abstract class Associativity
override def toString = exp
}
+ def apply(stat: Statement) : String = {
+ processStatement(stat)
+
+ buffer.prepend("\n")
+ buffer.prependAll(symbolManager.getDeclarations)
+ buffer.mkString("\n")
+ }
- def processStatement(stat: Statement) : String = {
+ private def processStatement(stat: Statement) {
stat match {
case (x : NullStatement) => ()
case (x : Comment) => addLine("!" + x.getValue)
case (a : Assignment) => processAssignment(a)
case x => throw new UnimplementedException("Unknown statement type in FORTRAN generator: " + x.toString)
}
-
- buffer.mkString("\n")
}
private def in() {
package ofc.codegen
-sealed abstract class Type
+sealed abstract class Type {
+ def getFortranAttributes : Set[String]
+}
sealed abstract class PrimitiveType extends Type
// These are case classes solely for the comparison operators
-final case class IntType() extends PrimitiveType
-final case class FloatType() extends PrimitiveType
-final case class BoolType() extends PrimitiveType
+final case class IntType() extends PrimitiveType {
+ def getFortranAttributes = Set("integer")
+}
+
+final case class FloatType() extends PrimitiveType {
+ def getFortranAttributes = Set("real(kind=DP")
+}
+
+final case class BoolType() extends PrimitiveType {
+ def getFortranAttributes = Set("logical")
+}
final case class ArrayType[ElementType <: Type](rank: Int, eType: ElementType) extends Type {
def this(rank: Int)(implicit builder: TypeBuilder[ElementType]) = this(rank, builder())
def getElementType = eType
+ def getFortranAttributes = eType.getFortranAttributes ++ Set("allocatable", (":"*rank).mkString("dimension(",",",")"))
}
final case class PointerType[TargetType <: Type](tType: TargetType) extends Type {
def this()(implicit builder: TypeBuilder[TargetType]) = this(builder())
def getTargetType = tType
+ def getFortranAttributes = tType.getFortranAttributes + "pointer"
}
abstract class StructType extends Type
}
val fortranGenerator = new FortranGenerator
- val code = fortranGenerator.processStatement(statements)
+ val code = fortranGenerator(statements)
println(code)
}
}
val fieldType = new PointerType[ArrayType[StructType]](new ArrayType(1, TightBox))
new FieldSymbol[PointerType[ArrayType[StructType]]]("tight_boxes", fieldType)
}
+
+ def getFortranAttributes = Set("type(FUNC_BASIS)")
}
object CellInfo extends StructType {
val ppdWidth = {for (dim <- 1 to 3) yield new FieldSymbol[IntType]("n_pt"+dim)}.toSeq
val numPPDs = {for (dim <- 1 to 3) yield new FieldSymbol[IntType]("n_ppds_a"+dim)}.toSeq
+ def getFortranAttributes = Set("type(CELL_INFO)")
}
object TightBox extends StructType {
val finishPts = {for (dim <- 1 to 3) yield new FieldSymbol[IntType]("finish_pts"+dim)}.toSeq
val startPPD = {for (dim <- 1 to 3) yield new FieldSymbol[IntType]("start_ppd"+dim)}.toSeq
val finishPPD = {for (dim <- 1 to 3) yield new FieldSymbol[IntType]("finish_ppd"+dim)}.toSeq
+ def getFortranAttributes = Set("type(FUNCTION_TIGHT_BOX)")
}
}