/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id$ /**

* This program generates the Product$i classes, where * 0 <= i <+ MAXWIDTH. *

*

* usage: scala -classpath ... genprod PATH * where PATH is the desired output directory *

* * @author Burak Emir * @version 1.0 */ object genprod { /** The biggest ?? has Sup?? - 1 components/arguments */ val SUP_PRODUCT_ARITY = 23 val SUP_TUPLE_ARITY = 23 val SUP_FUNCTION_ARITY = 9 def productClassname(i: Int) = "Product"+i def productFilename(i: Int) = productClassname(i)+".scala" def tupleClassname(i: Int) = "Tuple"+i def tupleFilename(i: Int) = tupleClassname(i)+".scala" def functionClassname(i: Int) = "Function"+i def functionFilename(i: Int) = functionClassname(i)+".scala" def targs(i: Int) = for (val j <- List.range(1, i+1)) yield "T" + j def covariantArgs(i: Int) = for (val t <- targs(i)) yield "+" + t def contraCoArgs(i: Int) = (for (val t <- targs(i)) yield "-" + t) ::: List("+R") def vdefs(i: Int) = for (val j <- List.range(1, i+1)) yield "v" + j def mdefs(i: Int) = for (val j <- List.range(1, i+1)) yield "_" + j def zippedAndCommaSeparated (left: List[String], right: List[String]): String = { val sb = new StringBuffer() val it = (left zip right).elements def append1 = { val p = it.next sb.append(p._1).append(':').append(p._2) } if (it.hasNext) { append1 while(it.hasNext) { sb.append(", "); append1 } } sb.toString } def fields(i: Int) = zippedAndCommaSeparated(mdefs(i), targs(i)) def funArgs(i: Int) = zippedAndCommaSeparated(vdefs(i), targs(i)) def productFiles = for(val i <- List.range(0, SUP_PRODUCT_ARITY)) yield ProductFile.make(i) def tupleFiles = for(val i <- List.range(1, SUP_TUPLE_ARITY)) yield TupleFile.make(i) def functionFiles = for(val i <- List.range(0, SUP_FUNCTION_ARITY)) yield FunctionFile.make(i) def allfiles = productFiles ::: tupleFiles ::: functionFiles def main(args:Array[String]) = { if (args.length != 1) { Console.println("please give path of output directory") System.exit(-1) } import java.io.{File, FileOutputStream} import java.nio.channels.Channels val out = args(0) for (val node <- allfiles) { val f = new File(out + File.separator + node.attributes("name")) try { f.createNewFile val fos = new FileOutputStream(f) val c = fos.getChannel val w = Channels.newWriter(c, "utf-8") w.write(node.text) w.close } catch { case e: java.io.IOException => Console.println(e.getMessage() + ": " + out) System.exit(-1) } } } } /* zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz F U N C T I O N zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */ object FunctionFile { import genprod._ def make(i: Int) = { val __typeArgs__ = contraCoArgs(i).mkString("[",", ","]") val __funArgs__ = funArgs(i) /* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id$ // generated by genprod on {new java.util.Date().toString()} {if(descriptiveComment(i).length > 0) "(with fancy comment)" else ""} {if(moreMethods(i).length > 0) "(with extra methods)" else ""} package scala /** <p> * Function with {i} parameters. * </p> * {descriptiveComment(i)} */ trait {functionClassname(i)}{__typeArgs__} extends AnyRef {{ def apply({__funArgs__}): R override def toString() = "<function>" {moreMethods(i)} }} } def moreMethods(i:Int) = i match { case 1 => """ /** (f compose g)(x) = f(g(x)) */ def compose[A](g: A => T1): A => R = { x => apply(g(x)) } /** (f andThen g)(x) = g(f(x)) */ def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } """ case _ => "" } def descriptiveComment(i: Int) = i match { case 0 => """

In the following example the definition of * currentSeconds is a shorthand for the anonymous class * definition anonfun0: *

*
 *  object Main extends Application {
 *
 *    val currentSeconds = () => System.currentTimeMillis() / 1000L
 *
 *    val anonfun0 = new Function0[Long] {
 *      def apply(): Long = System.currentTimeMillis() / 1000L
 *    }
 *
 *    Console.println(currentSeconds())
 *    Console.println(anonfun0())
 *  }
""" case 1 => """

In the following example the definition of * succ is a shorthand for the anonymous class definition * anonfun1: *

*
 *  object Main extends Application {
 *
 *    val succ = (x: Int) => x + 1
 *
 *    val anonfun1 = new Function1[Int, Int] {
 *      def apply(x: Int): Int = x + 1
 *    }
 *
 *    Console.println(succ(0))
 *    Console.println(anonfun1(0))
 *  }
""" case 2 => """

In the following example the definition of * max is a shorthand for the anonymous class definition * anonfun2: *

*
 *  object Main extends Application {
 *
 *    val max = (x: Int, y: Int) => if (x < y) y else x
 *
 *    val anonfun2 = new Function2[Int, Int, Int] {
 *      def apply(x: Int, y: Int): Int = if (x < y) y else x
 *    }
 *
 *    Console.println(max(0, 1))
 *    Console.println(anonfun2(0, 1))
 *  }
""" case _ => "" } } // object FunctionFile /* zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz T U P L E zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */ object TupleFile { import genprod._ def make(i: Int) = { val __typeArgs__ = covariantArgs(i).mkString("[",", ","]") val __fields__ = fields(i) /* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id$ // generated by genprod on {new java.util.Date().toString()} package scala /** {tupleClassname(i)} is the canonical representation of a @see {productClassname(i)} */ case class {tupleClassname(i)}{__typeArgs__}({ __fields__ }) {{ override def toString() = {{ val sb = new compat.StringBuilder { if ({i} == 1) "sb.append('{').append(_" + {i} + ").append(\",}\")" else { val xs = List.range(1, i+1).map(i => ".append(_" + i + ")") xs.mkString("sb.append('{')", ".append(',')",".append('}')") } } sb.toString }} }} } } // object TupleFile /* zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz P R O D U C T zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */ object ProductFile { import genprod._ def make(i:Int) = { val __typeArgs__ = if (i==0) Nil else covariantArgs(i).mkString("[",", ","]") val __refArgs__ = if (i==0) Nil else targs(i).mkString("[",", ","]") /* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id$ // generated by genprod on {new java.util.Date().toString()} package scala import Predef._ object {productClassname(i)} {{ def unapply{__refArgs__}(x: Any): Option[{productClassname(i)}{__refArgs__}] = if (x.isInstanceOf[{productClassname(i)}{__refArgs__}]) Some(x.asInstanceOf[{productClassname(i)}{__refArgs__}]) else None }} /** {productClassname(i)} is a cartesian product of {i} components */ trait {productClassname(i)}{__typeArgs__} extends Product {{ /** * The arity of this product. * @return {i} */ override def arity = {i} /** * Returns the n-th projection of this product if 0&lt;=n&lt;arity, * otherwise null. * * @param n number of the projection to be returned * @return same as _(n+1) * @throws IndexOutOfBoundsException */ override def element(n: Int) = n match {{ {for(val Tuple2(m, j) <- mdefs(i).zip(List.range(0, i))) yield "case "+j+" => "+m+"\n "}case _ => throw new IndexOutOfBoundsException(n.toString()) }} {for(val Tuple2(m, t) <- mdefs(i) zip targs(i)) yield "/** projection of this product */\n def " + m + ": " + t + "\n\n" } }} } }