]> git.unchartedbackwaters.co.uk Git - francis/ofc.git/commitdiff
Add initial Scala work and build scripts.
authorFrancis Russell <francis@unchartedbackwaters.co.uk>
Mon, 19 Dec 2011 22:58:01 +0000 (22:58 +0000)
committerFrancis Russell <francis@unchartedbackwaters.co.uk>
Mon, 19 Dec 2011 22:58:01 +0000 (22:58 +0000)
build.xml [new file with mode: 0644]
examples/integrals_kinetic.ofl [new file with mode: 0644]
ofc [new file with mode: 0755]
src/ofc/OFC.scala [new file with mode: 0644]
src/ofc/parser/Parser.scala [new file with mode: 0644]
src/ofc/parser/Statement.scala [new file with mode: 0644]

diff --git a/build.xml b/build.xml
new file mode 100644 (file)
index 0000000..3fdc897
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="OFC" default="build">
+  <property name="project.dir" value="."/>
+  <property name="main.class" value="ofc.OFC"/>
+
+  <target name="init">
+    <!-- derived path names -->
+    <property name="source.dir" value="${project.dir}/src"/>
+    <property name="build.dir" value="${project.dir}/build"/>
+    <property name="scala-library.jar" location="/usr/share/java/scala-library.jar"/>
+    <property name="scala-compiler.jar" location="/usr/share/java/scala-compiler.jar"/>
+
+    <path id="project.classpath">
+      <pathelement location="${scala-library.jar}"/>
+      <pathelement location="${build.dir}"/>
+    </path>
+
+    <path id="scala.classpath">
+      <pathelement location="${scala-compiler.jar}"/>
+      <pathelement location="${scala-library.jar}"/>
+    </path>
+
+    <!-- definition for the "scalac" and "scaladoc" ant tasks -->
+    <taskdef resource="scala/tools/ant/antlib.xml" classpathref="scala.classpath">
+    </taskdef>
+  </target>
+
+  <target name="clean" depends="init" description="clean">
+    <delete dir="${build.dir}"/>
+    <delete file="ofc.jar"/>
+  </target>
+
+  <!-- compile project -->
+  <target name="build" depends="init" description="build">
+    <mkdir dir="${build.dir}"/>
+    <scalac 
+      classpathref="scala.classpath"
+      srcdir="${source.dir}" 
+      destdir="${build.dir}" 
+      force="false"
+      deprecation="yes"
+    >
+      <include name="**/*.scala"/>
+    </scalac>
+  </target>
+
+  <target name="jar" depends="build">
+    <jar jarfile="ofc.jar">
+      <fileset dir="${build.dir}"/>
+      <zipfileset includes="**/*.class" src="${scala-library.jar}"/>
+      <manifest>
+        <attribute name="Main-Class" value="${main.class}"/>
+      </manifest>
+    </jar>
+  </target>
+</project>
diff --git a/examples/integrals_kinetic.ofl b/examples/integrals_kinetic.ofl
new file mode 100644 (file)
index 0000000..3357a13
--- /dev/null
@@ -0,0 +1,14 @@
+# Parameter information
+Matrix kinet
+FunctionSet bra, ket
+Index alpha, beta
+
+# Computation
+kinet[alpha, beta] = inner(bra[alpha], reciprocal(laplacian(reciprocal(fftbox(ket[beta])))*-0.5))
+
+# Implementation specific
+target ONETEP
+kinet is SPAM3("kinet")
+bra is PPDFunctionSet("bra_basis", "bras_on_grid")
+ket is PPDFunctionSet("ket_basis", "kets_on_grid")
+output is FortranFunction("integrals_kinetic", ["kinet", "bras_on_grid", "bra_basis", "kets_on_grid", "ket_basis"])
diff --git a/ofc b/ofc
new file mode 100755 (executable)
index 0000000..7e8fe60
--- /dev/null
+++ b/ofc
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+scala -cp build ofc.OFC "$@"
diff --git a/src/ofc/OFC.scala b/src/ofc/OFC.scala
new file mode 100644 (file)
index 0000000..7d42620
--- /dev/null
@@ -0,0 +1,12 @@
+package ofc
+import java.io.FileReader
+import parser.Parser
+
+object OFC extends Parser {
+
+  def main(args: Array[String]) {
+    if (args.isEmpty) throw new IllegalArgumentException("Unspecified input file.")
+    val reader = new FileReader(args(0))
+    println(parseAll(program, reader))
+  }
+}
diff --git a/src/ofc/parser/Parser.scala b/src/ofc/parser/Parser.scala
new file mode 100644 (file)
index 0000000..92fe892
--- /dev/null
@@ -0,0 +1,54 @@
+package ofc.parser
+
+import scala.util.parsing.combinator._
+
+sealed abstract class ScalarOperationTag
+case class MultiplicationTag() extends ScalarOperationTag
+case class DivisionTag() extends ScalarOperationTag
+
+class Parser extends JavaTokenParsers {
+  def program : Parser[List[Statement]] = rep(comment | declarations | definition | target | comment | specifics)
+  def comment : Parser[Comment] = "#"~!".*".r ^^ (v => new Comment(v._2))
+  def identifier : Parser[Identifier] = ident ^^ (v => new Identifier(v))
+
+  def oflType : Parser[OFLType] = matrixType | functionSetType | indexType
+  def matrixType : Parser[Matrix] = "Matrix" ^^ (_ => new Matrix)
+  def functionSetType : Parser[FunctionSet] = "FunctionSet" ^^ (_ => new FunctionSet)
+  def indexType : Parser[Index] = "Index" ^^ (_ => new Index)
+
+  def declarations: Parser[DeclarationList] = oflType~!repsep(identifier, ",") ^^ 
+    (d => new DeclarationList(d._1, d._2))
+
+  def definition: Parser[Definition] = indexedIdentifier~("="~>expr) ^^ (x => new Definition(x._1, x._2))
+  def expr : Parser[Expression] = term~opt(scalarOperator~!expr) ^^
+    (x => x._2 match { 
+      case None => x._1
+      case Some(y) => y._1 match { 
+        case MultiplicationTag() => new Multiplication(x._1, y._2) 
+        case DivisionTag() => new Division(x._1, y._2)
+      }
+    })
+
+  def scalarOperator : Parser[ScalarOperationTag] = mulOp | divOp
+  def mulOp : Parser[ScalarOperationTag] = "*" ^^ (_ => MultiplicationTag())
+  def divOp : Parser[ScalarOperationTag] = "/" ^^ (_ => DivisionTag())
+
+  def term: Parser[Expression] = scalarConstant ||| indexedIdentifier ||| operator
+  def scalarConstant : Parser[ScalarConstant] = floatingPointNumber ^^ (x => new ScalarConstant(x.toDouble))
+  def indexedIdentifier: Parser[IndexedTerm]  = identifier~opt("["~>repsep(identifier, ",")<~"]") ^^ 
+    (x => new IndexedTerm(x._1, x._2 match { 
+      case Some(list) => list 
+      case None => Nil 
+    }))
+  def operator : Parser[Operator] = identifier~("("~>repsep(expr, ",")<~")") ^^ (x => new Operator(x._1, x._2))
+
+  def target : Parser[Target] = "target"~!identifier ^^ (x => new Target(x._2))
+  def specifics : Parser[TargetAssignment] = identifier~("is"~>functionCall) ^^ (x => new TargetAssignment(x._1, x._2))
+  def functionCall : Parser[FunctionCall] = identifier~("("~>repsep(functionParameter, ",")<~")") ^^ 
+    (x => new FunctionCall(x._1, new ParameterList(x._2)))
+  
+  def functionParameter : Parser[Parameter] = stringParameter | numericParameter | parameterList
+  def stringParameter : Parser[StringParameter] = stringLiteral ^^ (x => new StringParameter(x.slice(1, x.length-1)))
+  def numericParameter : Parser[NumericParameter] = floatingPointNumber ^^ (x => new NumericParameter(x.toDouble))
+  def parameterList : Parser[ParameterList] = "["~>repsep(functionParameter, ",")<~"]" ^^ (x => new ParameterList(x))
+}
diff --git a/src/ofc/parser/Statement.scala b/src/ofc/parser/Statement.scala
new file mode 100644 (file)
index 0000000..f09c33b
--- /dev/null
@@ -0,0 +1,67 @@
+package ofc.parser
+
+class Identifier(name: String) {
+  override def toString : String = "id(\""+name+"\")"
+}
+
+sealed abstract class Statement
+class Comment(value: String) extends Statement {
+  override def toString : String = "comment(\""+value+"\")"
+}
+class DeclarationList(oflType: OFLType, names: List[Identifier]) extends Statement {
+  override def toString : String = "decl("+oflType+", "+names+")"
+}
+class Definition(term: IndexedTerm, expr: Expression) extends Statement {
+  override def toString : String = "define("+term+", "+expr+")"
+}
+class Target(name: Identifier) extends Statement {
+  override def toString : String = "target("+name+")"
+}
+class TargetAssignment(id: Identifier, value: FunctionCall) extends Statement {
+  override def toString : String = "target_assignment("+id+", "+value+")"
+}
+
+sealed abstract class OFLType
+class Matrix extends OFLType {
+  override def toString : String = "Matrix"
+}
+class FunctionSet extends OFLType {
+  override def toString : String = "FunctionSet"
+}
+class Index extends OFLType {
+  override def toString : String = "Index"
+}
+
+sealed abstract class Expression
+class ScalarConstant(s: Double) extends Expression {
+  override def toString : String = s.toString
+}
+class IndexedTerm(id: Identifier, indices : List[Identifier]) extends Expression {
+  override def toString : String = id+"["+indices.mkString(",")+"]"
+}
+class Operator(id: Identifier, operands : List[Expression]) extends Expression {
+  override def toString : String = "operator("+id+ ", ["+ operands.mkString(",")+"])"
+}
+
+sealed abstract class ScalarOperation extends Expression
+class Multiplication(a: Expression, b: Expression) extends ScalarOperation {
+  override def toString : String = "mul("+a.toString+","+b.toString+")"
+}
+class Division(a: Expression, b: Expression) extends ScalarOperation {
+  override def toString : String = "div("+a.toString+","+b.toString+")"
+}
+
+class FunctionCall(name: Identifier, params: ParameterList) {
+  override def toString : String = "call("+name+", "+params+")"
+}
+
+sealed abstract class Parameter
+class ParameterList(params: List[Parameter]) extends Parameter {
+  override def toString : String = "["+params.mkString(",")+"]"
+}
+class StringParameter(s: String)  extends Parameter {
+  override def toString : String = "\""+s+"\""
+}
+class NumericParameter(s: Double)  extends Parameter {
+  override def toString : String = s.toString
+}