hare

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

commit e4b13d5c8f052980a6457e044fdfbeffafb00525
parent d2e1e4657daa217b5730c84ff36a82fbcb1b0acb
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 19 Apr 2021 09:55:49 -0400

hare::parse: store docs on ast::decl

Diffstat:
Mhare/ast/decl.ha | 3+++
Mhare/parse/+test/unit.ha | 19+++++++++++++++++++
Mhare/parse/decl.ha | 13+++++++++++--
3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/hare/ast/decl.ha b/hare/ast/decl.ha @@ -38,6 +38,9 @@ export type decl = struct { exported: bool, loc: lex::location, decl: ([]decl_global | []decl_type | decl_func), + + // Only valid if the lexer has comments enabled + docs: str, }; // Frees resources associated with a declaration diff --git a/hare/parse/+test/unit.ha b/hare/parse/+test/unit.ha @@ -1,4 +1,5 @@ use bufio; +use fmt; use hare::ast; use hare::lex; use io::{mode}; @@ -133,3 +134,21 @@ use strings; "@test fn foo(_: int, ...) void;\n" "export fn main() void = void;\n"); }; + +@test fn docs() void = { + const src = "// Example text\nexport fn main() void = void;\n"; + let buf = bufio::fixed(strings::toutf8(src), mode::READ); + defer io::close(buf); + let lexer = lex::init(buf, "<test>", lex::flags::COMMENTS); + let decls = match (decls(&lexer)) { + decls: []ast::decl => decls, + err: error => { + fmt::errorln(strerror(err)); + abort(); + }, + }; + defer for (let i = 0z; i < len(decls); i += 1) { + ast::decl_free(decls[i]); + }; + assert(decls[0].docs == " Example text\n"); +}; diff --git a/hare/parse/decl.ha b/hare/parse/decl.ha @@ -142,12 +142,20 @@ export fn decls(lexer: *lex::lexer) ([]ast::decl | error) = { let decls: []ast::decl = []; for (true) { if (peek(lexer, ltok::EOF)? is lex::token) break; + let comment = ""; let exported = match (try(lexer, ltok::EXPORT)?) { void => false, - lex::token => true, + lex::token => { + comment = strings::dup(lex::comment(lexer)); + true; + }, }; const toks = [ltok::CONST, ltok::LET, ltok::DEF, ltok::TYPE]; - let decl = match (try(lexer, toks...)?) { + const next = try(lexer, toks...)?; + if (comment == "") { + comment = strings::dup(lex::comment(lexer)); + }; + let decl = match (next) { void => decl_func(lexer)?, t: lex::token => if (t.0 == ltok::TYPE) decl_type(lexer)? @@ -157,6 +165,7 @@ export fn decls(lexer: *lex::lexer) ([]ast::decl | error) = { exported = exported, loc = mkloc(lexer), decl = decl, + docs = comment, }); want(lexer, ltok::SEMICOLON)?; };