diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 69030f3c808..67c26f9b07d 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -5,23 +5,111 @@ import front.token; import middle.trans; import middle.resolve; -io fn main(vec[str] args) { +import std.util.option; +import std.util.some; +import std.util.none; +import std._str; +import std._vec; +io fn compile_input(session.session sess, str input, str output) { + auto p = parser.new_parser(sess, 0, input); + auto crate = parser.parse_crate(p); + crate = resolve.resolve_crate(sess, crate); + trans.trans_crate(sess, crate, output); +} + +fn warn_wrong_compiler() { log "This is the rust 'self-hosted' compiler."; log "The one written in rust."; log "It does nothing yet, it's a placeholder."; log "You want rustboot, the compiler next door."; +} + +fn usage(session.session sess, str argv0) { + log #fmt("usage: %s [options] ", argv0); + log "options:"; + log ""; + log " -o write output to "; + log " -nowarn suppress wrong-compiler warning"; + log " -h display this message"; + log ""; + log ""; +} + +io fn main(vec[str] args) { - auto i = 0; auto sess = session.session(); - for (str filename in args) { - if (i > 0) { - auto p = parser.new_parser(sess, 0, filename); - auto crate = parser.parse_crate(p); - crate = resolve.resolve_crate(sess, crate); - trans.trans_crate(sess, crate); + let option[str] input_file = none[str]; + let option[str] output_file = none[str]; + let bool do_warn = true; + + auto i = 1u; + auto len = _vec.len[str](args); + + // FIXME: a getopt module would be nice. + while (i < len) { + auto arg = args.(i); + if (_str.byte_len(arg) > 0u && arg.(0) == '-' as u8) { + if (_str.eq(arg, "-nowarn")) { + do_warn = false; + } else { + // FIXME: rust could use an elif construct. + if (_str.eq(arg, "-o")) { + if (i+1u < len) { + output_file = some(args.(i+1u)); + i += 1u; + } else { + usage(sess, args.(0)); + sess.err("-o requires an argument"); + } + } else { + if (_str.eq(arg, "-h")) { + usage(sess, args.(0)); + } else { + usage(sess, args.(0)); + sess.err("unrecognized option: " + arg); + } + } + } + } else { + alt (input_file) { + case (some[str](_)) { + usage(sess, args.(0)); + sess.err("multiple inputs provided"); + } + case (none[str]) { + input_file = some[str](arg); + } + } + // FIXME: dummy node to work around typestate mis-wiring bug. + i = i; + } + i += 1u; + } + + if (do_warn) { + warn_wrong_compiler(); + } + + alt (input_file) { + case (none[str]) { + usage(sess, args.(0)); + sess.err("no input filename"); + } + case (some[str](?ifile)) { + alt (output_file) { + case (none[str]) { + let vec[str] parts = _str.split(ifile, '.' as u8); + parts = _vec.pop[str](parts); + parts += ".bc"; + auto ofile = _str.concat(parts); + compile_input(sess, ifile, ofile); + } + case (some[str](?ofile)) { + compile_input(sess, ifile, ofile); + } + } } - i += 1; } } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 6263c3db8cb..83e744ea4d2 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1095,7 +1095,7 @@ fn trans_main_fn(@trans_ctxt cx, ValueRef llcrate) { } -fn trans_crate(session.session sess, @ast.crate crate) { +fn trans_crate(session.session sess, @ast.crate crate, str output) { auto llmod = llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"), llvm.LLVMGetGlobalContext()); @@ -1138,7 +1138,7 @@ fn trans_crate(session.session sess, @ast.crate crate) { trans_exit_task_glue(cx); trans_main_fn(cx, crate_constant(cx)); - llvm.LLVMWriteBitcodeToFile(llmod, _str.buf("rust_out.bc")); + llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output)); llvm.LLVMDisposeModule(llmod); }