123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 | #!/usr/bin/env moon
util = require 'util'
import log, viz, set_file from util
number_code = (code, color="1")->
line = 0
(code\gsub("\n$","")\gsub "[^\n]*", =>
line += 1
"\x1b[2m#{("% 4d")\format line}|\x1b[22m \x1b[#{color}m#{@}\x1b[m"
)
verbose = false
compile = false
files, args = {}, {}
output_file = nil
qbe_file = nil
asm_file = nil
so_file = nil
i = 1
while i <= #arg
a = arg[i]
if a == "-h" or a == "--help"
print "blangc - compile blang programs\nUsage: blangc [-v|--verbose] [-c|--compile] [-o output_binary_file] [-a output_asm_file] [-q output_qbe_file] file"
os.exit!
elseif a == "-v" or a == "--verbose"
verbose = true
elseif a == "-c" or a == "--compile"
compile = true
elseif a == "-o"
output_file = assert(arg[i+1], "No output name provided")
i += 2
continue
elseif a == "-a"
asm_file = assert(arg[i+1], "No asm name provided")
i += 2
continue
elseif a == "-s"
so_file = assert(arg[i+1], "No .so file provided")
i += 2
continue
elseif a == "-q"
qbe_file = assert(arg[i+1], "No qbe name provided")
i += 2
continue
elseif a == "--"
args = {table.unpack(arg, i+1, #arg)}
break
else
table.insert files, a
i += 1
unless verbose
log = ->
util.log = log
parse = require 'parse'
import compile_prog from require 'compile'
mktemp = (suffix)-> io.popen("mktemp --suffix=#{suffix} /tmp/blang.XXXXXX")\read("l")
assert #files == 1, "Expected exactly one file, but got #{#files}"
filename = files[1]
file = assert(io.open(filename), "Couldn't open file: #{filename}")
log "\x1b[1;4mFile #{filename}\x1b[m"
with file
dirname = filename\match("^.*/") or "./"
base_name = filename\match("[^/]*$")\gsub("%.bl$", "")
text = \read "*a"
set_file filename, text
log number_code(text, "34;1")
ast = parse text, filename
assert ast, "No match!"
ast = ast[1]
log "#{viz ast}"
code = compile_prog ast, filename
log number_code(code, "36;1")
qbe_file or= filename..".qbe"
with io.open qbe_file, "w"
\write code
\close!
run = (cmd)->
log "> \x1b[1m#{cmd}\x1b[m"
success,how,what = os.execute cmd
if not success
log "\x1b[31;1mCommand `#{cmd}` #{how}ed: #{what}\x1b[m"
os.exit(1)
log "\x1b[2mRunning QBE...\x1b[m"
asm_file or= filename..".s"
run "qbe #{qbe_file} > #{asm_file}"
log "\x1b[2mCompiling assembly...\x1b[m"
output_file or= dirname..base_name..".o"
run "rm -f #{output_file}"
if compile
run "cc -O3 #{asm_file} -c -fPIC -ggdb -o #{output_file} -lm -lbhash -lbp -lgc -L . -lintern -lcord"
so_file or= dirname.."lib"..base_name..".so"
run "rm -f #{so_file}"
run "cc -O3 lib/*.o -shared -Wl,-soname,lib#{base_name}.so.1 -o #{so_file} #{output_file} -lc -lm -lbhash -lbp -lgc -L . -lintern -lcord"
log "Compiled to #{so_file}"
else
run "cc -O3 #{asm_file} -ggdb -o #{output_file} lib/*.o -lc -lm -lbhash -lbp -lgc -L . -lintern -lcord"
log "Compiled to #{output_file}"
\close!
|