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