--- 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.")
}