commit 4c930f9ad308c8859664382c5e78093d4f1a231f
parent 404dddd275436a5030311e3403b1638fc0d064f6
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 26 Feb 2021 12:32:29 -0500
hare::module: new module (WIP)
Diffstat:
3 files changed, 105 insertions(+), 0 deletions(-)
diff --git a/hare/module/context.ha b/hare/module/context.ha
@@ -0,0 +1,47 @@
+use fs;
+use hare::ast;
+use os;
+use path;
+
+export type context = struct {
+ // Filesystem to use for the cache and source files.
+ fs: *fs::fs,
+ // List of paths to search, generally populated from HAREPATH plus some
+ // baked-in default.
+ paths: []str,
+ // Path to the Hare cache, generally populated from HARECACHE and
+ // defaulting to $XDG_CACHE_HOME/hare.
+ cache: str,
+ // Build tags to apply to this context.
+ tags: []tag,
+};
+
+// Initializes a new context with the system default configuration.
+export fn context_init(tags: []tag) context = {
+ let ctx = context {
+ fs = os::cwd,
+ tags = tags,
+ ...
+ };
+ // TODO: Insert default variables, look up environment, w/e
+ return ctx;
+};
+
+// Converts an identifier to a partial path (e.g. foo::bar becomes foo/bar). The
+// return value must be freed by the caller.
+export fn ident_path(name: ast::ident) path::path = {
+ let p = path::join(name[0]);
+ for (let i = 1z; i < len(name); i += 1) {
+ let q = path::join(p, name[i]);
+ path::path_free(p);
+ p = q;
+ };
+ return p;
+};
+
+@test fn ident_path() void = {
+ let ident: ast::ident = ["foo", "bar", "baz"];
+ let p = ident_path(ident);
+ defer path::path_free(p);
+ assert(path::equal(p, "foo/bar/baz"));
+};
diff --git a/hare/module/scan.ha b/hare/module/scan.ha
@@ -0,0 +1,17 @@
+use fs;
+use hare::ast;
+use slice;
+use path;
+use io;
+
+// Scans the files in a directory for eligible build inputs and returns a
+// [version] which includes all applicable files.
+export fn scan(ctx: *context, path: path::path) (version | error) = {
+ abort();
+};
+
+// Looks up a module by its identifier from HAREPATH, and returns a [version]
+// which includes all eligible build inputs.
+export fn lookup(ctx: *context, name: ast::ident) (version | error) = {
+ abort();
+};
diff --git a/hare/module/types.ha b/hare/module/types.ha
@@ -0,0 +1,41 @@
+use fs;
+use io;
+
+// The inclusive/exclusive state for a build tag.
+type tag_mode = enum {
+ INCLUSIVE,
+ EXCLUSIVE,
+};
+
+// A build tag, e.g. +x86_64.
+type tag = struct {
+ name: str,
+ mode: tag_mode,
+};
+
+// The manifest for a particular module, with some number of inputs, and
+// versions.
+type manifest = struct {
+ inputs: []input,
+ versions: []version,
+};
+
+// A module version: a set of possible input files for that module.
+type version = struct {
+ hash: str,
+ inputs: []input,
+};
+
+// An input to a module, generally a source file.
+type input = struct {
+ hash: str,
+ path: str,
+ tags: []tag,
+ stat: fs::filestat,
+};
+
+// The requested module could not be found.
+export type module_not_found = void!;
+
+// All possible error types.
+export type error = (fs::error | io::error | module_not_found);