hare.ha (2661B)
1 // SPDX-License-Identifier: GPL-3.0-only 2 // (c) Hare authors <https://harelang.org> 3 4 use bufio; 5 use fmt; 6 use hare::ast; 7 use hare::module; 8 use hare::unparse; 9 use io; 10 use os; 11 use strings; 12 13 // Formats output as Hare source code (prototypes) 14 export fn emit_hare(ctx: *context) (void | error) = { 15 const summary = ctx.summary; 16 17 let first = true; 18 match (ctx.readme) { 19 case let readme: io::file => 20 first = false; 21 for (true) { 22 match (bufio::read_line(readme)?) { 23 case io::EOF => 24 break; 25 case let b: []u8 => 26 fmt::fprintfln(ctx.out, 27 "// {}", strings::fromutf8(b)!)?; 28 free(b); 29 }; 30 }; 31 case void => void; 32 }; 33 34 emit_submodules_hare(ctx)?; 35 36 // XXX: Should we emit the dependencies, too? 37 for (let i = 0z; i < len(summary.types); i += 1) { 38 if (!first) { 39 fmt::fprintln(ctx.out)?; 40 }; 41 first = false; 42 details_hare(ctx, summary.types[i])?; 43 }; 44 for (let i = 0z; i < len(summary.constants); i += 1) { 45 if (!first) { 46 fmt::fprintln(ctx.out)?; 47 }; 48 first = false; 49 details_hare(ctx, summary.constants[i])?; 50 }; 51 for (let i = 0z; i < len(summary.errors); i += 1) { 52 if (!first) { 53 fmt::fprintln(ctx.out)?; 54 }; 55 first = false; 56 details_hare(ctx, summary.errors[i])?; 57 }; 58 for (let i = 0z; i < len(summary.globals); i += 1) { 59 if (!first) { 60 fmt::fprintln(ctx.out)?; 61 }; 62 first = false; 63 details_hare(ctx, summary.globals[i])?; 64 }; 65 for (let i = 0z; i < len(summary.funcs); i += 1) { 66 if (!first) { 67 fmt::fprintln(ctx.out)?; 68 }; 69 first = false; 70 details_hare(ctx, summary.funcs[i])?; 71 }; 72 }; 73 74 fn emit_submodules_hare(ctx: *context) (void | error) = { 75 if (len(ctx.submods) != 0) { 76 fmt::fprintln(ctx.out)?; 77 if (len(ctx.ident) == 0) { 78 fmt::fprintln(ctx.out, "// Modules")?; 79 } else { 80 fmt::fprintln(ctx.out, "// Submodules")?; 81 }; 82 for (let i = 0z; i < len(ctx.submods); i += 1) { 83 let submodule = if (len(ctx.ident) != 0) { 84 const s = unparse::identstr(ctx.ident); 85 defer free(s); 86 yield strings::concat(s, "::", ctx.submods[i]); 87 } else { 88 yield strings::dup(ctx.submods[i]); 89 }; 90 defer free(submodule); 91 92 fmt::fprintf(ctx.out, "// - [[")?; 93 fmt::fprintf(ctx.out, submodule)?; 94 fmt::fprintfln(ctx.out, "]]")?; 95 }; 96 }; 97 }; 98 99 fn details_hare(ctx: *context, decl: ast::decl) (void | error) = { 100 if (len(decl.docs) == 0 && !ctx.show_undocumented) { 101 return; 102 }; 103 104 const iter = strings::tokenize(decl.docs, "\n"); 105 for (true) { 106 match (strings::next_token(&iter)) { 107 case void => 108 break; 109 case let s: str => 110 if (len(s) != 0) { 111 fmt::fprintfln(ctx.out, "//{}", s)?; 112 }; 113 }; 114 }; 115 116 unparse::decl(ctx.out, &unparse::syn_wrap, decl)?; 117 fmt::fprintln(ctx.out)?; 118 return; 119 };