hare

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

commit 78bedb21079c4c51939de6ee60adb4983ffb8ff1
parent 17b238f7f77f52c34d093fff259293f81d3b59a8
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 26 Feb 2021 14:52:59 -0500

hare::module: implement scan, somewhat

Diffstat:
Mhare/module/scan.ha | 59++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mhare/module/types.ha | 20+++++++++++++-------
2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/hare/module/scan.ha b/hare/module/scan.ha @@ -1,13 +1,51 @@ use fs; use hare::ast; -use slice; -use path; use io; +use path; +use slice; +use strings; // 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(); + let inputs: []input = []; + let iter = match (fs::iter(ctx.fs, path)) { + fs::wrongtype => { + let st = fs::stat(ctx.fs, path)?; + append(inputs, input { + path = path, + stat = st, + ... + }); + return version { + hash = "", // TODO + inputs = inputs, + }; + }, + err: fs::error => return err, + iter: *fs::iterator => iter, + }; + for (true) match (fs::next(iter)) { + void => break, + ent: fs::dirent => switch (ent.ftype) { + fs::mode::DIR => void, // TODO + fs::mode::LINK => abort(), // TODO + fs::mode::REG => if (eligible(ctx, ent.name)) { + let p = path::join(path, ent.name); + let st = fs::stat(ctx.fs, p)?; + append(inputs, input { + path = p, + stat = st, + ... + }); + }, + * => void, + }, + }; + return version { + hash = "", // TODO + inputs = inputs, + }; }; // Looks up a module by its identifier from HAREPATH, and returns a [version] @@ -15,3 +53,18 @@ export fn scan(ctx: *context, path: path::path) (version | error) = { export fn lookup(ctx: *context, name: ast::ident) (version | error) = { abort(); }; + +// TODO: Filter inputs by build tags +fn eligible(ctx: *context, name: path::path) bool = { + if (!(name is str)) { + return false; + }; + let name = name as str; + static const exts = [".ha", ".s"]; + for (let i = 0z; i < len(exts); i += 1) { + if (strings::has_suffix(name, exts[i])) { + return true; + }; + }; + return false; +}; diff --git a/hare/module/types.ha b/hare/module/types.ha @@ -1,36 +1,36 @@ use fs; use io; +use path; // The inclusive/exclusive state for a build tag. -type tag_mode = enum { +export type tag_mode = enum { INCLUSIVE, EXCLUSIVE, }; // A build tag, e.g. +x86_64. -type tag = struct { +export type tag = struct { name: str, mode: tag_mode, }; // The manifest for a particular module, with some number of inputs, and // versions. -type manifest = struct { +export type manifest = struct { inputs: []input, versions: []version, }; // A module version: a set of possible input files for that module. -type version = struct { +export type version = struct { hash: str, inputs: []input, }; // An input to a module, generally a source file. -type input = struct { +export type input = struct { hash: str, - path: str, - tags: []tag, + path: path::path, stat: fs::filestat, }; @@ -39,3 +39,9 @@ export type module_not_found = void!; // All possible error types. export type error = (fs::error | io::error | module_not_found); + +export fn errstr(err: error) const str = match (err) { + err: fs::error => fs::errstr(err), + err: io::error => io::errstr(err), + module_not_found => "Module not found", +};