hare

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

commit a9a501ab2226b36c9f6e369e5dc3b21cc008c60d
parent d311f7c612d56182a8803bed4377dfe3e063d985
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Date:   Tue,  1 Oct 2024 18:03:25 +0200

hare::module: Optionally gather modules recursively

Signed-off-by: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>

Diffstat:
Mhare/module/deps.ha | 47+++++++++++++++++++++++++++++------------------
1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/hare/module/deps.ha b/hare/module/deps.ha @@ -23,6 +23,7 @@ export type module = struct { srcs: srcset, // [](Index to the module, Identifier of of the module) deps: [](size, ast::ident), + is_dep: bool, }; // Get the list of dependencies referred to by a set of source files. @@ -107,43 +108,47 @@ fn get_deps(cachedir: str, srcs: *srcset) ([]ast::ident | error) = { return deps; }; -// Gather a [[module]] and all its dependencies, appending them to an existing -// slice, deduplicated, in reverse topological order, returning the index of the -// input module within the slice. Dependencies will also be written to the -// cache. +// Gather a [[module]] and by default all its dependencies, appending them to +// an existing slice, deduplicated, in reverse topological order, returning the +// index of the input module within the slice. Dependencies will also be written +// to the cache. export fn gather( ctx: *context, out: *[]module, mod: location, + recursive: bool = true, ) (size | error) = { let stack: []str = []; defer free(stack); - return _gather(ctx, out, &stack, mod)?; + return _gather(ctx, out, &stack, mod, false, recursive)?; }; -// Gather submodules and all their dependencies, appending them to an existing -// slice, deduplicated, in reverse topological order, returning the number of -// modules added to the slice. The submodules are searched relative to a parent -// directory that may target a module, or a source directory (for example a -// HAREPATH component). The parent module identifier should reflect the nature -// of the parent directory and may be left empty for source directories. -// Dependencies will also be written to the cache. +// Gather submodules and by default all their dependencies, appending them to +// an existing slice, deduplicated, in reverse topological order, returning the +// number of modules added to the slice. The submodules are searched relative +// to a parent directory that may target a module, or a source directory (for +// example a HAREPATH component). The parent module identifier should reflect +// the nature of the parent directory and should be left empty for source +// directories. Dependencies will also be written to the cache. export fn gather_submodules( ctx: *context, out: *[]module, buf: *path::buffer, mod: *ast::ident, + recursive: bool = true, ) (size | error) = { let n = 0z; let it = os::iter(path::string(buf))?; defer fs::finish(it); for (let dir => next(it)?) { + let stack: []str = []; + defer free(stack); path::push(buf, dir.name)?; defer path::pop(buf); append(mod, dir.name); defer delete(mod[len(mod) - 1]); - match (gather(ctx, out, *mod)) { + match (_gather(ctx, out, &stack, *mod, false, recursive)) { case size => n += 1; case let e: error => @@ -151,7 +156,7 @@ export fn gather_submodules( return e; }; }; - n += gather_submodules(ctx, out, buf, mod)?; + n += gather_submodules(ctx, out, buf, mod, recursive)?; }; return n; }; @@ -161,6 +166,8 @@ fn _gather( out: *[]module, stack: *[]str, mod: location, + is_dep: bool, + recursive: bool, ) (size | error) = { let (modpath, srcs) = match (find(ctx, mod)) { case let r: (str, srcset) => @@ -182,6 +189,7 @@ fn _gather( }; for (let j = 0z; j < len(out); j += 1) { if (modpath == out[j].path) { + out[j].is_dep &&= is_dep; return j; }; }; @@ -192,10 +200,12 @@ fn _gather( let depids = get_deps(cache, &srcs)?; defer free(depids); let deps: [](size, ast::ident) = alloc([], len(depids)); - for (let i = 0z; i < len(depids); i += 1) { - static append(deps, - (_gather(ctx, out, stack, depids[i])?, depids[i]) - ); + + if (!is_dep || recursive) { + for (let depid .. depids) { + static append(deps, (_gather(ctx, out, stack, depid, + true, recursive)?, depid)); + }; }; append(out, module { @@ -214,6 +224,7 @@ fn _gather( path = strings::dup(modpath), srcs = srcs, deps = deps, + is_dep = is_dep, }); return len(out) - 1; };