diff -r 2f9a0dcf61ae -r 059f970287d1 progs/fun/fun_llvm.sc --- 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.") }