hare

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

main.ha (2552B)


      1 // SPDX-License-Identifier: GPL-3.0-only
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bufio;
      5 use fmt;
      6 use getopt;
      7 use hare::ast;
      8 use hare::lex;
      9 use hare::parse;
     10 use hare::types;
     11 use hare::unparse;
     12 use io;
     13 use memio;
     14 use os;
     15 use path;
     16 use strings;
     17 
     18 fn typeinfo(
     19 	store: *types::typestore,
     20 	s: str,
     21 ) (void | io::error | parse::error | types::deferred | types::error) = {
     22 	const hatype = if (s == "null") {
     23 		fmt::println("null")?;
     24 		yield types::lookup_builtin(store, ast::builtin_type::NULL);
     25 	} else {
     26 		let stream = memio::fixed(strings::toutf8(s));
     27 		defer io::close(&stream)!;
     28 		let sc = bufio::newscanner(&stream);
     29 		defer bufio::finish(&sc);
     30 		let lexer = lex::init(&sc, "-");
     31 		const atype = parse::_type(&lexer)?;
     32 		defer ast::type_finish(&atype);
     33 		const typ = types::lookup(store, &atype)?;
     34 		unparse::_type(os::stdout, &unparse::syn_nowrap, &atype)?;
     35 		fmt::println()?;
     36 		yield typ;
     37 	};
     38 	fmt::println("\tid:", hatype.id)?;
     39 	fmt::println("\tsize:",
     40 		if (hatype.sz == types::SIZE_UNDEFINED) "undefined"
     41 		else hatype.sz)?;
     42 	fmt::println("\talign:",
     43 		if (hatype._align == types::SIZE_UNDEFINED) "undefined"
     44 		else hatype._align)?;
     45 };
     46 
     47 fn str_to_arch(name: str) types::arch = {
     48 	switch (name) {
     49 	case "aarch64" =>
     50 		return types::aarch64;
     51 	case "riscv64" =>
     52 		return types::riscv64;
     53 	case "x86_64" =>
     54 		return types::x86_64;
     55 	case =>
     56 		fmt::fatal("Unsupported architecture", name);
     57 	};
     58 };
     59 
     60 export fn main() void = {
     61 	let arch = os::arch_name(os::architecture());
     62 	let arch = str_to_arch(arch);
     63 
     64 	const help: []getopt::help = [
     65 		"prints information about Hare types",
     66 		('m', "arch", "set target architecture (x86_64, aarch64, riscv64)"),
     67 		"types...",
     68 	];
     69 	const cmd = getopt::parse(os::args, help...);
     70 	defer getopt::finish(&cmd);
     71 	for (let i = 0z; i < len(cmd.opts); i += 1) {
     72 		const opt = cmd.opts[i];
     73 		switch (opt.0) {
     74 		// TODO: tags
     75 		case 'm' =>
     76 			arch = str_to_arch(opt.1);
     77 		case => abort(); // unreachable
     78 		};
     79 	};
     80 	if (len(cmd.args) == 0) {
     81 		const name = path::basename(os::args[0]);
     82 		getopt::printusage(os::stderr, name, help)!;
     83 		os::exit(1);
     84 	};
     85 
     86 	const store = types::store(arch, null, null);
     87 	defer types::store_free(store);
     88 	for (let i = 0z; i < len(cmd.args); i += 1) {
     89 		match (typeinfo(store, cmd.args[i])) {
     90 		case void => void;
     91 		case let err: io::error =>
     92 			fmt::fatal("I/O error:", io::strerror(err));
     93 		case let err: parse::error =>
     94 			fmt::fatal(parse::strerror(err));
     95 		case let err: types::error =>
     96 			fmt::fatal(types::strerror(err));
     97 		case types::deferred =>
     98 			fmt::fatal("Invalid type");
     99 		};
    100 	};
    101 };