hare

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

commit 2f8887f661ba204928a530cf8653aff0a4dcc2e1
parent 695fb305e3ce03c5248b3219edd7e6f55779ed0d
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sun, 12 Jun 2022 19:30:45 -0400

Parse labels in hare::parse instead of hare::lex

As per the change to the spec which allows whitespace characters between
the colon and name of a label, labels are now handled during parse
instead of lex. The lexer only sees a colon and a name, and the label is
constructed by the parser from this.

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

Diffstat:
Mhare/lex/+test.ha | 3++-
Mhare/lex/lex.ha | 11+++--------
Mhare/lex/token.ha | 4----
Mhare/parse/expr.ha | 23++++++++++++-----------
4 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/hare/lex/+test.ha b/hare/lex/+test.ha @@ -179,7 +179,8 @@ fn loc(line: uint, col: uint) location = location { (ltok::RETURN, void, loc(1, 13)), (ltok::VOID, void, loc(1, 20)), (ltok::NAME, "foobar", loc(1, 25)), - (ltok::LABEL, "foobaz", loc(1, 32)), + (ltok::COLON, void, loc(1, 32)), + (ltok::NAME, "foobaz", loc(1, 33)), ]; lextest(in, expected); }; diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -107,7 +107,7 @@ export fn lex(lex: *lexer) (token | error) = { lex.require_int = false; if (is_name(r.0, false)) { unget(lex, r); - return lex_name(lex, r.1, false); + return lex_name(lex, r.1); }; let tok = switch (r.0) { @@ -299,7 +299,7 @@ fn lex_rn_str(lex: *lexer) (token | error) = { return ret; }; -fn lex_name(lex: *lexer, loc: location, label: bool) (token | error) = { +fn lex_name(lex: *lexer, loc: location) (token | error) = { let buf = strio::dynamic(); match (next(lex)) { case let r: (rune, location) => @@ -322,9 +322,6 @@ fn lex_name(lex: *lexer, loc: location, label: bool) (token | error) = { line_comment(lex)?; let n = strio::string(&buf); - if (label) { - return (ltok::LABEL, n, loc); - }; match (sort::searchstrings(bmap[..ltok::LAST_KEYWORD+1], n)) { case void => @@ -644,9 +641,7 @@ fn lex2(lexr: *lexer) (token | error) = { case => unget(lexr, r); line_comment(lexr)?; - return if (is_name(r.0, false)) { - yield lex_name(lexr, first.1, true)?; - } else (ltok::COLON, void, first.1); + return (ltok::COLON, void, first.1); }; case io::EOF => return (ltok::COLON, void, first.1); diff --git a/hare/lex/token.ha b/hare/lex/token.ha @@ -153,7 +153,6 @@ export type ltok = enum uint { LAST_LITERAL = LIT_STR, NAME, - LABEL, EOF, }; @@ -337,9 +336,6 @@ export fn tokstr(tok: token) const str = { return "str"; case ltok::NAME => return tok.1 as str; - case ltok::LABEL => - // XXX: strings::concat(":", tok.1 as str)? - return "label"; case ltok::EOF => return "EOF"; case => diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -593,9 +593,9 @@ fn constant(lexer: *lex::lexer) (ast::expr | error) = { fn control(lexer: *lex::lexer) (ast::expr | error) = { let tok = want(lexer, ltok::BREAK, ltok::CONTINUE, ltok::RETURN)?; let label = if (tok.0 == ltok::BREAK || tok.0 == ltok::CONTINUE) { - yield match (try(lexer, ltok::LABEL)?) { - case let tok: lex::token => - yield tok.1 as str; + yield match (try(lexer, ltok::COLON)?) { + case lex::token => + yield want(lexer, ltok::NAME)?.1 as str; case void => yield ""; }; @@ -640,11 +640,12 @@ fn delete_expr(lexer: *lex::lexer, is_static: bool) (ast::expr | error) = { fn compound_expr(lexer: *lex::lexer) (ast::expr | error) = { let items: []*ast::expr = []; - const start = want(lexer, ltok::LBRACE, ltok::LABEL)?; + const start = want(lexer, ltok::LBRACE, ltok::COLON)?; const label = switch (start.0) { - case ltok::LABEL => + case ltok::COLON => + const tok = want(lexer, ltok::NAME)?; want(lexer, ltok::LBRACE)?; - yield start.1 as str; + yield tok.1 as str; case => yield ""; }; @@ -1221,7 +1222,7 @@ fn unarithm(lexer: *lex::lexer) (ast::expr | error) = { const tok = match (try(lexer, ltok::PLUS, ltok::MINUS, ltok::BNOT, ltok::LNOT, ltok::TIMES, ltok::BAND, - ltok::SWITCH, ltok::MATCH, ltok::LABEL, ltok::LBRACE)) { + ltok::SWITCH, ltok::MATCH, ltok::COLON, ltok::LBRACE)) { case void => return builtin(lexer); case let tok: lex::token => @@ -1232,7 +1233,7 @@ fn unarithm(lexer: *lex::lexer) (ast::expr | error) = { case ltok::MATCH => lex::unlex(lexer, tok); return match_expr(lexer); - case ltok::LABEL, ltok::LBRACE => + case ltok::COLON, ltok::LBRACE => lex::unlex(lexer, tok); return compound_expr(lexer); case => @@ -1300,15 +1301,15 @@ fn yield_expr(lexer: *lex::lexer) (ast::expr | error) = { const start = want(lexer, ltok::YIELD)?; let label = ""; let value: nullable *ast::expr = null; - match (try(lexer, ltok::SEMICOLON, ltok::LABEL, ltok::EOF)?) { + match (try(lexer, ltok::SEMICOLON, ltok::COLON, ltok::EOF)?) { case void => value = alloc(expr(lexer)?); case let t: lex::token => switch (t.0) { case ltok::SEMICOLON, ltok::EOF => lex::unlex(lexer, t); - case ltok::LABEL => - label = t.1 as str; + case ltok::COLON => + label = want(lexer, ltok::NAME)?.1 as str; match (try(lexer, ltok::COMMA)?) { case void => void; case lex::token =>