hare

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

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 };