progs/fun.scala
changeset 645 30943d5491b6
parent 644 b4f5714485e1
child 649 e83afb44f276
equal deleted inserted replaced
644:b4f5714485e1 645:30943d5491b6
     1 // A Small Compiler for a Simple Functional Language
     1 // A Small Compiler for a Simple Functional Language
     2 // (includes an external lexer and parser)
     2 // (includes an external lexer and parser)
     3 
     3 //
     4 import java.io._
     4 // call with 
       
     5 //
       
     6 //     scala fun.scala fact
       
     7 //
       
     8 //     scala fun.scala defs
       
     9 //
       
    10 // this will generate a .j file and run the jasmin
       
    11 // assembler (installed at jvm/jasmin-2.4/jasmin.jar)
       
    12 // it runs the resulting JVM file twice for timing 
       
    13 // purposes.
       
    14 
       
    15 
       
    16 
     5 
    17 
     6 object Compiler {
    18 object Compiler {
       
    19 
       
    20 import java.io._  
       
    21 import scala.util._
       
    22 import scala.sys.process._
     7 
    23 
     8 // Abstract syntax trees for the Fun language
    24 // Abstract syntax trees for the Fun language
     9 abstract class Exp extends Serializable 
    25 abstract class Exp extends Serializable 
    10 abstract class BExp extends Serializable 
    26 abstract class BExp extends Serializable 
    11 abstract class Decl extends Serializable 
    27 abstract class Decl extends Serializable 
   163   for (j <- 1 to i) code
   179   for (j <- 1 to i) code
   164   val end = System.nanoTime()
   180   val end = System.nanoTime()
   165   (end - start)/(i * 1.0e9)
   181   (end - start)/(i * 1.0e9)
   166 }
   182 }
   167 
   183 
   168 def deserialise[T](fname: String) : T = {
   184 def deserialise[T](fname: String) : Try[T] = {
   169   val in = new ObjectInputStream(new FileInputStream(fname))
   185   import scala.util.Using
   170   val data = in.readObject.asInstanceOf[T]
   186   Using(new ObjectInputStream(new FileInputStream(fname))) {
   171   in.close
   187     in => in.readObject.asInstanceOf[T]
   172   data
   188   }
   173 }
   189 }
   174 
       
   175 
   190 
   176 def compile(class_name: String) : String = {
   191 def compile(class_name: String) : String = {
   177   val ast = deserialise[List[Decl]](class_name ++ ".prs") 
   192   val ast = deserialise[List[Decl]](class_name ++ ".prs").getOrElse(Nil) 
   178   val instructions = ast.map(compile_decl).mkString
   193   val instructions = ast.map(compile_decl).mkString
   179   (library + instructions).replaceAllLiterally("XXX", class_name)
   194   (library + instructions).replaceAllLiterally("XXX", class_name)
   180 }
   195 }
   181 
   196 
   182 def compile_to_file(class_name: String) = {
   197 def compile_to_file(class_name: String) = {
   183   val output = compile(class_name)
   198   val output = compile(class_name)
   184   scala.tools.nsc.io.File(s"${class_name}.j").writeAll(output)
   199   scala.tools.nsc.io.File(s"${class_name}.j").writeAll(output)
   185 }
   200 }
   186 
   201 
   187 import scala.sys.process._
   202 def compile_and_run(class_name: String) : Unit = {
   188 
       
   189 def compile_run(class_name: String) : Unit = {
       
   190   compile_to_file(class_name)
   203   compile_to_file(class_name)
   191   (s"java -jar jvm/jasmin-2.4/jasmin.jar ${class_name}.j").!!
   204   (s"java -jar jvm/jasmin-2.4/jasmin.jar ${class_name}.j").!!
   192   println("Time: " + time_needed(2, (s"java ${class_name}/${class_name}").!))
   205   println("Time: " + time_needed(2, (s"java ${class_name}/${class_name}").!))
   193 }
   206 }
   194 
   207 
   195 
   208 
   196 // some examples of .fun files
   209 // some examples of .fun files
   197 //compile_file("fact")
   210 //compile_to_file("fact")
   198 //compile_run("defs")
   211 //compile_and_run("fact")
   199 //compile_run("fact")
   212 //compile_and_run("defs")
       
   213 
   200 
   214 
   201 def main(args: Array[String]) = 
   215 def main(args: Array[String]) = 
   202    compile_run(args(0))
   216    compile_and_run(args(0))
   203 
   217 
   204 
   218 
   205 }
   219 }