progs/fun/fun_llvm.sc
changeset 813 059f970287d1
parent 789 f0696713177b
child 819 fd88a0656164
--- a/progs/fun/fun_llvm.sc	Fri Nov 27 13:53:06 2020 +0000
+++ b/progs/fun/fun_llvm.sc	Tue Dec 01 05:41:12 2020 +0000
@@ -1,22 +1,35 @@
 // A Small LLVM Compiler for a Simple Functional Language
 // (includes an external lexer and parser)
 //
+//
 // call with 
 //
+//     amm fun_llvm.sc main fact.fun
+//     amm fun_llvm.sc main defs.fun
+//
+// or
+//
 //     amm fun_llvm.sc write fact.fun
-//
 //     amm fun_llvm.sc write defs.fun
 //
-// this will generate a .ll file. Other options are compile and run.
+//       this will generate an .ll file. 
+//
+// or 
 //
-// You can interpret an .ll file using lli.
+//     amm fun_llvm.sc run fact.fun
+//     amm fun_llvm.sc run defs.fun
+//
+//
+// You can interpret an .ll file using lli, for example
+//
+//      lli fact.ll
 //
 // The optimiser can be invoked as
 //
 //      opt -O1 -S in_file.ll > out_file.ll
 //      opt -O3 -S in_file.ll > out_file.ll
 //
-// The code produced for the various architectures can be obtains with
+// The code produced for the various architectures can be obtain with
 //   
 //   llc -march=x86 -filetype=asm in_file.ll -o -
 //   llc -march=arm -filetype=asm in_file.ll -o -  
@@ -30,7 +43,6 @@
 
 import $file.fun_tokens, fun_tokens._
 import $file.fun_parser, fun_parser._ 
-import scala.util._
 
 
 // for generating new labels
@@ -150,10 +162,11 @@
   case "/" => "sdiv i32 "
   case "%" => "srem i32 "
   case "==" => "icmp eq i32 "
-  case "<=" => "icmp sle i32 "    // signed less or equal
-  case "<" => "icmp slt i32 "     // signed less than
+  case "<=" => "icmp sle i32 "     // signed less or equal
+  case "<"  => "icmp slt i32 "     // signed less than
 }
 
+// compile K values
 def compile_val(v: KVal) : String = v match {
   case KNum(i) => s"$i"
   case KVar(s) => s"%$s"
@@ -211,19 +224,22 @@
   }
 }
 
+
 // main compiler functions
-
-def compile_prog(prog: List[Decl]) : String = 
+def compile(prog: List[Decl]) : String = 
   prelude ++ (prog.map(compile_decl).mkString)
 
 
+import ammonite.ops._
+
+
 @main
-def compile(fname: String) = {
+def main(fname: String) = {
     val path = os.pwd / fname
     val file = fname.stripSuffix("." ++ path.ext)
     val tks = tokenise(os.read(path))
     val ast = parse_tks(tks)
-    println(compile_prog(ast))
+    println(compile(ast))
 }
 
 @main
@@ -232,7 +248,7 @@
     val file = fname.stripSuffix("." ++ path.ext)
     val tks = tokenise(os.read(path))
     val ast = parse_tks(tks)
-    val code = compile_prog(ast)
+    val code = compile(ast)
     os.write.over(os.pwd / (file ++ ".ll"), code)
 }
 
@@ -240,13 +256,11 @@
 def run(fname: String) = {
     val path = os.pwd / fname
     val file = fname.stripSuffix("." ++ path.ext)
-    val tks = tokenise(os.read(path))
-    val ast = parse_tks(tks)
-    val code = compile_prog(ast)
-    os.write.over(os.pwd / (file ++ ".ll"), code)
+    write(fname)  
     os.proc("llc", "-filetype=obj", file ++ ".ll").call()
-    os.proc("gcc", file ++ ".o", "-o", file).call()
-    print(os.proc(os.pwd / file).call().out.string)
+    os.proc("gcc", file ++ ".o", "-o", file ++ ".bin").call()
+    os.proc(os.pwd / (file ++ ".bin")).call(stdout = os.Inherit)
+    println(s"done.")
 }