~smlavine/hareimports-dev

Scan module instead of reading from stdin v1 SUPERSEDED

Sebastian: 1
 Scan module instead of reading from stdin

 1 files changed, 77 insertions(+), 17 deletions(-)
May 22, 2022 21:12:30 Sebastian LaVine <mail@smlavine.com>:
Next
Sorry I'm taking a while with this; I've been busy and haven't gotten the 
chance to finish this up. I should have a patch ready by either today or 
tomorrow.
- Sebastian
Sounds good! No worries.
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~smlavine/hareimports-dev/patches/32460/mbox | git am -3
Learn more about email & git

[PATCH] Scan module instead of reading from stdin Export this patch

To add imports, the program needs to be able to distinguish between
module identifiers and local enum identifiers. Enums may be declared in
other source files within the module, so knowledge of the entire module
is required to make this distinction.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
---
 main.ha | 94 ++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 77 insertions(+), 17 deletions(-)

diff --git a/main.ha b/main.ha
index 22e734b..c70750c 100644
--- a/main.ha
+++ b/main.ha
@@ -14,34 +14,94 @@
// along with this program. If not, see http://www.gnu.org/licenses/.

use fmt;
use getopt;
use hare::ast;
use hare::lex;
use hare::module;
use hare::parse;
use hare::unparse;
use io;
use os;
use strings;

export fn main() void = {
	const lexer = lex::init(os::stdin, "<stdin>", lex::flags::NONE);
	const help: []getopt::help = [
		"Hare import manager",
		('T', "tags...", "set tags"),
		"[<path>]"
	];
	const cmd = getopt::parse(os::args, help...);
	defer getopt::finish(&cmd);

	const subunit = match (parse::subunit(&lexer)) {
	case let s: ast::subunit =>
		yield s;
	case let e: parse::error =>
		fmt::fatalf(parse::strerror(e));
	let tags: []module::tag = [];
	defer module::tags_free(tags);
	for (let i = 0z; i < len(cmd.opts); i += 1) {
		const opt = cmd.opts[i];
		switch (opt.0) {
		case 'T' =>
			if (len(tags) > 0) {
				getopt::printusage(os::stderr,
					"hareimports", help);
				os::exit(1);
			};
			tags = match (module::parsetags(opt.1)) {
			case void =>
				fmt::fatal("Invalid tag set");
			case let t: []module::tag =>
				yield t;
			};
		case => abort();
		};
	};

	const path = switch (len(cmd.args)) {
	case 0 =>
		yield ".";
	case 1 =>
		yield cmd.args[0];
	case =>
		getopt::printusage(os::stderr, "hareimports", help);
		os::exit(1);
	};
	defer ast::subunit_finish(subunit);

	for (let i = 0z; i < len(subunit.imports); i += 1) {
		const m = &subunit.imports[i];
	const mctx = module::context_init(tags, [], "");
	defer module::context_finish(&mctx);

	const ver = match (module::scan(&mctx, path)) {
	case let v: module::version =>
		yield v;
	case let e: module::error =>
		fmt::fatal(module::strerror(e));
	};

	for (let i = 0z; i < len(ver.inputs); i += 1) {
		const input = ver.inputs[i];
		if (input.ft != module::filetype::HARE) {
			continue;
		};
		const f = os::open(input.path)!;
		defer io::close(f)!;

		const lexer = lex::init(f, "<stdin>");
		const subunit = match (parse::subunit(&lexer)) {
		case let s: ast::subunit =>
			yield s;
		case let e: parse::error =>
			fmt::fatal(parse::strerror(e));
		};
		defer ast::subunit_finish(subunit);

		const joined_ident = strings::join("::", m.ident...);
		defer free(joined_ident);
		fmt::printfln("{}:", input.path)!;
		for (let i = 0z; i < len(subunit.imports); i += 1) {
			const m = &subunit.imports[i];

		switch (m.mode) {
		case ast::import_mode::ALIAS =>
			fmt::printfln("{} (= {})", m.alias, joined_ident)!;
		case =>
			fmt::println(joined_ident)!;
			const s = unparse::identstr(m.ident);
			defer free(s);
			switch (m.mode) {
			case ast::import_mode::ALIAS =>
				fmt::printfln("{} (= {})", m.alias, s)!;
			case =>
				fmt::println(s)!;
			};
		};
	};
};
-- 
2.35.1

Thanks for the substantial patch! I've spent a bit of time looking it
over as well the relevant documentation so that I can understand it as
best I can. Overall I think this looks good, howeever I have a few
questions and nitpicks:

On Sun May 22, 2022 at 7:10 PM EDT, Sebastian wrote: