hare

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

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