hare

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

commit 79d0f6184ef00ba6daa7bc6e30b046e36af4ae4c
parent 310ab1300e0548af73dcbe6012f5235443da44f4
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sat, 20 Apr 2024 22:16:16 -0400

haredoc: warn and continue on parsing error

This only applies to -Ftty; -Fhtml is unchanged.

Prior to this commit, haredoc would exit with a failure status if any
file failed to parse. Now, when a file fails to parse, haredoc will
display a warning showing all the parsing errors that occurred, but it
won't terminate; it will still show documentation from all files that
parsed successfully.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mcmd/haredoc/doc/resolve.ha | 11+++++++----
Mcmd/haredoc/doc/tty.ha | 20++++++++++++++++++++
Mcmd/haredoc/doc/types.ha | 1+
Mcmd/haredoc/main.ha | 44++++++++++++++++++++++++++++++++++++++------
4 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/cmd/haredoc/doc/resolve.ha b/cmd/haredoc/doc/resolve.ha @@ -148,8 +148,9 @@ fn lookup_remote_enum(ctx: *context, what: ast::ident) (ast::ident | void | erro free(decls); }; for (let in .. srcs.ha) { - let u = scan(in)?; - append(decls, u.decls...); + let d = scan(in)?; + defer free(d); + append(decls, d...); }; for (let decl .. decls) { @@ -178,7 +179,7 @@ fn lookup_remote_enum(ctx: *context, what: ast::ident) (ast::ident | void | erro }; }; -export fn scan(path: str) (ast::subunit | error) = { +export fn scan(path: str) ([]ast::decl | parse::error) = { const input = match (os::open(path)) { case let f: io::file => yield f; @@ -189,5 +190,7 @@ export fn scan(path: str) (ast::subunit | error) = { let sc = bufio::newscanner(input, types::SIZE_MAX); defer bufio::finish(&sc); let lexer = lex::init(&sc, path, lex::flag::COMMENTS); - return parse::subunit(&lexer)?; + let su = parse::subunit(&lexer)?; + ast::imports_finish(su.imports); + return su.decls; }; diff --git a/cmd/haredoc/doc/tty.ha b/cmd/haredoc/doc/tty.ha @@ -4,6 +4,7 @@ use bufio; use fmt; use hare::ast; +use hare::lex; use hare::unparse; use io; use memio; @@ -38,6 +39,25 @@ export fn emit_tty(ctx: *context) (void | error) = { fmt::fprintln(ctx.out, "\n")?; }; + if (len(ctx.parse_errs) > 0) { + if (!no_color) fmt::fprintf(ctx.out, "\x1b[{}m", + color(unparse::synkind::COMMENT))?; + fmt::fprint(ctx.out, "// ")?; + if (!no_color) fmt::fprint(ctx.out, "\x1b[93m")?; + fmt::fprint(ctx.out, "WARNING")?; + if (!no_color) fmt::fprintf(ctx.out, "\x1b[m" "\x1b[{}m", + color(unparse::synkind::COMMENT))?; + fmt::fprintln(ctx.out, + ": parsing errors occurred; documentation may be incomplete")?; + if (!no_color) fmt::fprint(ctx.out, "\x1b[m")?; + }; + for (let i = 0z; i < len(ctx.parse_errs); i += 1) { + fmt::fprintln(ctx.out, "//", lex::strerror(ctx.parse_errs[i]))?; + }; + if (len(ctx.parse_errs) > 0) { + fmt::fprintln(ctx.out)?; + }; + match (ctx.readme) { case let readme: io::file => let rbuf: [os::BUFSZ]u8 = [0...]; diff --git a/cmd/haredoc/doc/types.ha b/cmd/haredoc/doc/types.ha @@ -51,6 +51,7 @@ export type context = struct { ident: ast::ident, tags: []str, ambiguous: bool, + parse_errs: []lex::syntax, srcs: module::srcset, submods: []str, summary: summary, diff --git a/cmd/haredoc/main.ha b/cmd/haredoc/main.ha @@ -152,11 +152,28 @@ fn doc(name: str, cmd: *getopt::command) (void | error) = { free(decls); }; + let parse_errs: []lex::syntax = []; + defer free(parse_errs); + if (declpath != "") { for (let ha .. declsrcs.ha) { - let u = doc::scan(ha)?; - ast::imports_finish(u.imports); - append(decls, u.decls...); + let d = match (doc::scan(ha)) { + case let d: []ast::decl => + yield d; + case let err: parse::error => + if (html) { + return err; + }; + match (err) { + case let err: lex::syntax => + append(parse_errs, err); + continue; + case => + return err; + }; + }; + defer free(d); + append(decls, d...); }; let matching: []ast::decl = []; @@ -199,9 +216,23 @@ fn doc(name: str, cmd: *getopt::command) (void | error) = { if (len(decls) == 0) { for (let ha .. modsrcs.ha) { - let u = doc::scan(ha)?; - ast::imports_finish(u.imports); - append(decls, u.decls...); + let d = match (doc::scan(ha)) { + case let d: []ast::decl => + yield d; + case let err: parse::error => + if (html) { + return err; + }; + match (err) { + case let err: lex::syntax => + append(parse_errs, err); + continue; + case => + return err; + }; + }; + defer free(d); + append(decls, d...); }; const rpath = path::init(modpath, "README")!; @@ -228,6 +259,7 @@ fn doc(name: str, cmd: *getopt::command) (void | error) = { ident = id, tags = tags, ambiguous = ambiguous, + parse_errs = parse_errs, srcs = srcs, submods = submods, summary = summary,