hare

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

commit 1a4c56b0e0412d7db6d31b17c17040d7f4110fba
parent 9b3040e17587e3e60425b00844662d90976de480
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 17 Apr 2021 08:01:48 -0400

hare::lex: implement labels

Diffstat:
Mhare/lex/+test.ha | 3++-
Mhare/lex/lex.ha | 16++++++++++++----
2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/hare/lex/+test.ha b/hare/lex/+test.ha @@ -137,13 +137,14 @@ fn loc(line: uint, col: uint) location = location { }; @test fn lexname() void = { - const in = "hello world return void foobar"; + const in = "hello world return void foobar :foobaz"; const expected: [_]token = [ (ltok::NAME, "hello", loc(1, 1)), (ltok::NAME, "world", loc(1, 7)), (ltok::RETURN, void, loc(1, 13)), (ltok::VOID, void, loc(1, 20)), (ltok::NAME, "foobar", loc(1, 25)), + (ltok::LABEL, "foobaz", loc(1, 32)), ]; lextest(in, expected); }; diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -85,7 +85,7 @@ export fn lex(lex: *lexer) (token | error) = { if (is_name(r, false)) { unget(lex, r); - return lex_name(lex, loc); + return lex_name(lex, loc, true); }; if (ascii::isdigit(r)) { unget(lex, r); @@ -215,7 +215,7 @@ fn lex_rn_str(lex: *lexer, loc: location) (token | error) = { return ret; }; -fn lex_name(lex: *lexer, loc: location) (token | error) = { +fn lex_name(lex: *lexer, loc: location, keyword: bool) (token | error) = { let chars: []u8 = []; match (next(lex)) { r: rune => { @@ -237,9 +237,12 @@ fn lex_name(lex: *lexer, loc: location) (token | error) = { }; let n = strings::fromutf8(chars); + if (!keyword) { + return (ltok::NAME, n, loc); + }; + return match (sort::search(bmap[..ltok::LAST_KEYWORD+1], size(str), &n, &ncmp)) { - // TODO: Validate that names are ASCII null => (ltok::NAME, n, loc), v: *void => { let tok = v: uintptr - &bmap[0]: uintptr; @@ -492,7 +495,12 @@ fn lex2(lexr: *lexer, loc: location, r: rune) (token | error) = { ':' => match (n) { r: rune => switch (r) { ':' => return (ltok::DOUBLE_COLON, void, loc), - * => ltok::COLON, + * => if (is_name(r, false)) { + unget(lexr, r); + let tok = lex_name(lexr, loc, false)?; + tok.0 = ltok::LABEL; + return tok; + } else ltok::COLON, }, io::EOF => ltok::COLON, },