From f78ed02b94b42d2b8cd9df6be9fa6cade2f6d76a Mon Sep 17 00:00:00 2001 From: Francis Russell Date: Mon, 19 Dec 2011 22:58:01 +0000 Subject: [PATCH] Add initial Scala work and build scripts. --- build.xml | 57 +++++++++++++++++++++++++++++ examples/integrals_kinetic.ofl | 14 +++++++ ofc | 3 ++ src/ofc/OFC.scala | 12 ++++++ src/ofc/parser/Parser.scala | 54 +++++++++++++++++++++++++++ src/ofc/parser/Statement.scala | 67 ++++++++++++++++++++++++++++++++++ 6 files changed, 207 insertions(+) create mode 100644 build.xml create mode 100644 examples/integrals_kinetic.ofl create mode 100755 ofc create mode 100644 src/ofc/OFC.scala create mode 100644 src/ofc/parser/Parser.scala create mode 100644 src/ofc/parser/Statement.scala diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..3fdc897 --- /dev/null +++ b/build.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/integrals_kinetic.ofl b/examples/integrals_kinetic.ofl new file mode 100644 index 0000000..3357a13 --- /dev/null +++ b/examples/integrals_kinetic.ofl @@ -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 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 index 0000000..7d42620 --- /dev/null +++ b/src/ofc/OFC.scala @@ -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 index 0000000..92fe892 --- /dev/null +++ b/src/ofc/parser/Parser.scala @@ -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 index 0000000..f09c33b --- /dev/null +++ b/src/ofc/parser/Statement.scala @@ -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 +} -- 2.47.3