main.ha (2308B)
1 // SPDX-License-Identifier: GPL-3.0-only 2 // (c) Hare authors <https://harelang.org> 3 4 use bufio; 5 use fmt; 6 use fs; 7 use getopt; 8 use hare::ast; 9 use hare::lex; 10 use hare::parse; 11 use hare::types; 12 use hare::unit; 13 use io; 14 use os; 15 16 export fn main() void = { 17 let usage: []getopt::help = [ 18 "compiles Hare programs to an intermediate form", 19 ('D', "ident:type=value", "defines a constant"), 20 ('T', "tags...", "sets build tags"), 21 ('N', "ident", "set the namespace for unit"), 22 ('o', "path", "set the output file"), 23 ('t', "path", "write typedefs to a file"), 24 "files...", 25 ]; 26 let cmd = getopt::parse(os::args, usage...); 27 defer getopt::finish(&cmd); 28 29 let out = os::stdout; 30 for (let i = 0z; i < len(cmd.opts); i += 1) { 31 let opt = cmd.opts[i]; 32 switch (opt.0) { 33 case 'D' => abort(); // TODO 34 case 'N' => abort(); // TODO 35 case 'T' => abort(); // TODO 36 case 'o' => 37 out = match (os::create(opt.1, 0o644)) { 38 case let f: io::file => 39 yield f; 40 case let e: fs::error => 41 fmt::fatal(fs::strerror(e)); 42 }; 43 case 't' => abort(); // TODO 44 case => abort(); 45 }; 46 }; 47 48 if (len(cmd.args) == 0) { 49 getopt::printusage(os::stderr, os::args[0], usage)!; 50 os::exit(1); 51 }; 52 53 // TODO: Use hare::unit resolver 54 const store = types::store(types::x86_64, null, null); 55 defer types::store_free(store); 56 57 let subunits: []ast::subunit = []; 58 defer for (let i = 0z; i < len(subunits); i += 1) { 59 ast::subunit_finish(subunits[i]); 60 }; 61 62 for (let i = 0z; i < len(cmd.args); i += 1) { 63 let input = match (os::open(cmd.args[i])) { 64 case let f: io::file => 65 yield f; 66 case let err: fs::error => 67 fmt::fatalf("Error opening {}: {}", 68 cmd.args[i], fs::strerror(err)); 69 }; 70 defer io::close(input)!; 71 static let buf: [os::BUFSZ]u8 = [0...]; 72 let bufin = bufio::init(input, buf, []); 73 defer io::close(&bufin)!; 74 let sc = bufio::newscanner(&bufin); 75 defer bufio::finish(&sc); 76 77 let lexer = lex::init(&sc, cmd.args[i]); 78 let su = match (parse::subunit(&lexer)) { 79 case let err: parse::error => 80 printerr(err); 81 os::exit(1); 82 case let u: ast::subunit => 83 yield u; 84 }; 85 append(subunits, su); 86 }; 87 88 let unit = match (unit::check(store, [], subunits)) { 89 case unit::error => abort(); // TODO 90 case let u: unit::unit => 91 yield u; 92 }; 93 defer unit::unit_finish(unit); 94 gen(out, store, &unit); 95 };