hare

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

commit 2d20726b2e39af479b43cc3cc271453948923a19
parent ac7517aae812a350cb1ec21e4189aad724f34b46
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 14 May 2022 12:20:07 +0200

hare::parse: add parse::decl

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mhare/parse/decl.ha | 77+++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 41 insertions(+), 36 deletions(-)

diff --git a/hare/parse/decl.ha b/hare/parse/decl.ha @@ -175,47 +175,52 @@ fn decl_func(lexer: *lex::lexer) (ast::decl_func | error) = { }; }; +// Parses a declaration. +export fn decl(lexer: *lex::lexer) (ast::decl | error) = { + const start = lex::mkloc(lexer); + let comment = ""; + let exported = match (try(lexer, ltok::EXPORT)?) { + case void => + yield false; + case lex::token => + comment = strings::dup(lex::comment(lexer)); + yield true; + }; + const toks = [ltok::CONST, ltok::LET, ltok::DEF, ltok::TYPE]; + const next = try(lexer, toks...)?; + if (comment == "") { + comment = strings::dup(lex::comment(lexer)); + }; + let decl = match (next) { + case void => + yield decl_func(lexer)?; + case let t: lex::token => + yield switch (t.0) { + case ltok::TYPE => + yield decl_type(lexer)?; + case ltok::LET, ltok::CONST => + yield decl_global(lexer, t.0)?; + case ltok::DEF => + yield decl_const(lexer, t.0)?; + case => abort(); + }; + }; + want(lexer, ltok::SEMICOLON)?; + return ast::decl { + exported = exported, + start = start, + end = lex::mkloc(lexer), + decl = decl, + docs = comment, + }; +}; + // Parses the declarations for a sub-unit. export fn decls(lexer: *lex::lexer) ([]ast::decl | error) = { let decls: []ast::decl = []; for (true) { if (peek(lexer, ltok::EOF)? is lex::token) break; - const start = lex::mkloc(lexer); - let comment = ""; - let exported = match (try(lexer, ltok::EXPORT)?) { - case void => - yield false; - case lex::token => - comment = strings::dup(lex::comment(lexer)); - yield true; - }; - const toks = [ltok::CONST, ltok::LET, ltok::DEF, ltok::TYPE]; - const next = try(lexer, toks...)?; - if (comment == "") { - comment = strings::dup(lex::comment(lexer)); - }; - let decl = match (next) { - case void => - yield decl_func(lexer)?; - case let t: lex::token => - yield switch (t.0) { - case ltok::TYPE => - yield decl_type(lexer)?; - case ltok::LET, ltok::CONST => - yield decl_global(lexer, t.0)?; - case ltok::DEF => - yield decl_const(lexer, t.0)?; - case => abort(); - }; - }; - append(decls, ast::decl { - exported = exported, - start = start, - end = lex::mkloc(lexer), - decl = decl, - docs = comment, - }); - want(lexer, ltok::SEMICOLON)?; + append(decls, decl(lexer)?); }; return decls; };