summaryrefslogblamecommitdiff
path: root/src/build/genprod.scala
blob: bf4245b3827269420f929172b2ce026a4c37fd5d (plain) (tree)
1
2
3
4
5
6
7
8
9






                                                                          

       











                                                                     


                                                          
                             
                             
                             
 
                                            
 
                                                            
 
                                        
 
                                                        
 
                                              
 
                                                              
 

                                                   
 

                                         
 

                                                           

                     
                                                   

                     
                                                   








                                                                                   
                     




                                                    
 


                                                                   

                    
                                                                            

                  
                                                                        







                                                                              
                           


                                                             

                                           
























                                                                              
                                                                          




                                                                          

       

                                                                                                                                                                                                 


             



                                   
   
                                                            








                                           

                                   
                                                           


                                   
                                                           


                
                                            






                                                                        
  
                                                                          
  


                                                                     
  









                                                                         
  
                                         
  


                                                            
  









                                                                        
  
                                                                            
  


                                                                                 
  


                                     










                                                                              

                                                              


                                                                          
                                                                          






                                                                          


                                                            

                                                                                          
                                                               
 




                                                                                                                                        













                                                                                
                                                                       


                                                                          
                                                                          




                                                                          


                                                            
 



               




                                                                                                                             

                                                                  
                                                            







                                

                                                                              
    
                                                      

                                        

                                           
                                                            


                                                                                                  
                                                       




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

// $Id$

/** <p>
 *   This program generates the <code>Product$i</code> classes, where
 *   <code>0 &lt;= i &lt;+ MAXWIDTH</code>.
 *  </p>
 *  <p>
 *    usage: <code>scala -classpath ... genprod PATH</code>
 *    where <code>PATH</code> 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"))
      f.createNewFile
      val fos = new FileOutputStream(f)
      val c = fos.getChannel
      val w = Channels.newWriter(c, "utf-8")
      w.write(node.text)
      w.close
    }
  }
}

/* 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)
<file name={functionFilename(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


/** &lt;p&gt;
 *    Function with {i} parameters.
 *  &lt;/p&gt;
 *  {descriptiveComment(i)}
 */
trait {functionClassname(i)}{__typeArgs__} extends AnyRef {{
  def apply({__funArgs__}): R
  override def toString() = "&lt;function>"
  {moreMethods(i)}
}}
</file>
}

  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 => """<p>
      In the following example the definition of
 *    <code>currentSeconds</code> is a shorthand for the anonymous class
 *    definition <code>anonfun0</code>:
 *  </p>
 *  <pre>
 *  <b>object</b> Main <b>extends</b> Application {
 *
 *    <b>val</b> currentSeconds = () => System.currentTimeMillis() / 1000L
 *
 *    <b>val</b> anonfun0 = <b>new</b> Function0[Long] {
 *      <b>def</b> apply(): Long = System.currentTimeMillis() / 1000L
 *    }
 *
 *    Console.println(currentSeconds())
 *    Console.println(anonfun0())
 *  }</pre>"""
    case 1 => """<p>
      In the following example the definition of
 *    <code>succ</code> is a shorthand for the anonymous class definition
 *    <code>anonfun1</code>:
 *  </p>
 *  <pre>
 *  <b>object</b> Main <b>extends</b> Application {
 *
 *    <b>val</b> succ = (x: Int) => x + 1
 *
 *    <b>val</b> anonfun1 = <b>new</b> Function1[Int, Int] {
 *      <b>def</b> apply(x: Int): Int = x + 1
 *    }
 *
 *    Console.println(succ(0))
 *    Console.println(anonfun1(0))
 *  }</pre>"""
    case 2 => """<p>
      In the following example the definition of
 *    <code>max</code> is a shorthand for the anonymous class definition
 *    <code>anonfun2</code>:
 *  </p>
 *  <pre>
 *  <b>object</b> Main <b>extends</b> Application {
 *
 *    <b>val</b> max = (x: Int, y: Int) => <b>if</b> (x < y) y <b>else</b> x
 *
 *    <b>val</b> anonfun2 = <b>new</b> Function2[Int, Int, Int] {
 *      <b>def</b> apply(x: Int, y: Int): Int = <b>if</b> (x < y) y <b>else</b> x
 *    }
 *
 *    Console.println(max(0, 1))
 *    Console.println(anonfun2(0, 1))
 *  }</pre>"""
    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)
<file name={tupleFilename(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
	 sb.append('{{'){for(val j <- List.range(1,i)) yield <xml:group>.append(_{j}).append(',')</xml:group>}.append(_{i}).append('}}')
	 sb.toString
   }}
}}
</file>
    }
} // 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("[",", ","]")
<file name={productFilename(i)}>
/*                     __                                               *\
**     ________ ___   / /  ___     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&amp;lt;=n&amp;lt;arity,
   *  otherwise <code>null</code>.
   *
   *  @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  " }
}}
</file>
  }
}