hare

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

commit ac3e274cc0e76956d5035dd3b7f0d331cc9a3954
parent eefbd852f6a3f09f4116ccc0b18bc3e49abcd3b6
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sat, 28 Oct 2023 02:36:07 -0400

cmd/parsechk: initial commit

This uses hare::parse to parse all .ha files in the tree, and report if
any parsing errors occurred. This should hopefully ensure that in the
future we keep hare::parse up to date, and don't push changes that
compile but don't work with haredoc.

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

Diffstat:
M.builds/alpine.yml | 3+++
Acmd/parsechk/main.ha | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/.builds/alpine.yml b/.builds/alpine.yml @@ -38,6 +38,9 @@ tasks: - check_with_libc: | cd hare hare test -lc +- parsechk: | + cd hare + hare run cmd/parsechk - lint: | cd hare ./scripts/lint.sh diff --git a/cmd/parsechk/main.ha b/cmd/parsechk/main.ha @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-3.0-only +// (c) Hare authors <https://harelang.org> + +use bufio; +use fmt; +use fs; +use hare::ast; +use hare::lex; +use hare::parse; +use io; +use os; +use path; +use types; + +export fn main() void = { + let buf = path::init()!; + let status: int = os::status::SUCCESS; + iter(&buf, &status); + os::exit(status); +}; + +fn iter(buf: *path::buffer, status: *int) void = { + let it = os::iter(path::string(buf))!; + defer fs::finish(it); + for (true) match (fs::next(it)) { + case void => + break; + case let ent: fs::dirent => + path::push(buf, ent.name)!; + defer path::pop(buf); + const st = os::stat(path::string(buf))!; + if (fs::isfile(st.mode)) { + match (path::peek_ext(buf)) { + case let s: str => + if (s == "ha") { + parse(path::string(buf), status); + }; + case void => void; + }; + } else if (fs::isdir(st.mode)) { + iter(buf, status); + }; + }; +}; + +fn parse(path: str, status: *int) void = { + const f = os::open(path)!; + defer io::close(f)!; + let sc = bufio::newscanner(f, types::SIZE_MAX); + defer bufio::finish(&sc); + let lexer = lex::init(&sc, path); + match (parse::subunit(&lexer)) { + case let su: ast::subunit => + ast::subunit_finish(su); + case let err: parse::error => + fmt::errorln(parse::strerror(err))!; + *status = os::status::FAILURE; + }; +};