hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

main.ha (2308B)


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